vue3+pinia+路由守卫实现用户访问页面权限

vue3+pinia+路由守卫实现用户访问页面权限

每个用户能访问的路由在登陆接口返回,格式包含一个Key(用于比对数据)
如下:

[{name:'',Key:''},{name:'',Key:''}...]

在router中定义两个数组一个为需要权限才能访问的权限路由,一个为不需要权限就能访问的固定路由

//不需要权限
export const constantRoutes: RouteRecordRaw[] = [
    //路由重定向
    {
        path: '/',
        redirect: '/Layout'
    },
    {
        path: '/login',
        name: 'login',
        component: login,
    }]]
//需要权限
export const asyncRoutes: RouteRecordRaw[] = [ {
                path: '/EventManagement',
                name: '活动管理',
                component: () => import('@/views/EventManagement/EventManagement.vue'),
                meta: {
                    title: '活动管理',
                    authkey: 'LIFE_EVENTMANAGEMENT',
                    icon: 'home'
                }
            }]

在路由守卫中判断用户是否登录,是否添加路由,是否处理路由。

import router from '@/router/router'
import { useUserStore } from '@/store';
import { asyncRoutes } from '@/router/router'
let iscomparison = false;//判断是否添加路由
router.beforeEach((to, from, next) => {
    console.log('进入路由守卫')
    var userStore = useUserStore();

    if (to.path === '/login') {
        next()
    } else {
        //如果有用户名证明已经登陆,如果没有就是还没有登陆
        if (userStore.name) {
            //判断是否处理过账户的权限路由userStore.iscomparison为true是为处理过当登出与登录失效时,会重新变为false
            if (userStore.iscomparison) {
                //判断是否添加过路由(刷新的时候addRoute方法添加的路由会丢失需要重新addRoute)
                if (iscomparison) {
                    next()
                } else {
                    //重新添加                    
                    userStore.comparisonKeys(userStore.message.AuthList).then((res: any) => {

                        userStore.userProfile.addRoute.forEach(item => {
                            router.addRoute('Layout', item)
                    })
                    userStore.iscomparison = true;
                    iscomparison = true;
                    next({ ...to, replace: true })
                })

                }
            } else {
                //如果没有处理过权限路由,判断有没有添加过路由
                if (iscomparison) {
                    //添加过路由(在退出登陆与登陆超时会遇到)首先将之前添加的路由删除再将iscomparison设置为false再跑一次路由守卫
                    //userStore.userProfile.addRoute.forEach(item => {
                    //    router.removeRoute(item.name)
                    //})
                    iscomparison = false;
                    next({ ...to, replace: true })
                } else {
                    //没有添加过路由也没有处理过权限,处理权限
                    userStore.comparisonKeys(userStore.message.AuthList).then((res: any) => {

                        userStore.userProfile.addRoute.forEach(item => {
                            router.addRoute('Layout',item)
                        })
                        userStore.iscomparison = true;
                        iscomparison = true;
                        next({ ...to, replace: true })
                    })

                }
            }

        } else {
            next('/login')
        }
    }
})

先说说这一次踩的坑:
1.登录之后一直白屏,在路由守卫中console.log(‘进入路由守卫’)发现一直进入路由守卫问了神奇的度娘之后才知道,next({ …to, replace: true })、next(‘/login’)与next()的区别。在路由守卫中next({ …to, replace: true })和next(‘/login’)会再次进入路由守卫而next()为放行不会再次进入路由守卫。

2.登录之后跳转到后台管理页面,看起来一点问题都没有了,但是刷新页面之后,之前使用router.addRouter()方法添加的权限路由不见了!!!!原因是刷新页面的时候路由也会跟着一起初始化,后面添加权限路由也会随之消失,解决方法是在router.ts中声明一个变量let iscomparison = false;
当iscomparison 为false时代表还没有使用router.addRouter()添加权限路由反之为已经添加了路由防止重复添加,再刷新页面的时候iscomparison 也会随着路由一起初始化。

3.切换账号时,上一个账号的路由权限没有删除,比如我先登陆一个叫admin的管理员账号,登出后再登陆一个叫test的用户账号,会发现在test账号中可以访问admin的路由,我当时唰一下脸就白了,当时就觉得这个逼不讲武德,细细想来我只添加了路由而没有删除路由,这时的我脑海中想到了两个办法,一个是利用上面提到过的刷新初始化路由的方法,只需要登出后location.reload()一下就能解决问题,就是用户看起来不优雅。二就是使用router.removeRoute()方法将之前添加的路由使用for of方法删除,就是麻烦一点。想到这时我忍不住看了一眼后面的测试小姐姐,算了算了还是第二种方法吧。于是我在pinia中定义了一个专门用来删除路由的方法cleanRoute,在每次登陆失效或者登出的时候调用达到清除上一个账户添加的路由。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为了实现动态路由用户权限路由,我们需要进行以下步骤: 1. 安装依赖 ```shell npm install vue-router@4 pinia element-plus mock -S npm install @types/mock -D ``` 2. 创建路由配置文件 在src文件夹下创建router文件夹,并在其中创建index.ts文件,用于配置路由。在该文件中,我们需要定义路由的各个页面组件,并根据需要配置路由的子路由路由守卫。例如: ```typescript import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router' import Home from '@/views/home/indexName.vue' import Login from '@/views/login/index.vue' import NotFound from '@/views/404/index.vue' const routes: Array<RouteRecordRaw> = [ { path: '/', name: 'Home', component: Home, meta: { title: '首页', requireAuth: true // 需要登录才能访问 } }, { path: '/login', name: 'Login', component: Login, meta: { title: '登录' } }, { path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound, meta: { title: '404' } } ] const router = createRouter({ history: createWebHistory(), routes }) // 路由守卫 router.beforeEach((to, from, next) => { const token = localStorage.getItem('token') if (to.meta.requireAuth && !token) { next('/login') } else { next() } }) export default router ``` 3. 在main.ts中挂载路由 在main.ts中,我们需要将路由配置文件挂载到Vue实例中,以便在应用中使用路由。例如: ```typescript import { createApp } from 'vue' import App from './App.vue' import router from './router' createApp(App).use(router).mount('#app') ``` 4. 创建权限控制文件 在src文件夹下创建permission文件夹,并在其中创建index.ts文件,用于控制用户权限。在该文件中,我们需要定义用户权限列表,并根据需要判断用户是否有权限访问某个路由。例如: ```typescript import router from '@/router' const whiteList = ['/login'] // 不需要登录即可访问页面 router.beforeEach((to, from, next) => { const token = localStorage.getItem('token') if (token) { if (to.path === '/login') { next('/') } else { // 判断用户是否有权限访问路由 const hasPermission = true // 根据实际情况判断用户是否有权限 if (hasPermission) { next() } else { next('/404') } } } else { if (whiteList.indexOf(to.path) !== -1) { next() } else { next('/login') } } }) ``` 5. 在App.vue中挂载路由渲染入口 在App.vue中,我们需要将路由渲染入口挂载到模板中,以便在应用中渲染路由。例如: ```html <template> <div id="app"> <router-view /> </div> </template> ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值