背景
最近项目中,想在vue2中把状态管理库从vuex转到pinia。
如何从vuex转到pinia
安装和配置
1. 安装
"@vue/composition-api": "^1.7.0",
"pinia": "^2.0.17",
import {
PiniaVuePlugin, createPinia } from 'pinia'
Vue.use(PiniaVuePlugin)
const pinia = createPinia()
new Vue({
router,
store,
render: h => h(App),
pinia
}).$mount('#app')
2. 配置vue-cli识别mjs后缀文件
由于pinia的源码文件后缀是mjs和cjs,webpack默认不识别该后缀的文件,我们项目中是通过import的方式导入的,需要配置vue-cli匹配到mjs文件时,把文件代码识别成ES Module格式导入
configureWebpack: {
module: {
rules: [
{
test: /\.mjs$/,
include: /node_modules/,
type: 'javascript/auto'
}
]
}
}
pinia与 Vuex 的比较
- mutations不再存在。在pinia的思想中被认为是多余的,延长了状态更改的链路,action和mutation在vuex中最初是为了和devtools插件有更好的联系而存在的,pinia中可以直接修改状态(devtools能够记录下来state的变化),或者提交action修改状态
- 无需创建自定义复杂包装器来支持 TypeScript,所有内容都是类型化的,并且 API 的设计方式尽可能利用 TS 类型推断。
- 不再需要注入(mixin)、你只需要在想改变状态的地方,导入函数、调用函数即可
- 无需动态添加 Store,默认情况下它们都是动态的,您甚至都不会注意到。请注意,您仍然可以随时手动使用 Store 进行注册,但因为它是自动的,您无需担心。
- 不再有 modules 的嵌套结构(命名空间模块)。你仍然可以通过在另一个 Store 中导入和 使用 来隐式嵌套 Store,但不建议, Pinia 提倡平级的去管理各个store,同时支持 Store 之间的交叉组合方式
第5点举例:vuex的组织方式可能是这样的:嵌套
src
└── store
├── index.js
└── modules
├── module1.js
└── nested
├── index.js
├── module2.js
└── module3.js
重构成pinia后:平级
src
└── stores
├── index.js
├── module1.js
├── nested-module2.js
├── nested-module3.js
└── nested.js
pinia在vue2中基本使用:
修改Store中的State状态(直接修改$patch\actions修改$reset)
现有store如下:
import {
defineStore } from "pinia";
export const storeA = defineStore("storeA", {
state: () => {
return {
msg: "hello pinia",
name: "hmi",
};
},
getters: {
},
actions: {
setName(data) {
this.name = data;
},
},
});
直接修改
<template>
<div>{
{
piniaStoreA.msg }}</div>
</template>
<script setup>
import {
storeA } from '@/piniaStore/storeA'
let piniaStoreA = storeA()
piniaStoreA.msg = 'hello world'
</script>
$patch
import {
storeA } from '@/piniaStore/storeA'
let piniaStoreA = storeA