首頁 > 軟體

手把手教你vue實現動態路由

2022-07-10 14:01:55

1、什麼是動態路由?

動態路由,動態即不是寫死的,是可變的。我們可以根據自己不同的需求載入不同的路由,做到不同的實現及頁面的渲染。動態的路由儲存可分為兩種,一種是將路由儲存到前端。另一種則是將路由儲存到資料庫。動態路由的使用一般結合角色許可權控制一起使用。

總結:

     1)路由可變,不是寫死的,動態載入

     2)儲存分兩種:存前端,存資料庫

2、動態路由的好處

使用動態路由可以跟靈活,無需手工維護,我們可以使用一個頁面對路由進行維護。如果將路由儲存到資料庫,還可以增加安全性。

總結:

     1)靈活,無需手工維護

     2)增加安全性

3、動態路由如何實現

在此以路由儲存在資料庫為例

流程:一般我們在登入的時候,根據登入使用者的角色返回此角色可以存取的頁面的路由,前端將路由儲存到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!


IT145.com E-mail:sddin#qq.com