Vue 動(dòng)態(tài)路由,就是基于 router.addRoutes | router.addRoute
這個(gè) api
的一個(gè)功能實(shí)現(xiàn).
推薦使用
router.addRoute
, 因?yàn)?router.addRoutes
使用時(shí)會(huì)給出警告! 此函數(shù)會(huì)在vue-router v4.x 中被移除!
所謂的靜態(tài)路由.
常規(guī)模式下,我們的路由都是靜態(tài)的.
- 準(zhǔn)備好所有的路由表信息.
- 準(zhǔn)備好所有的顯示路由的
<router-view></router-view>
即可.
router 和組件結(jié)構(gòu)一一對應(yīng)
代碼例子:
export default new VueRouter({
mode: 'hash',
// 將所有的路由和路由信息都注冊到路由表里,這就叫所謂的[靜態(tài)路由]
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') }
]
})
界面:
靜態(tài)路由.gif
所謂的動(dòng)態(tài)路由
動(dòng)態(tài)路由只要是依仗于 vue-router
實(shí)例 router
提供的 addRoute
函數(shù),可以讓我們在[路由表中]|(路由配置中),動(dòng)態(tài)添加路由對象的能力,從而達(dá)到動(dòng)態(tài)路由的目的.
好處是: 當(dāng)你的路由表信息由于是動(dòng)態(tài)導(dǎo)入的,所以,對于那些沒有配置的到路由信息里的組件,即使你知道路由鏈接,也無法訪問.可以很好的做好的權(quán)限管理.
一般用于作為權(quán)限管理的時(shí)候使用.
動(dòng)態(tài)路由模式:
- 將一些公共路由,寫入到
./router/index.js
中.(公共權(quán)限) - 從后臺(tái)獲取用戶角色(或者動(dòng)態(tài)路由信息),將這些動(dòng)態(tài)路由數(shù)據(jù),通過
router.addRoute
注冊到路由表中. - 還是要將所有的
<router-view></router-view>
組件和結(jié)構(gòu)準(zhǔn)備好.
動(dòng)態(tài)路由
注意:
- 由于你路由的動(dòng)態(tài)加載的.
- 所以相應(yīng)的你的路由點(diǎn)擊鏈接也應(yīng)該是動(dòng)態(tài)加載的.
- 模板上依賴于你的動(dòng)態(tài)路由來循環(huán)
v-for
出點(diǎn)擊鏈接. - 所以,你需要使用一個(gè)響應(yīng)式的對象來存儲(chǔ)動(dòng)態(tài)路由鏈接信息列表.
- 你可以使用
vuex
以及任何其他的響應(yīng)式對象去存儲(chǔ). - 這里也包含從哪個(gè)地方注冊進(jìn)動(dòng)態(tài)路由信息以及路由信息緩存的問題.
所以,我這里使用 vuex
存儲(chǔ)動(dòng)態(tài)路由信息.
vuex
代碼
// 在這里使用 vuex 管理動(dòng)態(tài)路由
// 好處一: 可以做到動(dòng)態(tài)路由緩存.
// 好處二: 數(shù)據(jù)是響應(yīng)式的,當(dāng)動(dòng)態(tài)路由發(fā)生改變時(shí),模板會(huì)自動(dòng) render 更新.
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)
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' // 無權(quán)限提示組件,沒有必要設(shè)定成懶加載形式
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') },
// 對于用戶自己手動(dòng)的用輸入鏈接訪問路由表中不存在的路由組件,那么就直接提示無權(quán)訪問.
{ 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/D.json'
// 動(dòng)態(tài)路由請求并加載到路由表
vm.setUserRoutes(url).then(routes => {
// 動(dòng)態(tài)路由加載,包括緩存功能
routes.map(({ path, name, component }) => ({
path,
name,
component: () => import(`../components/${component}.vue`)
})).forEach(route => {
router.addRoute(route)
})
})
export default router
效果
動(dòng)態(tài)路由.gif