Vue开发实例(15)之动态路由

本文介绍了如何在Vue中实现动态路由,结合状态管理Vuex处理用户权限,确保无权限的路由无法被访问。通过模拟数据和动态创建菜单,展示了如何根据用户权限动态生成并限制路由,防止非法访问。同时,还讲解了如何避免路由重复加载,优化用户体验。
摘要由CSDN通过智能技术生成

引言

Vue是现在前端最流行的框架之一,作为前端开发人员应该要熟练的掌握它,如果你是打算学习Vue的开发流程,那么来吧,明哥带你快速上手、带你飞!
即使你并非前端开发人员,对前端的开发流程进行一定的了解也是很有必要的,谁也不确定公司以后会不会让我做前端去,做些简单的实例既不需要花费很多时间,也可以提高自己的自信和成就感,所以跟着明哥走,没有错,来吧!

导航

✪  Vue开发实例目录总索引
上一篇【14】Vue状态管理store
下一篇【16】创建标签页

概述

场景是这样的:
假如我定义了3条路由,分别是 ‘/index/menu1’,‘/index/menu2’,‘/index/menu3’
但当前登录的用户只有 ‘/index/menu1’,‘/index/menu2’ 两条路由的权限,如果按照之前章节的做法,可以直接在浏览器输入’/index/menu3’ 这条路由地址来访问,这显然是不对的,于是这里我们就用到动态路由。

回顾

菜单页面 Aside.vue

<template>
    <div style="height: 100%;">
        <el-menu background-color="#545c64" text-color="#ffffff"
                 active-text-color="#ffd04b" class="el-menu-vertical-demo"
                 router>
            <el-menu-item :index="item.path" v-for="item in menu_data" :key="item.name">
                <i :class="item.icon"></i>{{item.name}}
            </el-menu-item>
        </el-menu>
    </div>
</template>

<script>
    export default {
        name: "Aside",
        data(){
            return {
                menu_data:[
                    {
                        name:'一级菜单1',
                        icon:'el-icon-location',
                        path:'/index/menu1'
                    },
                    {
                        name:'一级菜单2',
                        icon:'el-icon-document',
                        path:'/index/menu2'
                    },
                    {
                        name:'一级菜单3',
                        icon:'el-icon-setting',
                        path:'/index/menu3'
                    }
                ]
            }
        }
    }
</script>

<style scoped>
    .el-menu-vertical-demo{
        height: 100%;

    }
</style>

路由代码 router.js


import VueRouter from "vue-router"
import Index from "./components/Index";
import Aside from "./components/Aside";

const routes = [
    //一级路由
    {
        path: '/index',
        name: 'index',
        component: Index,
        redirect: '/index/Main',
        //路由嵌套
        children:[
            {path: '/index/Main',component: () => import('./components/Main.vue')},
            {path: '/index/menu1',component: () => import('./components/Main1.vue')},
            {path: '/index/menu2',component: () => import('./components/Main2.vue')},
            {path: '/index/menu3',component: () => import('./components/Main3.vue')}
        ]
    },
    {
        path: '/aside',
        name: 'aside',
        component: Aside
    }
]

const router = new VueRouter({
    mode:'history',
    routes
})

export  default router;

下方的3条子路由,假设后端只返回menu1和menu2这2条,也就是这路由,我们只需动态创建2条即可。
在这里插入图片描述

动态创建菜单

目前菜单已经是动态创建了,只是数据是写死的,就用之前章节的mockjs来模拟数据,并且动态数据中没有menu3,这样就只会创建出前两个菜单。

  1. 原来的 menu_data 使用mockjs来返回,模拟后台查询菜单数据返回:
  • 在mockjs中定义对象的/post/menuList 路径get请求
  • 返回参数中除了原来的 name、icon、path 增加了component,用于定义跳转路径。
Mock.mock('/post/menuList','get',function(){
    const menu_data = [
        {
            name:'一级菜单1',
            icon:'el-icon-location',
            path:'/index/menu1',
            component:'Main1'
        },
        {
            name:'一级菜单2',
            icon:'el-icon-document',
            path:'/index/menu2',
            component:'Main2'
        }
    ]

    return{
        menu_data
    }
});

  1. 在store.js中修改

state 增加属性menu_data

const state ={
    username: '明世隐',
    userState:0,
    menu_data:[]
}

mutations 中增加方法setMenuData

setMenuData(state,data){
   state.menu_data = data
}
  1. 在router.js 里面使用方法 beforeEach 来获取数据,并提交到store
  1. axios.get(‘/post/menuList’) 获取模拟后台传来的菜单数据
  2. store.commit(‘setMenuData’,res.data.menu_data) 提交数据
router.beforeEach((to, from, next)=>{
    next();
    axios.get('/post/menuList').then(res=>{
         store.commit('setMenuData',res.data.menu_data)
    });
})
  1. data里面的属性menu_data不能直接返回了,需通过computed来返回,并且返回的值是从store里面获取的
computed:{
   menu_data:{
       get(){
           return this.$store.state.menu_data
       }
    }
}

此时Aside.vue完整代码如下:

<template>
    <div style="height: 100%;">
        <el-menu background-color="#545c64" text-color="#ffffff"
                 active-text-color="#ffd04b" class="el-menu-vertical-demo"
                 router>
            <el-menu-item :index="item.path" v-for="item in menu_data" :key="item.name">
                <i :class="item.icon"></i>{{item.name}}
            </el-menu-item>
        </el-menu>
    </div>
</template>

<script>
    export default {
        name: "Aside",
        data(){
            return {}
        },
        computed:{
            menu_data:{
               get(){
                   return this.$store.state.menu_data
               }
            }
        }

    }
</script>

<style scoped>
    .el-menu-vertical-demo{
        height: 100%;

    }
</style>
  1. 页面效果
    在这里插入图片描述

此时菜单确实只有2个菜单,点击菜单也能对应访问到路由menu1和menu2,但是当我们在地址栏输入 menu3的时候,也能访问,这显然是不对的,因为我们的路由是静态写死的,这里肯定是不合理的,所以需要动态来修改一下。

在这里插入图片描述

根据菜单数据来创建路由

先看看我们目前路由的写法
在这里插入图片描述
针对上面的情况,我们是不是可以考虑,通过菜单取到的数据,动态的添加这个路由呢,而不是直接写死。

  1. 先将这3条路由代码删除

在这里插入图片描述
2. 在router.js中创建添加动态路由的方法 buildRouter

let oRouters = router.options.routes;
const buildRouter = ()=>{
    let data = store.state.menu_data;
    data.forEach(item=>{
        let new_router = {
            path:item.path,
            component:() => import('./components/'+item.component+'.vue')
        }
        oRouters[0].children.push(new_router);
    })
    router.addRoutes(oRouters)
}
  1. 在创建动态菜单的同时调用这个函数

修改之前的 beforeEach,调用buildRouter

router.beforeEach((to, from, next)=>{
    next();
    axios.get('/post/menuList').then(res=>{
         store.commit('setMenuData',res.data.menu_data);

        //动态创建路由
        buildRouter();
    });

})
  1. 测试

menu1 menu2 测试点击正常

在这里插入图片描述

地址栏输入menu3,页面无法显示,因为没有这条路由

在这里插入图片描述

添加路由已加载标记,省的每次点击菜单都要加载

  1. 在store.js的state添加 属性isLoadRoute为false
    在这里插入图片描述

  2. 在 mutations 添加更新方法

setLoadRoute(state,data){
    state.isLoadRoute = data
}
  1. 在router.js 添加路由的 router.beforeEach 稍作修改
router.beforeEach((to, from, next)=>{
    //判断路由是否已经加载过
    let isLoadRoute = store.state.isLoadRoute;
    if(!isLoadRoute){
        axios.get('/post/menuList').then(res=>{
            store.commit('setMenuData',res.data.menu_data);

            //动态创建路由
            buildRouter();
            //设置已经加载过的标记
            store.commit("setLoadRoute",true);
        });
    }
    next();
})

此时点击菜单就不会重复加载了。

小结

这节总结了“ 动态路由 ”,希望能对大家有所帮助,请各位小伙伴帮忙 【点赞】+【收藏】+ 【评论区打卡】, 如果有兴趣跟小明哥一起学习Java和前端的,【关注一波】不迷路哦。
请到文章下方帮忙【一键三连】谢谢哈!

在这里插入图片描述

导航

✪  Vue开发实例目录总索引
上一篇【14】Vue状态管理store
下一篇【16】创建标签页

热门专栏推荐

【1】Java小游戏(俄罗斯方块、植物大战僵尸等)
【2】JavaWeb项目实战(图书管理、宿舍管理等)
【3】JavaScript精彩实例(飞机大战、验证码等)
【4】Java小白入门200例
【5】从零学Java、趣学Java
【6】IDEA从零到精通
在这里插入图片描述

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

编程界小明哥

请博主喝瓶水,博主持续输出!

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

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

打赏作者

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

抵扣说明:

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

余额充值