【前端】Vue+Element UI案例:通用后台管理系统-登陆不同用户显示不同菜单、动态添加路由

本文详细介绍了如何在Vue+ElementUI的后台管理系统中实现动态显示菜单和动态注册路由,以及解决页面刷新后的权限问题。通过在store中管理菜单数据,登录时设置并存储用户菜单,然后在页面创建时动态添加路由,确保不同用户访问不同的页面。同时,文章提供了一套完整的代码示例,包括关键代码段和相关教程链接。
摘要由CSDN通过智能技术生成


参考视频: VUE项目,VUE项目实战,vue后台管理系统,前端面试,前端面试项目

案例链接
【前端】Vue+Element UI案例:通用后台管理系统-导航栏(视频p1-16)https://blog.csdn.net/karshey/article/details/127640658
【前端】Vue+Element UI案例:通用后台管理系统-Header+导航栏折叠(p17-19)https://blog.csdn.net/karshey/article/details/127652862
【前端】Vue+Element UI案例:通用后台管理系统-Home组件:卡片、表格(p20-22)https://blog.csdn.net/karshey/article/details/127674643
【前端】Vue+Element UI案例:通用后台管理系统-Echarts图表准备:axios封装、mock数据模拟实战(p23-25)https://blog.csdn.net/karshey/article/details/127735159
【前端】Vue+Element UI案例:通用后台管理系统-Echarts图表:折线图、柱状图、饼状图(p27-30)https://blog.csdn.net/karshey/article/details/127737979
【前端】Vue+Element UI案例:通用后台管理系统-面包屑、tag栏(p31-35)https://blog.csdn.net/karshey/article/details/127756733
【前端】Vue+Element UI案例:通用后台管理系统-用户管理:Form表单填写、Dialog对话框弹出(p36-38)https://blog.csdn.net/karshey/article/details/127787418
【前端】Vue+Element UI案例:通用后台管理系统-用户管理:Table表格增删查改、Pagination分页、搜索框(p39-42)https://blog.csdn.net/karshey/article/details/127777962
【前端】Vue+Element UI案例:通用后台管理系统-登陆页面Login(p44)https://blog.csdn.net/karshey/article/details/127795302
【前端】Vue+Element UI案例:通用后台管理系统-登陆页面功能:登录权限跳转、路由守卫、退出(p45-46)https://blog.csdn.net/karshey/article/details/127849502
【前端】Vue+Element UI案例:通用后台管理系统-登陆不同用户显示不同菜单、动态添加路由(p47-48)https://blog.csdn.net/karshey/article/details/127865621
【前端】Vue+Element UI案例:通用后台管理系统-项目总结https://blog.csdn.net/karshey/article/details/127867638

目标

  • 不同用户登录后显示的菜单和能访问的页面不同
  • 动态添加路由

代码

0.动态地显示菜单:store

菜单的显示在CommonAside.vue中,而不同用户登陆后会显示哪些菜单在permission.js里。因此,我们可以把permission.js里要显示的menu写在store中,CommonAside.vue只需要获取store的数据即可。

在store的tab.js中:注意,要把菜单信息用cookie存起来,否则刷新后menu的信息就清空了。

export default {
    state: {
        menu: [],//不同用户的菜单
    },
    mutations: {
        // 设置不同用户的菜单
        setMenu(state, val) {
            state.menu = val
            Cookie.set('menu', JSON.stringify(val))
        }
    }
}

在Login.vue的submit函数中:在登录时commit

submit() {
    // 表单的校验
    this.$refs.form.validate((valid) => {
        if (valid) {
            // 传入表单数据
            getMenu(this.login).then((data) => {
                console.log(data);
                if(data.data.code===20000){
                    // 记录cookie
                    Cookie.set('token',data.data.data.token)
                    // 设置菜单
                    this.$store.commit('setMenu',data.data.data.menu)
                    // 跳转到首页
                    this.$router.push('/home')
                }else{
                    // 验证失败的弹窗
                    this.$message.error(data.data.data.message);
                }
            })
        }
    })
}

在CommonAside中显示菜单:在computed中

// 获取菜单
menuData() {
    return JSON.parse(cookie.get('menu')) || this.$store.state.tab.menu
}

效果:
以用户

username:xiaoxiao
password:xiaoxiao

登陆后,菜单发生了变化。
在这里插入图片描述

1.动态注册路由

我们在以xiaoxiao登陆后,在url处访问user,结果是可以访问。
原因是:我们在router处把路由写死了:

const routes = [
    // 主路由
    {
        path: '/',
        component: Main,
        redirect: '/home', // 重定向
        children: [
            // 子路由
            { path: '/home', name: 'home', component: Home }, // 首页
            { path: '/user', name: 'user', component: User }, // 用户管理
            { path: '/mall', name: 'mall', component: Mall }, // 商品管理
            { path: '/page1', name: 'page1', component: PageOne }, // 页面1
            { path: '/page2', name: 'page2', component: PageTwo }, // 页面2
        ]
    },
    {
        path: '/login',
        name: 'login',
        component: Login
    }
]

实际上,xiaoxiao只能访问“首页”和“商品管理”这两个路由。于是我们需要动态地添加路由。

在store的mutation处:addMenu,动态地添加路由:

// 动态添加路由
addMenu(state, router) {
    // 判断Cookie
    if (!Cookie.get('menu')) return
    const menu = JSON.parse(Cookie.get('menu'))
    state.menu = menu

    const menuArray=[]

    // 组装路由
    menu.forEach(item => {
        // 判断是否有子路由
        if (item.children) {
            item.children = item.children.map(itemm => {
                itemm.component = () => import(`../Views/${itemm.url}`)
                return itemm
            })
            menuArray.push(...item.children)
        } else {
            item.component=()=>import(`../Views/${item.url}`)
            menuArray.push(item)
        }
    });

    menuArray.forEach(item=>{
        router.addRoute('Main',item)
    })
}

在Login处commit:

// 动态添加路由
this.$store.commit('addMenu',this.$router)

注意要把router中写死的子路由注释掉。

效果:在登录xiaoxiao时访问user是访问不了的。

2.解决刷新后摆平问题

我们在登录之后刷新页面,会白屏,原因是:我们只在Login登陆处添加了路由。而vue页面在刷新后会重新渲染,此时就没有路由的代码了。

解决方法:在vue的created生命周期时就进行动态添加路由。

new Vue({
  router,
  store,
  render: h => h(App),
  created() {
    store.commit('addMenu', router)
  }
}).$mount('#app')

效果:刷新后也能显示页面了。

总代码

本篇修改的代码文件

  • CommonAside:显示菜单menuData,获取store的tab中的menu
  • router的index:注释掉子路由
  • store的tab:添加mutation的方法:设置菜单和动态添加路由;添加menu
  • Login:submit时commit在tab中新加的mutation方法
  • main.js:在created生命周期时就动态添加路由

在这里插入图片描述

tab.js

import Cookie from "js-cookie"

export default {
    state: {
        isCollapse: false,//导航栏是否折叠
        tabList: [
            {
                path: '/',
                name: 'home',
                label: '首页',
                icon: 's-home',
                url: 'Home/Home'
            }
        ],//面包屑的数据:点了哪个路由,首页是一定有的
        menu: [],//不同用户的菜单
    },
    mutations: {
        // 修改导航栏展开和收起的方法
        CollapseMenu(state) {
            state.isCollapse = !state.isCollapse
        },
        // 更新面包屑的数据
        SelectMenu(state, item) {
            // 如果点击的不在面包屑数据中,则添加
            const index = state.tabList.findIndex(val => val.name === item.name)
            if (index === -1) {
                state.tabList.push(item)
            }
        },
        // 删除tag:删除tabList中对应的item
        closeTag(state, item) {
            // 要删除的是state.tabList中的item
            const index = state.tabList.findIndex(val => val.name === item.name)
            state.tabList.splice(index, 1)
        },
        // 设置不同用户的菜单
        setMenu(state, val) {
            state.menu = val
            Cookie.set('menu', JSON.stringify(val))
        },
        // 动态添加路由
        addMenu(state, router) {
            // 判断Cookie
            if (!Cookie.get('menu')) return
            const menu = JSON.parse(Cookie.get('menu'))
            state.menu = menu

            const menuArray = []

            // 组装路由
            menu.forEach(item => {
                // 判断是否有子路由
                if (item.children) {
                    item.children = item.children.map(itemm => {
                        itemm.component = () => import(`../Views/${itemm.url}`)
                        return itemm
                    })
                    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)
            })
        }
    }
}
  • 3
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

karshey

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值