<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
動態路由,動態即不是寫死的,是可變的。我們可以根據自己不同的需求載入不同的路由,做到不同的實現及頁面的渲染。動態的路由儲存可分為兩種,一種是將路由儲存到前端。另一種則是將路由儲存到資料庫。動態路由的使用一般結合角色許可權控制一起使用。
總結:
1)路由可變,不是寫死的,動態載入
2)儲存分兩種:存前端,存資料庫
使用動態路由可以跟靈活,無需手工維護,我們可以使用一個頁面對路由進行維護。如果將路由儲存到資料庫,還可以增加安全性。
總結:
1)靈活,無需手工維護
2)增加安全性
在此以路由儲存在資料庫為例
流程:一般我們在登入的時候,根據登入使用者的角色返回此角色可以存取的頁面的路由,前端將路由儲存到vuex(vuex儲存的資料必須可持久的,不要一重新整理頁面就不見),我們在路由前置守衛處動態新增拿到的路由,對頁面進行渲染。
1)此為我的router目錄,index.js對路由新增,守衛攔截等處理。static-route.js為前端定義的靜態路由,不需要動態載入的,如登陸頁面,忘記密碼頁面,404頁面等。
index.js
import Vue from 'vue' import $cookies from 'vue-cookies' import VueRouter from 'vue-router' import store from '../store' import staticRoute from './static-route.js' Vue.use(VueRouter) const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes: staticRoute //staticRoute為靜態路由,不需動態新增 }) let isToken = true router.beforeEach(async (to, from, next) => { //定義isToken為true和vuex不為空時新增路由 if (isToken && store.state.routers.routers.length != 0) { //從vuex中獲取動態路由 const accessRouteses = await store.state.routers.routers; //動態路由迴圈解析和新增 accessRouteses.forEach(v => { v.children = routerChildren(v.children); v.component = routerCom(v.component); router.addRoute(v); //新增 }) isToken = false //將isToken賦為 false ,否則會一直迴圈,崩潰 next({ ...to, // next({ ...to })的目的,是保證路由新增完了再進入頁面 (可以理解為重進一次) replace: true, // 重進一次, 不保留重複歷史 }) } else { if (to.name == null) { next("/404") } else { if (to.meta.title) { //判斷是否有標題 document.title = to.meta.title //給相應頁面新增標題 } next() } } }) function routerCom(path) { //對路由的component解析 return (resolve) => require([`@/views/${path}`], resolve); } function routerChildren(children) { //對子路由的component解析 children.forEach(v => { v.component = routerCom(v.component); if (v.children != undefined) { v.children = routerChildren(v.children) } }) return children } export default router
2)登陸成功後將獲取到的動態路由儲存到vuex
vuex—>index.js
import Vue from 'vue' import Vuex from 'vuex' //資料持久化 import createPersistedState from "vuex-persistedstate"; Vue.use(Vuex) const routers = { namespaced: true, state: () => ({ routers:"", }), mutations: { routers(state, newsdata) { state.routers = newsdata }, }, actions: { routers(context) { context.commit('routers') }, }, getters: { routers(state) { console.log("getters", state) return state.routers }, } } const store = new Vuex.Store({ modules: { routers: routers, }, // 資料持久化 plugins: [createPersistedState({ //key是儲存資料的鍵名 key: 'routersData', //paths是儲存state中的那些資料,如果是模組下具體的資料需要加上模組名稱,如user.token paths: ["routers.routers"] })] }) export default store
我的動態路由模板
//動態路由 const dynamicRoute = [{ "path": "/main", "name": "main", "redirect": "/main/index", "component": "main/main.vue", "children": [{ "path": "index", "name": "index", "component": "index/index.vue", "meta": { "name": "index", "title": "首頁", "icon": "el-icon-location", "menu":true //true為選單欄 } }, { "path": "Configuration", "name": "Configuration", "redirect": "Configuration/route", "component": "Configuration/index.vue", "roles": ['developer', "admin"], // developer、admin角色的使用者才能存取該頁面 "meta": { "title": "設定", "icon": "el-icon-location", "menu":true }, "children": [{ "path": "route", "name": "route", "component": "Configuration/route/index.vue", "meta": { "title": "選單", "icon": "", "menu":true }, }, { "path": "user", "name": "user", "component": "Configuration/user/index.vue", "meta": { "title": "使用者管理", "icon": "el-icon-location", "menu":true }, }, { "path": "admin", "name": "admin", "component": "Configuration/admin/index.vue", "meta": { "title": "管理員管理", "icon": "", "menu":true }, }, { "path": "userEdit", "name": "userEdit", "component": "Configuration/user/user-Edit.vue", "meta": { "title": "編輯使用者", "icon": "", "menu":false }, }, ] }, { "path": "check", "name": "check", "redirect": "check/user", "component": "check/index.vue", "roles": ['developer', "admin", "check"], // developer、admin角色的使用者才能存取該頁面 "meta": { "title": "稽核", "icon": "el-icon-location", "menu":true }, "children": [{ "path": "user", "name": "checkUser", "component": "check/check-user/index.vue", "meta": { "title": "使用者實名稽核", "icon": "el-icon-location", "menu":true } }, { "path": "enterprise", "name": "checkEnterprise", "component": "check/check-enterprise/index.vue", "meta": { "title": "企業認證稽核", "icon": "el-icon-location", "menu":true }, }, { "path": "checkNormImage", "name": "checkNormImage", "component": "check/check-norm-image/index.vue", "meta": { "title": "標準照認證稽核", "icon": "el-icon-location", "menu":true }, }, { "path": "checkHiringJobs", "name": "checkHiringJobs", "component": "check/check-hiring-Jobs/index.vue", "meta": { "title": "求職、招聘認證稽核", "icon": "el-icon-location", "menu":true }, } ] } ] }, ] export default dynamicRoute
路由管理介面(可能有不完善的地方)
講一講遇到的坑及注意點
1)“component”: “check/check-norm-image/index.vue”, 用字串再在解析,不要像靜態路由一樣。否則第一次進去可以,重新整理就變空白
2)此處為重要的一點,直接用next()不行
next({ ...to, // next({ ...to })的目的,是保證路由新增完了再進入頁面 (可以理解為重進一次) replace: true, // 重進一次, 不保留重複歷史 })
3)由於新增完路由還會重複執行一遍路由守衛,所有必須確保不要一直死迴圈新增路由。否則直接崩潰。這裡我用的是isToken變數確保不迴圈。
到此這篇關於vue實現動態路由的文章就介紹到這了,更多相關vue實現動態路由內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45