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

82 阅读2分钟

最后

技术是没有终点的,也是学不完的,最重要的是活着、不秃。零基础入门的时候看书还是看视频,我觉得成年人,何必做选择题呢,两个都要。喜欢看书就看书,喜欢看视频就看视频。最重要的是在自学的过程中,一定不要眼高手低,要实战,把学到的技术投入到项目当中,解决问题,之后进一步锤炼自己的技术。

技术学到手后,就要开始准备面试了,找工作的时候一定要好好准备简历,毕竟简历是找工作的敲门砖,还有就是要多做面试题,复习巩固。

开源分享:docs.qq.com/doc/DSmRnRG… }, { 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://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/63eb6d125ef94c6da14d2df6321917e7~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MzM5MTQ5MjgwNjA=:q75.awebp?rk3s=f64ab15b&x-expires=1771325710&x-signature=VARfvnDIDmFb53MwUSBv6jQoKVQ%3D)


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


![](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/eb6c3fb9703e407fb4d852bd03c07377~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MzM5MTQ5MjgwNjA=:q75.awebp?rk3s=f64ab15b&x-expires=1771325710&x-signature=RpMHBe5VTof18KfkBvFh8%2BM4QQM%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://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/4df034170439411fb85d9461a32fb06f~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MzM5MTQ5MjgwNjA=:q75.awebp?rk3s=f64ab15b&x-expires=1771325710&x-signature=U%2Be9e7xRX3X8vrv%2FFLqWzBGte7s%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)
                        
                        //动态添加路由表中的数据
                        this.$store.commit('addMenu',this.$router)

                        //跳转到首页
                        this.$router.push('/home')
                    }else{
                        this.$message.error(data.data.message)
                    }
                })
            }
        })

常用的JavaScript设计模式

  • 单体模式

  • 工厂模式

  • 例模式

函数