Pinia 上手
背景
随着 Vue3 正式发布,Vue3 的生态也在不到完善,Pinia 就是其中一员。Pinia 是 Vue 的一个状态仓库,与 Vuex 相比它有很多优点,更轻量,更简洁,更好的类型支持等等。
安装
npm i pinia
如果在 Vue2 中使用还需要安装 @vue/composition-api。
npm i @vue/composition-api
使用
创建 Pinia 实例,并添加到应用中
Vue3 写法
import { createPinia } from "pinia";
app.use(createPinia());
Vue2 写法
import { createPinia, PiniaVuePlugin } from "pinia";
Vue.use(PiniaVuePlugin);
const pinia = createPinia();
new Vue({
el: "#app",
// 其他配置
pinia,
});
定义一个仓库
import { defineStore } from "pinia";
export const useCounterStore = defineStore("counter", {
state: () => {
return {
count: 0,
};
},
getters: {
double: (state) => state.count * 2,
plus(): number {
return this.double + 1;
},
},
actions: {
increment() {
this.count++;
},
asyncfn() {
setTimeout(() => {
this.count *= 2;
}, 3000);
},
},
});
使用
setup
import { storeToRefs } from "pinia";
import { useCounterStore } from "../store/module/counter";
const counter = useCounterStore();
const { count, double, plus } = storeToRefs(counter);
const { increment, asyncfn } = counter;
Options API
import { mapActions, mapState } from "pinia";
import { useCounterStore } from "../store/module/counter";
export default {
computed: {
...mapState(useCounterStore, ["count", "double", "plus"]),
},
methods: {
...mapActions(useCounterStore, ["increment", "asyncfn"]),
},
};
更多使用细节可以阅读官方文档官方文档
常见问题
在 Vue Cli 中使用出现 Can't import the named export 'computed' from non EcmaScript module (only default export is available) 等问题如下图
ERROR Failed to compile with 18 errors
error in ./node_modules/pinia/dist/pinia.mjs
Can't import the named export 'computed' from non EcmaScript module (only default export is available)
error in ./node_modules/pinia/dist/pinia.mjs
Can't import the named export 'del' from non EcmaScript module (only default export is available)
...
可能原因
第三方包没有导出对应版本的包
解决办法
- 修改 vue.config.js 配置
// vue.config.js
module.exports = {
// 导出对象
configureWebpack: {
module: {
rules: [
{
test: /\.mjs$/,
include: /node_modules/,
type: "javascript/auto"
}
]
}
}
// 导出函数
configureWebpack: config => {
config.module.rules.push({
test: /\.mjs$/,
include: /node_modules/,
type: 'javascript/auto',
})
}
}
可选步骤
- 更新 typescript 版本
- 跳过第三方包检查
{
"compilerOptions": {
...
"skipLibCheck": true
}
}