Vue開發實例(九)動態路由實現左側菜單導航

之前在【Vue開發實例(六)實現左側菜單導航】文中實現了菜單的導航,本篇是在那個基礎上改造的。

動態路由實現左側菜單導航

  • 一、動態菜單創建
  • 二、根據菜單數據來創建路由
  • 三、添加路由已加載標記,省的每次點擊菜單都要加載

一、動態菜單創建

假如我定義了3條路由,分別是 ‘/index/menu1’,‘/index/menu2’,‘/index/menu3’
但當前登錄的用戶只有 ‘/index/menu1’,‘/index/menu2’ 兩條路由的權限,如果按照【Vue開發實例(六)實現左側菜單導航】的做法,可以直接在瀏覽器輸入’/index/menu3’ 這條路由地址來訪問,這顯然是不對的,于是我們就需要動態路由。

在前文中,router/index.js下方的3條子路由,假設后端只返回menu1和menu2這2條,也就是這路由,我們只需動態創建2條即可。
在這里插入圖片描述

  1. 原來的 menu_data 使用mockjs來返回,模擬后臺查詢菜單數據返回
    • 在mockjs中定義對象的 /post/menuList 路徑get請求
    • 返回參數中除了原來的 name、icon、path 增加了component,用于定義跳轉路徑。

mock/index.js代碼

Mock.mock('/post/menuList', 'get', function () {const menu_data = [{name: '一級菜單1',icon: 'el-icon-location',path: '/index/menu1',component: 'Main1'},{name: '一級菜單2',icon: 'el-icon-document',path: '/index/menu2',component: 'Main2'}]return {menu_data}
});
  1. 修改store/index.js,全部參考代碼如下
    在這里插入圖片描述
import Vue from 'vue'
import Vuex from 'vuex'
import moduleA from './module/moduleA.js';
import moduleB from './module/moduleB.js';Vue.use(Vuex)const state = {username: '牛牛',userState: 0,menu_data: []
}
const mutations = {setUser(state, name) {state.username = name},setUserState(state, data) {state.userState += data},setMenuData(state, data) {state.menu_data = data},
}
const getters = {getUserState(state) {let data;if (state.userState == 0) {data = '無效'} else {data = state.userState + '級'}return data;}
}
const modules = {a: moduleA,b: moduleB
}export default new Vuex.Store({state,mutations,getters,modules
})
  1. router/index.js 里面使用方法 beforeEach 來獲取數據,并提交到store

注意:

  • 不要忘記引入axios和store的內容
import axios from "axios";
import store from "@/store/index.js";

在這里插入圖片描述

import VueRouter from "vue-router"
import Index from "@/components/Index";
import axios from "axios";
import store from "@/store/index.js";const routes = [//一級路由{path: '/index',name: 'index',component: Index,redirect: 'index/Main',//路由嵌套children:[{path: '/index/Main',component: () => import('@/components/Main/index.vue')},{path: '/index/menu1',component: () => import('@/components/Main/Main1.vue')},{path: '/index/menu2',component: () => import('@/components/Main/Main2.vue')},{path: '/index/menu3',component: () => import('@/components/Main/Main3.vue')}]}
]
const router = new VueRouter({mode:'history',routes
})
router.beforeEach((to, from, next)=>{next();axios.get('/post/menuList').then(res=>{store.commit('setMenuData',res.data.menu_data)});
})
export  default router;
  1. Aside.vue 代碼中,data里面的屬性menu_data不能直接返回了,需通過computed來返回,并且返回的值是從store里面獲取的

Aside.vue 參考代碼如下

<template><div style="height: 100%"><el-menubackground-color="#545c64"text-color="#ffffff"active-text-color="#ffd04b"class="el-menu-vertical-demo"router><el-menu-item:index="item.path"v-for="item in menu_data":key="item.name"><i :class="item.icon"></i>{{ item.name }}</el-menu-item></el-menu></div>
</template><script>
export default {name: "Aside",data() {return {};},computed: {menu_data: {get() {return this.$store.state.menu_data;},},},
};
</script><style scoped>
.el-icon-location,
.el-icon-document,
.el-icon-setting {display: inline-flex;align-items: center;justify-content: center;
}
</style>

頁面效果
在這里插入圖片描述

此時菜單確實只有2個菜單,點擊菜單也能對應訪問到路由menu1和menu2,但是當我們在地址欄輸入 menu3的時候,也能訪問,這顯然是不對的,因為我們的路由是靜態寫死的,這里肯定是不合理的,所以需要動態來修改一下。

在這里插入圖片描述

二、根據菜單數據來創建路由

目前的路由寫法

const routes = [//一級路由{path: '/index',name: 'index',component: Index,redirect: 'index/Main',//路由嵌套children:[{path: '/index/Main',component: () => import('@/components/Main/index.vue')},{path: '/index/menu1',component: () => import('@/components/Main/Main1.vue')},{path: '/index/menu2',component: () => import('@/components/Main/Main2.vue')},{path: '/index/menu3',component: () => import('@/components/Main/Main3.vue')}]}
]

針對上面的情況,我們可以考慮,通過菜單取到的數據,動態添加這個路由,而不是直接寫死。

說干就干!!!

  1. 先將router/index.js這3條路由代碼刪除
const routes = [//一級路由{path: '/index',name: 'index',component: Index,redirect: 'index/Main',//路由嵌套children:[{path: '/index/Main',component: () => import('@/components/Main/index.vue')},]}
]
  1. router/index.js 中創建添加動態路由的方法 buildRouter
let oRouters = router.options.routes;
const buildRouter = () => {let data = store.state.menu_data;data.forEach(item => {let new_router = {path: item.path,component: () => import('../components/Main/' + item.component + '.vue')}oRouters[0].children.push(new_router);})router.addRoutes(oRouters)
}
  1. 在創建動態菜單的同時調用這個函數,修改 router/index.js
router.beforeEach((to, from, next)=>{next();axios.get('/post/menuList').then(res=>{store.commit('setMenuData',res.data.menu_data);//動態創建路由buildRouter();});
})

頁面展示,點擊訪問 index/menu1index/menu2正常
在這里插入圖片描述

訪問 index/menu3 就不會出現頁面內容
在這里插入圖片描述
全部參考代碼

router/index.js

import VueRouter from "vue-router"
import Index from "@/components/Index";
import axios from "axios";
import store from "@/store/index.js";const routes = [//一級路由{path: '/index',name: 'index',component: Index,redirect: 'index/Main',//路由嵌套children: [{ path: '/index/Main', component: () => import('@/components/Main/index.vue') },]}
]const router = new VueRouter({mode: 'history',routes
})let oRouters = router.options.routes;
const buildRouter = () => {let data = store.state.menu_data;data.forEach(item => {let new_router = {path: item.path,component: () => import('../components/Main/' + item.component + '.vue')}oRouters[0].children.push(new_router);})router.addRoutes(oRouters)
}router.beforeEach((to, from, next) => {next();axios.get('/post/menuList').then(res => {store.commit('setMenuData', res.data.menu_data);//動態創建路由buildRouter();});
})export default router;

三、添加路由已加載標記,省的每次點擊菜單都要加載

  1. 修改 store/index.js,在store.js的state添加 屬性isLoadRoute: false
    在這里插入圖片描述
  2. router/index.js 添加路由的 router.beforeEach 稍作修改
    在這里插入圖片描述

store和router的相關代碼如下

store/index.js代碼

import Vue from 'vue'
import Vuex from 'vuex'
import moduleA from './module/moduleA.js';
import moduleB from './module/moduleB.js';Vue.use(Vuex)const state = {username: '牛牛',userState: 0,menu_data: [],isLoadRoute: false,
}
const mutations = {setLoadRoute(state, data) {state.isLoadRoute = data},setUser(state, name) {state.username = name},setUserState(state, data) {state.userState += data},setMenuData(state, data) {state.menu_data = data},}
const getters = {getUserState(state) {let data;if (state.userState == 0) {data = '無效'} else {data = state.userState + '級'}return data;}
}
const modules = {a: moduleA,b: moduleB
}export default new Vuex.Store({state,mutations,getters,modules
})

router/index.js代碼

import VueRouter from "vue-router"
import Index from "@/components/Index";
import axios from "axios";
import store from "@/store/index.js";const routes = [//一級路由{path: '/index',name: 'index',component: Index,redirect: 'index/Main',//路由嵌套children: [{ path: '/index/Main', component: () => import('@/components/Main/index.vue') },]}
]const router = new VueRouter({mode: 'history',routes
})let oRouters = router.options.routes;
const buildRouter = () => {let data = store.state.menu_data;data.forEach(item => {let new_router = {path: item.path,component: () => import('../components/Main/' + item.component + '.vue')}oRouters[0].children.push(new_router);})router.addRoutes(oRouters)
}router.beforeEach((to, from, next) => {//判斷路由是否已經加載過let isLoadRoute = store.state.isLoadRoute;if (!isLoadRoute) {axios.get('/post/menuList').then(res => {store.commit('setMenuData', res.data.menu_data);//動態創建路由buildRouter();//設置已經加載過的標記store.commit("setLoadRoute", true);});}next();
})export default router;

此時點擊菜單就不會重復加載了。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/717763.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/717763.shtml
英文地址,請注明出處:http://en.pswp.cn/news/717763.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2021 年 3 月青少年軟編等考 C 語言一級真題解析

目錄 T1. 字符菱形思路分析 T2. 與圓相關的計算思路分析 T3. 蘋果和蟲子 2思路分析 T4. 奇數求和思路分析 T5. 藥房管理思路分析 T1. 字符菱形 給定一個字符&#xff0c;用它構造一個對角線長 5 5 5 個字符&#xff0c;傾斜放置的菱形。 時間限制&#xff1a;1 s 內存限制&a…

3、云原生安全之falco的部署

文章目錄 1、helm安裝2、拉去鏡像失敗與解決3、安裝faclo4、安裝nfs服務器,配置k8s的持久卷4.1、創建nfs服務器,4.2、部署master節點(nsf服務的客戶端)4.3、pv與pvc4.4、假設pv和pvc的配置文件出錯了5、安裝falcosidekick可視化(建議跳過,直接使用6)6、安裝faclo與falco…

【設計模式 01】單例模式

單例模式&#xff0c;是一種創建型設計模式&#xff0c;他的核心思想是保證一個類只有一個實例&#xff08;即&#xff0c;在整個應用程序中&#xff0c;只存在該類的一個實例對象&#xff0c;而不是創建多個相同類型的對象&#xff09;&#xff0c;并提供一個全局訪問點來訪問…

java012 - Java集合基礎

1、集合基礎 1.1 集合概述 引用數據類型包括&#xff1a;類、接口、數組[] 1.2 ArrayList構造和添加方法 代碼&#xff1a; 空集合對象&#xff1a;[] add() add(int index,E element): 1.3 ArrayList集合常用方法

計算機體系結構安全:對體系結構如何支持安全機制進行調研

一、體系結構支持信任建立和主動防御的技術&#xff1a; 可信3.0 二、體系結構怎么更好的支持信任建立和主動防御 2.1 支持信任建立 一、以手機芯片舉例&#xff0c;用智能手機的芯片作為信任根&#xff0c;確保應用程序和敏感數據受到保護。 二、啟動時驗證操作系統和應用…

Stable Diffusion 模型分享:Henmix_Real(人像、真實、寫真、亞洲面孔)

本文收錄于《AI繪畫從入門到精通》專欄,專欄總目錄:點這里。 文章目錄 模型介紹生成案例案例一案例二案例三案例四案例五案例六案例七案例八下載地址模型介紹 作者述:這個模型試圖改

深入理解算法的空間復雜度

算法一&#xff1a;逐步遞增型 void Loveyou(int n)//n為問題規模 {int i1;while(i<n){i;printf("I love you %d\n",i);}printf("I love you more than %d\n",n);//5 } int main() {Loveyou(3000);return 0; } 無論問題規模怎么變&#xff0c;算法運行…

Springboot教程(五)——單元測試

idea中一般使用JUnit進行單元測試 基本使用 我們可以在idea的test文件夾下的XXXXApplicationTests內進行單元測試&#xff1a; 可以在Test標注的方法上寫測試代碼&#xff1a; SpringBootTest class C0101ApplicationTests {Testfun contextLoads() {println("Hello …

基礎二分學習筆記

模板 : 個人傾向第一種 ; 整數二分 : 最大化查找 : 可行區域在左側 : 查找最后一個<q的數的下標 : int find(int q){// 查找最后一個 < q 的下標 int l 0 , r n 1 ;while(l 1 < r){int mid l r >> 1 ;if(a[mid]<q) l mid ;else r mid ;}return…

django settings.py STATICFILES_FINDERS 設置

STATICFILES_FINDERS 定義查找器后端以確保Django能夠正確地定位和提供靜態文件是很重要的. Django中的STATICFILES FINDERS設置是一個inder后端列表&#xff0c;它知道如何在不同的位置定位靜態文件。 它被Django的靜態文件處理系統用來在開發和部署過程中查找和收集靜態文件…

js json轉換成字符串

js中JSON數據轉換成字符串&#xff0c;可以使用JSON.stringify()方法。 var obj {name: "張三", age: 18, gender: "男"}; var jsonString JSON.stringify(obj); console.log(jsonString); // 輸出 {"name":"張三","age"…

土壤類型數據

國家地球系統科學數據中心

AGM CPLD (AGRV2K )的時鐘(外部時鐘和片上內部振蕩器)

AGM CPLD &#xff08;AGRV2K &#xff09;的時鐘(外部時鐘和片上內部振蕩器) 外部晶振 與 內部振蕩器&#xff1a; mcu 和 cpld 聯合編程時&#xff0c; 整顆芯片需要一顆外部晶振。 &#xff08;芯片有內部振蕩器&#xff0c; 但誤差較大&#xff0c; 校準后 5%以內誤差&…

216. 組合總和 III(力扣LeetCode)

文章目錄 216. 組合總和 III回溯算法 216. 組合總和 III 找出所有相加之和為 n 的 k 個數的組合&#xff0c;且滿足下列條件&#xff1a; 只使用數字1到9每個數字 最多使用一次 返回 所有可能的有效組合的列表 。該列表不能包含相同的組合兩次&#xff0c;組合可以以任何順序…

Electron通過預加載腳本從渲染器訪問Node.js

問題&#xff1a;如何實現輸出Electron的版本號和它的依賴項到你的web頁面上&#xff1f; 答案&#xff1a;在主進程通過Node的全局 process 對象訪問這個信息是微不足道的。 然而&#xff0c;你不能直接在主進程中編輯DOM&#xff0c;因為它無法訪問渲染器 文檔 上下文。 它們…

【軟考】數據庫的三級模式

目錄 一、概念1.1 說明1.2 數據庫系統體系結構圖 二、外模式三、概念模式四、內模式 一、概念 1.1 說明 1.數據的存儲結構各不相同&#xff0c;但體系結構基本上具有相同的特征&#xff0c;采用三級模式和兩級鏡像 2.數據庫系統設計員可以在視圖層、邏輯層和物理層對數據進行抽…

matplotlib散點圖

matplotlib散點圖 假設通過爬蟲你獲取到了北京2016年3, 10月份每天白天的最高氣溫(分別位于列表a, b), 那么此時如何尋找出氣溫和隨時間(天)變化的某種規律? from matplotlib import pyplot as pltx_3 range(1, 32) x_10 range(51, 82)y_3 [11,17,16,11,12,11,12,6,6,7,8…

試手一下CameraX(APP)

書接上回。 首先還是看谷歌的官方文檔&#xff1a; https://developer.android.com/media/camera/camerax?hlzh-cn https://developer.android.com/codelabs/camerax-getting-started?hlzh-cn#1 注&#xff1a;這里大部分內容也來自谷歌文檔。 官方文檔用的是Kotlin&…

常用的字符字符串的讀取方法(C / C++)

一、字符 1、讀取單個字符&#xff1a;直接讀取 //輸入a //讀取 char x; scanf("%c",&x); 2、讀取帶空格的字符 h h h 按格式書寫格式化字符串即可 char a,b,c; scanf("%c %c %c",&a,&b,&c); 3、 處理字符間的換行符 假設要讀取以…

Day14:信息打點-主機架構蜜罐識別WAF識別端口掃描協議識別服務安全

目錄 Web服務器&應用服務器差異性 WAF防火墻&安全防護&識別技術 蜜罐平臺&安全防護&識別技術 思維導圖 章節知識點 Web&#xff1a;語言/CMS/中間件/數據庫/系統/WAF等 系統&#xff1a;操作系統/端口服務/網絡環境/防火墻等 應用&#xff1a;APP對象/…