Vue 动态路由,顾名思义,就是我们的路由是动态加载的而不是写死的, 本质就是使用vue提供的 router.addRoutes 或者 router.addRoute
这两个函数的功能实现的
注意:推荐大家使用
router.addRoute
, 因为router.addRoutes
使用会有警告并且此函数在vue-router v4.x 里被删除了
静态路由
一般情况,我们的路由都是静态的
- 写出route 对应的path和component
- 注意path和component时固定的写死的
router 和组件一一对应
export default new VueRouter({
mode: 'hash',
// 将所有的路由和组件都注册到这里,这就是[静态路由],因为都是固定好的
routes: [
{ path: '/', component: () => import('../components/A.vue') },
{ path: '/b', component: () => import('../components/B.vue') },
{ path: '/c', component: () => import('../components/C.vue') },
{ path: '/d', component: () => import('../components/D.vue') }
]
})
动态路由
动态路由只要是依仗于 vue-router
实例 router
提供的 addRoute()
函数,可以让我们在路由配置中动态添加路由对象的能力,从而达到动态路由的目的.
路由配置由于是动态导入的,所以, 对于那些没有配置的到路由配置里的组件,即使知道路由链接,也无法访问.可以很好的做好的权限管理.
一般用于作为权限管理的时候使用
动态路由模式:
- 将一些公共路由,写入到
./router/index.js
中.(登录,注册之类的) - 从后台获取用户角色(或者动态路由信息),将这些动态路由数据,通过
router.addRoute
()添加到路由配置数组中
注意:
- 路由的动态加载的,所以相应的路由点击链接 ( 路由跳转的路径 )也应该是动态加载的
- 依据动态路由来循环
v-for
出点击链接 - 可以使用
vuex
来保存动态路由信息 - 从哪添加动态路由配置以及动态的路由缓存问题
vuex
代码
// 用 vuex 管理动态路由
// 可以做到动态路由缓存.
// 数据是响应式的,当动态路由发生改变时,页面的遍历会自动改变
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
userRoutes: [] // 用户的路由信息
},
mutations: {
setUserRoutes (state, payload) {
state.userRoutes = payload
}
},
actions: {
//请求后端获取路由
async setUserRoutes({ commit, getters, state }, url) {
//如果第一次进入项目,没有路由则请求后端,动态设置路由
if (!state.userRoutes.length) {
// 异步路由缓存,请求后端接口获取路由
const { data } = await axios.get(url);
console.log(data, "请求后端获取的路由信息");
// 提交mutatuons存储路由到vuex
commit("setUserRoutes", data);
return data;
}
//如果已经获取过路由了,则直接返回现有路由
return getters.userRoutes;
}
},
getters: {
userRoutes (state) {
return state.userRoutes
}
}
})
vue-router
代码
import Vue from 'vue'
import VueRouter from 'vue-router'
import NoAuthorization from '../components/NoAuthorization.vue' // 无权限提示组件,没有必要设定成懒加载形式
Vue.use(VueRouter)
import store from '../vuex'
import { mapActions } from 'vuex'
const vm = new Vue({
store,
methods: {
...mapActions(["setUserRoutes"])
}
})
const router = new VueRouter({
mode: 'hash',
// 将公用路由注册到路由表中
routes: [
{ path: '/', component: () => import('../components/A.vue') },
{ path: '/b', component: () => import('../components/B.vue') },
// 对于用户自己手动的用输入链接访问路由表中不存在的路由组件,那么就直接提示无权访问.
{ path: '*', component: NoAuthorization }
// { path: '/c', component: () => import('../components/C.vue') }, // C 角色的专属路由
// { path: '/d', component: () => import('../components/D.vue') } // D 角色的专属路由
]
})
// const url = '/static/C.json'
const url = "/static/CD.json";
// 请求调用方法请求后端接口动态设置路由
store.dispatch("setUserRoutes", url).then(routes => {
// 动态路由加载,包括缓存功能,处理成vuerouter认识的数据结构 {path:'',name:'',component:''}
let dynamicRouter = routes.map(item => {
//获取path,name,component 注意component必须是已经定义的vue文件的名字
let { path, name, component } = item;
return {
path,
name,
component: () => import(`../components/${component}.vue`)
};
});
//遍历请求的数据使用addRoute方法添加到路由中,这就是所谓的动态的路由了
dynamicRouter.forEach(route => {
router.addRoute(route);
});
});
export default router
CD.json 的数据
//我这里为了方便设置的数据结构和vueRouter需要的结构是一样的
[
{
"path": "/c",
"name": "去 C 组件",
"component": "C"
},
{
"path": "/d",
"name": "去 D 组件",
"component": "D"
}
]