這篇文章主要介紹了關於Vue動態路由的實現(後台傳遞路由,前端拿到並生成側邊欄),有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下
地獄空蕩蕩,師兄在土創。雖然土,但是可以療傷。
vue專案實作動態路由的方式大體可分為兩種:
#1.前端這邊把路由寫好,登入的時候根據使用者的角色權限來動態展示路由,(前端控制路由)
詳情可參閱花褲衩大佬的專案手把手...,我當時看這個專案看了好久才明白一點邏輯,
因為大神的動態路由那裡有很多層次判斷,並且穿插各種vuex,把小白的我都快搞懵逼了,對我啟發很大,也正是這篇文章,給我提供了很多邏輯
2.後台傳來當前用戶對應權限的路由表,前端透過調接口拿到後處理(後端處理路由)
這兩種方法各有優點,效果都能實現,我們公司是透過第二中種方法實現的,原因就是公司專案裡有一個專門的用戶中心,裡邊邏輯很複雜,不好返給前端用戶權限,擔心路由放到前端
不安全(以上的話是公司的後台同學講的),那好吧,抱著都試試、鍛煉下自己能力的態度,
我們搞了第二種方法。
今天我們來講講用後台傳遞路由表實現動態路由的思路,因為公司的專案里路有部分用到了vuex,我就把路由部分脫離vuex整理了出來,讓大家有個啟發,並不是絕對的解決方案,只是思路
github:https://github.com/Mrblackant...
線上看:http: //an888.net/antRouter/#/...
以下四步驟對應的程式碼都在下方會講到,並且是對應的
1.後台同學回傳一個json格式的路由表,我用easymock造了一段:動態路由表,大家可參考;
2.因為後端同學傳回來的都是字串格式的,但是前端這裡需要的是一個元件物件啊,寫個方法遍歷一下,將字串轉換為元件物件;
3.利用vue-router的beforeEach、addRoutes、 localStorage來配合上邊兩步驟實現效果;
4.左側選單列根據拿到轉換好的路由清單進行展示;
大體步驟:攔截路由->後台取到路由->保存路由到localStorage(用戶登入進來只會從後台取一次,其餘都從本地取,所以用戶,只有退出在登入路由才會更新)
1.路由表
每個路由都使用到元件Layout,這個元件是整體的頁面佈局:左側選單列,右邊頁面,所以children下邊的第一級路由就是你自己的開發的頁面,meta裡包含著路由的名字,以及路由對應的icon;
因為可能會有多級菜單,所以會出現children下邊嵌套children的情況;
路由是數組格式
"data": { "router": [ { "path": "", "component": "Layout", "redirect": "dashboard", "children": [ { "path": "dashboard", "component": "dashboard/index", "meta": { "title": "首页", "icon": "dashboard" } } ] }, { "path": "/example", "component": "Layout", "redirect": "/example/table", "name": "Example", "meta": { "title": "案例", "icon": "example" }, "children": [ { "path": "table", "name": "Table", "component": "table/index", "meta": { "title": "表格", "icon": "table" } }, { "path": "tree", "name": "Tree", "component": "tree/index", "meta": { "title": "树形菜单", "icon": "tree" } } ] }, { "path": "/form", "component": "Layout", "children": [ { "path": "index", "name": "Form", "component": "form/index", "meta": { "title": "表单", "icon": "form" } } ] }, { "path": "*", "redirect": "/404", "hidden": true } ] }
2.將後端傳回的"component": "Layout", 轉為"component": Layout元件物件
因為有多級路由的出現,所以要寫成遍歷遞歸方法,確保把每個component轉成對象,
因為後台傳回的是字串,所以要把載入元件的過程封裝成一個方法(此處參考花褲衩大神的解決方法),用這個方法在遍歷中使用;詳情查看專案裡的router資料夾下的_import_development.js和_import_production.js檔案
Layout我放的目錄跟其他檔案的目錄不一樣,所以我在遍歷裡單獨處理,各位小伙伴可自己調整哈
const _import = require('./router/_import_' + process.env.NODE_ENV)//获取组件的方法 import Layout from '@/views/layout' //Layout 是架构组件,不在后台返回,在文件里单独引入 function filterAsyncRouter(asyncRouterMap) { //遍历后台传来的路由字符串,转换为组件对象 const accessedRouters = asyncRouterMap.filter(route => { if (route.component) { **加粗文字** if (route.component === 'Layout') {//Layout组件特殊处理 route.component = Layout } else { route.component = _import(route.component) } } if (route.children && route.children.length) { route.children = filterAsyncRouter(route.children) } return true }) return accessedRouters }
3.使用beforeEach、addRoutes、localStorage來配合實現
beforeEach路由攔截,進入判斷,如果發現本地沒有路由數據,那就利用axios後台取一次,取完以後,利用localStorage存儲起來,利用addRoutes動態添加路由,
ps:beforeEach好壞啊,一步小心就進入到了他的死循環,瀏覽器都tm崩了,得在一開始就加判斷,拿到路由了,就直接next(),嚶嚶嚶
global.antRouter是為了傳遞資料給左側選單元件進行渲染
import axios from 'axios' var getRouter //用来获取后台拿到的路由 router.beforeEach((to, from, next) => { if (!getRouter) {//不加这个判断,路由会陷入死循环 if (!getObjArr('router')) { axios.get('https://www.easy-mock.com/mock/5a5da330d9b48c260cb42ca8/example/antrouter').then(res => { getRouter = res.data.data.router//后台拿到路由 saveObjArr('router', getRouter) //存储路由到localStorage routerGo(to, next)//执行路由跳转方法 }) } else {//从localStorage拿到了路由 getRouter = getObjArr('router')//拿到路由 routerGo(to, next) } } else { next() } }) function routerGo(to, next) { getRouter = filterAsyncRouter(getRouter) //过滤路由 router.addRoutes(getRouter) //动态添加路由 global.antRouter = getRouter //将路由数据传递给全局变量,做侧边栏菜单渲染工作 next({ ...to, replace: true }) } function saveObjArr(name, data) { //localStorage 存储数组对象的方法 localStorage.setItem(name, JSON.stringify(data)) } function getObjArr(name) { //localStorage 获取数组对象的方法 return JSON.parse(window.localStorage.getItem(name)); }
4.拿到遍歷好的路由,進行左側選單渲染
上邊第三部會為 global.antRouter賦值,這是一個全域變數(可以用vuex取代),選單那邊拿到路由,進行渲染,這裡又是參考了花褲衩大神的layout部分,這裡我就不貼代碼了
才疏學淺,希望大家多多指正,尤其對於路由攔截那部分,應該還有很多優化的地方,歡迎指正
以上就是本文的全部內容,希望對大家的學習有幫助,更多相關內容請關注PHP中文網!
相關推薦:
以上是Vue動態路由的實作(後台傳遞路由,前端拿到並產生側邊欄)的詳細內容。更多資訊請關注PHP中文網其他相關文章!