Vuex 转 Pinia
前言
想了解基础知识可移步《《Vue3 基础知识》Pinia 01 之 基础》
在 Vue3
项目中增 Pinia,且能与 Vuex4 同时使用。
安装
npm i pinia
文件目录
- 新建文件夹
stores
,注意是复数s
。因为Pinia
中每个模块都是一个 store; - 文件
index.js
是Pinia
初始化文件。其它文件是带id
的单个store
;
# Pinia 目录结构,注意 ID 与文件名匹配
src
└── stores
├── index.js # 初始化 Pinia
├── gmThemePro.js # 'gmThemePro' id
└── user.js # 'user' id
初始化
src/stores/index.js
中初始化 Pinia
import { createPinia } from 'pinia'
const pinia = createPinia()
export default pinia;
src/main.js
中注册,更多单页面应用在此;
import { createApp } from 'vue'
import App from './App.vue'
import pinia from './stores' // 导入 /stores/index.js
// 创建 Vue 实例
const app = createApp(App)
// 注册,注意任何 useXxxStore 都得在此代码之后使用
app.use(pinia)
改造
Vuex 写法
以 src\store\modules\user.js
为例,改造为 src\stores\user.js
export default {
state: () => {
return {
avatar: '',
name: '',
isManager: false,
userInfoRole: {}, //用户权限
funcIds: [], // 功能菜单权限
treeIds: [], // 目录树权限
toolIds: [], // 工具条权限
adminIds: [], //后台管理权限
}
},
mutations: {
SET_PRIVILEGE: (state, obj) => {
state.funcIds = obj.funcIds
state.treeIds = obj.treeIds
state.toolIds = obj.toolIds
state.adminIds = obj.privilegeExts
},
},
actions: {
// 登录
login({ commit }, obj) {
// TODO
},
// 登出
logout({ commit }) {
// TODO
},
},
}
Pinia 写法
- 使用
defineStore
定义一个store
,且唯一 id 为user
; state
转换为一个箭头函数;getter
中的第一个参数是state
,访问state
中的属性用第一个参数。访问其它getter
直接用this
;actions
中的第一个参数context
删除,所有东西都可用this
访问;mutations
在Pinia
中被弃用,可转为action
,将第一个参数state
删除,所有东西都可用this
访问;
import { defineStore } from 'pinia'
// 常量名建议以 `use` 开头且以 `Store` 结尾
export const useUserStore = defineStore('user', {
state: () => {
return {
avatar: '',
name: '',
isManager: false,
userInfoRole: {}, //用户权限
funcIds: [], // 功能菜单权限
treeIds: [], // 目录树权限
toolIds: [], // 工具条权限
adminIds: [], //后台管理权限
}
},
actions: {
// 登录
login(obj) {
// TODO
},
// 登出
logout() {
// TODO
},
// 设置用户信息,原 mutations 中的 SET_NAME
setUserInfo( userName, isManager, userInfoRole) {
// TODO
},
// 设置权限信息,原 mutations 中的 SET_PRIVILEGE
setPrivilege(obj) {
this.funcIds = obj.funcIds
this.treeIds = obj.treeIds
this.toolIds = obj.toolIds
this.adminIds = obj.privilegeExts
}
}
})
使用
- 代码第
3
行,先引入sotre
; - 代码第
9
行,再初始化sotre
; - 代码第
15,19
行,state/getters/actions
都可用this.userStore
直接访问;
<script>
<!-- 第一步: 引入 -->
import { useUserStore } from '@/stores/user'
<!-- 第二步: 定义为计算属性 -->
export default {
computed: {
userStore() {
return useUserStore();
},
},
methods: {
getUserName() {
// 直接调属性 name
return this.userStore.name;
},
logout() {
// 直接调方法 logout
this.userStore.logout();
}
}
</script>