Vue如何在mounted中使用mapState提前获取vuex状态控制v-if渲染
问题根因
- 你在
mounted钩子中调用mapState是无效用法:mapState是Vuex提供的计算属性语法糖,仅当展开写入computed配置项时,才会被Vue处理为组件实例的响应式属性,单独在生命周期中调用不会挂载任何属性,因此你无法拿到userSso的值。 - 你感知到的「computed响应速度慢」本质是状态更新的时间差问题:store中
userSso初始值为0,页面渲染时会先显示Account菜单,等你从数据库请求到userSso=1再更新store时,才会触发视图隐藏菜单,这段时间差就会导致用户可点击。
最优解决方案
1. 修正mapState用法
删除mounted中无效的mapState代码,放开computed中已注释的userSso声明即可:
computed: { ...mapState('store', { navbarState: (state) => state.navbarState, backColor: (state) => state.backColor, fontColor: (state) => state.fontColor, primaryColor: (state) => state.primaryColor, userSso: (state) => state.userSso, // 取消该行注释 }), }
2. 新增中间状态避免菜单闪现
调整store中userSso的初始值为null,用于标记「还未从数据库拿到结果」的中间状态:
// /store/store.js export const state = () => ({ userSso: null, // 初始值从0改为null })
同时修改模板判断逻辑,未拿到数据库结果时不渲染Account菜单,也可给整个导航栏加loading遮罩禁止用户操作:
<li v-if="userSso !== null && userSso == 0" :class="{ active: navbarState == 8 }"> <a href="/dashboard/user"> <img src="../assets/images/ico_user.svg" alt="icon" /> Account </a> </li>
3. 前置接口请求时机
将获取userSso的数据库请求放到全局路由守卫router.beforeEach、应用根组件的beforeCreate生命周期中触发,远早于导航组件渲染完成的时间点拿到结果,进一步缩短状态更新的时间差。
4. 路由拦截兜底
在/dashboard/user路由的beforeEnter守卫中新增userSso判断,即使用户绕过前端渲染限制点击了菜单,也会被拦截无法进入对应页面:
// 路由配置文件 { path: '/dashboard/user', component: () => import('xxx'), beforeEnter: (to, from, next) => { const userSso = store.state.store.userSso if (userSso === 1) { next('/dashboard/settings') // 跳转到其他合法页面 return } next() } }
内容的提问来源于stack exchange,提问作者niddddddfier
相关产品推荐
相关产品推荐

