首頁 >web前端 >js教程 >Vue動態路由的實作(後台傳遞路由,前端拿到並產生側邊欄)

Vue動態路由的實作(後台傳遞路由,前端拿到並產生側邊欄)

不言
不言原創
2018-07-09 14:25:1728542瀏覽

這篇文章主要介紹了關於Vue動態路由的實現(後台傳遞路由,前端拿到並生成側邊欄),有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下

地獄空蕩蕩,師兄在土創。雖然土,但是可以療傷。

前言

vue專案實作動態路由的方式大體可分為兩種:
#1.前端這邊把路由寫好,登入的時候根據使用者的角色權限來動態展示路由,(前端控制路由)
詳情可參閱花褲衩大佬的專案手把手...,我當時看這個專案看了好久才明白一點邏輯,
因為大神的動態路由那裡有很多層次判斷,並且穿插各種vuex,把小白的我都快搞懵逼了,對我啟發很大,也正是這篇文章,給我提供了很多邏輯
2.後台傳來當前用戶對應權限的路由表,前端透過調接口拿到後處理(後端處理路由)
這兩種方法各有優點,效果都能實現,我們公司是透過第二中種方法實現的,原因就是公司專案裡有一個專門的用戶中心,裡邊邏輯很複雜,不好返給前端用戶權限,擔心路由放到前端
不安全(以上的話是公司的後台同學講的),那好吧,抱著都試試、鍛煉下自己能力的態度,
我們搞了第二種方法。

今天我們來講講用後台傳遞路由表實現動態路由的思路,因為公司的專案里路有部分用到了vuex,我就把路由部分脫離vuex整理了出來,讓大家有個啟發,並不是絕對的解決方案,只是思路
github:https://github.com/Mrblackant...
線上看:http: //an888.net/antRouter/#/...
Vue動態路由的實作(後台傳遞路由,前端拿到並產生側邊欄)

思路整理

以下四步驟對應的程式碼都在下方會講到,並且是對應的

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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn