安装yarn add pinia # or npm install pinia
用法// user.tsimport { definestore } from 'pinia'export const useuserstore = definestore({ id: 'user', state: () => ({ ... }), actions: { ... }})// components.vueimport { useuserstore } from '@/store/user'const userstore = useuserstore()
使用中出现的问题cannot access 'useuserstore' before initialization重现步骤通常我们会在路由钩子中判断用户是否登陆,从而进行权限判断。如:
// permission.tsimport { navigationguardnext, routelocationnormalized } from 'vue-router'import router from './router'import { useuserstore } from './store/user'const userstore: any = useuserstore()router.beforeeach(async(to: routelocationnormalized, from: routelocationnormalized, next: navigationguardnext) => { // todo 判断是否登录 if (userstore.name) { ... }})// main.tsconst app = createapp(app)app.use(createpinia())import router from './router'import '@/permission'app.use(router)app.mount('#app')
问题原因代码从上往下执行过程中,遇到const userstore: any = useuserstore(),会进行用户状态模块的获取,但是应用还没有挂载,所以pinia的全局状态还没有进行初始化。造成了初始化用户模块状态获取时,全局状态并没有初始化,所以造成了当前问题。
解决方案在路由钩子函数进行用户状态模块的获取,调用路由钩子的时候,意味着全局状态已完全初始化完成。但会造成每次调用路由钩子都获取用户状态模块,会造成资源的浪费(当然可以达到预期目的,但并不是我们需要的)。我们可以在外层声明一个变量用来存储状态,在路由钩子中进行判断,如果当前变量为空,也就意味着状态还没有进行过获取,在当前情况下进行状态获取(类似于单例)。最终代码:
// permission.tsimport { navigationguardnext, routelocationnormalized } from 'vue-router'import router from './router'import { useuserstore } from './store/user'let userstore: any = nullrouter.beforeeach(async(to: routelocationnormalized, from: routelocationnormalized, next: navigationguardnext) => { if (userstore === null) { userstore = useuserstore() } // todo 判断是否登录 if (userstore.name) { ... }})
以上就是下面是对"vue3 pinia踩坑及解决实例代码分析"的重写:"解析vue3 pinia,包括踩坑与解决方法,结合实例代码进行分析。"的详细内容。