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

Posted 编程界明世隐

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue开发实例(15)之动态路由相关的知识,希望对你有一定的参考价值。

引言

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从零到精通

以上是关于Vue开发实例(15)之动态路由的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法在 vuejs 路由器中拥有动态路由/组件?

Vue-Router路由Vue-CLI脚手架和模块化开发 之 路由的动态跳转

vue动态添加路由addRoutes之不能将动态路由存入缓存

Vue全家桶之前端路由

vue项目实现动态路由和动态菜单搭建插件式开发框架免费源码

vue3.0 Composition API 上手初体验 用路由循环,做个导航菜单