引言
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,这样就只会创建出前两个菜单。
- 原来的 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
}
});
- 在store.js中修改
state 增加属性menu_data
const state ={
username: '明世隐',
userState:0,
menu_data:[]
}
mutations 中增加方法setMenuData
setMenuData(state,data){
state.menu_data = data
}
- 在router.js 里面使用方法 beforeEach 来获取数据,并提交到store
- axios.get(‘/post/menuList’) 获取模拟后台传来的菜单数据
- 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)
});
})
- 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>
- 页面效果
此时菜单确实只有2个菜单,点击菜单也能对应访问到路由menu1和menu2,但是当我们在地址栏输入 menu3的时候,也能访问,这显然是不对的,因为我们的路由是静态写死的,这里肯定是不合理的,所以需要动态来修改一下。
根据菜单数据来创建路由
先看看我们目前路由的写法 针对上面的情况,我们是不是可以考虑,通过菜单取到的数据,动态的添加这个路由呢,而不是直接写死。
- 先将这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)
}
- 在创建动态菜单的同时调用这个函数
修改之前的 beforeEach,调用buildRouter
router.beforeEach((to, from, next)=>{
next();
axios.get('/post/menuList').then(res=>{
store.commit('setMenuData',res.data.menu_data);
buildRouter();
});
})
- 测试
menu1 menu2 测试点击正常
地址栏输入menu3,页面无法显示,因为没有这条路由
添加路由已加载标记,省的每次点击菜单都要加载
-
在store.js的state添加 属性isLoadRoute为false -
在 mutations 添加更新方法
setLoadRoute(state,data){
state.isLoadRoute = data
}
- 在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从零到精通
|