vue项目中实现用户登录角色鉴权,不同的用户登录展示不同的菜单栏_vue+js实现不同用户展示不同的菜单栏

74 阅读2分钟

最后

为了帮助大家更好的了解前端,特别整理了《前端工程师面试手册》电子稿文件。

开源分享:docs.qq.com/doc/DSmRnRG… path: '/mall', name: 'mall', label: '商品管理', icon: 'video-play', url: 'Mall.vue' }, { path: '/user', name: 'user', label: '用户管理', icon: 'user', url: 'User.vue' }, { label: '其他', icon: 'location', children: [ { path: '/page1', name: 'page1', label: '页面1', icon: 'setting', url: 'PageOne.vue' }, { path: '/page2', name: 'page2', label: '页面2', icon: 'setting', url: 'PageTwo.vue' } ] } ], token: Mock.Random.guid(), message: '获取成功' } } } else if (username === 'xiaoxiao' && password === 'xiaoxiao') { return { code: 20000, data: { menu: [ { path: '/home', name: 'home', label: '首页', icon: 's-home', url: 'Home.vue' }, { path: '/video', name: 'video', label: '商品管理', icon: 'video-play', url: 'Mall.vue' } ], token: Mock.Random.guid(), message: '获取成功' } } } else { return { code: -999, data: { message: '密码错误' } } }

} }


在store/tab.js的state中定义一个menu数据用来存储后端返回的菜单栏数据,在mutations中定义一个setMenu方法,在登录成功的时候调用该方法,把后端返回的数据存入menu

export default { state:{ //菜单栏数据 menu:[] }, mutations:{ // 设置menu的数据 setMenu(state,val){ state.menu = val }, } }


在Login.vue组件中,点击登录调用后端接口,拿到后端返回的数据



//登录 submit(){ this.$refs.form.validate((valid) => { if(valid){ getMenu(this.form).then(({ data }) => { console.log(data) if(data.code === 20000){

                        //获取菜单的数据存入store中
                        this.$store.commit('setMenu',data.data.menu)
                        
                    }else{
                        this.$message.error(data.data.message)
                    }
                })
            }
        })
    }

在 CommonAside.vue中动态计算menuData,然后根据menuData生成菜单栏结构


![](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/084c4445f31f43a48a115e7771900b09~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MzM5MTQ5MjgwNjA=:q75.awebp?rk3s=f64ab15b&x-expires=1780397747&x-signature=vPWwgZ1Yh2vTcmmc5F9uWGMKR6U%3D)


这样就实现了不同账号登录展示不同的侧边栏。但是,当我们在地址栏中手动输入一些路径,仍能够访问到。比如,在xiaoxiao登录的系统中,输入'/user'仍然显示。原因是项目中的路由表是写死了,就像router/index.js中的注释掉的这部分内容这样:


![](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/b71e123aaf1d455186686e12a30f10a3~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MzM5MTQ5MjgwNjA=:q75.awebp?rk3s=f64ab15b&x-expires=1780397747&x-signature=ni31%2FMNn20Unt7M4sKlFjoLNf4s%3D)


 


 因此,接下来我们要做得就是利用router.addRoute方法,把这部分内容变成动态的。


代码如下:


还是在store/tab.js中


定义动态添加路由的方法,遍历存储在state中的menu数据,把它从这样



      menu: [
        {
          path: '/home',
          name: 'home',
          label: '首页',
          icon: 's-home',
          url: 'Home.vue'
        },
        {
          path: '/mall',
          name: 'mall',
          label: '商品管理',
          icon: 'video-play',
          url: 'Mall.vue'
        },
        {
          path: '/user',
          name: 'user',
          label: '用户管理',
          icon: 'user',
          url: 'User.vue'
        },
        {
          label: '其他',
          icon: 'location',
          children: [
            {
              path: '/page1',
              name: 'page1',
              label: '页面1',
              icon: 'setting',
              url: 'PageOne.vue'
            },
            {
              path: '/page2',
              name: 'page2',
              label: '页面2',
              icon: 'setting',
              url: 'PageTwo.vue'
            }
          ]
        }
      ]

变成和注释掉的那部分一样,然后调用router.addRoute()把内容添加到路由表中。


![](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/e22c93e170fc43b3b8e4fe46ca07aec3~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MzM5MTQ5MjgwNjA=:q75.awebp?rk3s=f64ab15b&x-expires=1780397747&x-signature=VUo%2BC376fAYRoOnQr%2FUeNuoPBOg%3D)


 实现代码如下:



export default { state:{ //菜单栏数据 menu:[] }, mutations:{ // 设置menu的数据 setMenu(state,val){ state.menu = val },

    //动态注册路由
    addMenu(state,router){
        if(state.menu.length == 0 ) return

        //组装动态路由的数据
        const menuArray = []
        state.menu.forEach(item => {
            if(item.children){
                item.children = item.children.map(childItem => {
                    childItem.component = () => import(`../views/${childItem.url}`)
                    console.log(childItem.component)
                    return childItem
                })
                console.log(item.children)
                menuArray.push(...item.children)
            }else{
                item.component = () => import(`../views/${item.url}`)
                menuArray.push(item)
            }

            console.log(menuArray,'menuArray')

            //路由的动态添加
            menuArray.forEach(item => {
                router.addRoute('main',item)
            })
        })

    }


}

}


因为要用到router的api,所以,在定义addMenu方法的时候要把路由实例作为参数传进来。


在Login.vue组件中,登录成功调用addMenu方法:



//登录 submit(){ this.$refs.form.validate((valid) => { if(valid){ getMenu(this.form).then(({ data }) => { console.log(data) if(data.code === 20000){ //token信息存入cookie用于不同页面间的通信 Cookie.set('token', data.data.token)

                        //获取菜单的数据存入store中
                        this.$store.commit('setMenu',data.data.menu)

最后

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

给大家分享一些关于HTML的面试题。