vue如何從后臺獲取數(shù)據(jù)生成動態(tài)菜單列表
1.數(shù)據(jù)準(zhǔn)備
樹形菜單基本數(shù)據(jù)很簡單,只需要菜單id,菜單名稱,路由地址,圖標(biāo)。下圖中的節(jié)點(diǎn)id和父節(jié)點(diǎn)id是為了后端生成樹形數(shù)據(jù),只負(fù)責(zé)前端的話只需要拿到前面說的四個數(shù)據(jù)就行。
后端將數(shù)據(jù)轉(zhuǎn)成樹形結(jié)構(gòu),傳給前端的數(shù)據(jù)結(jié)構(gòu)如圖
2.選擇組件
我直接用element-ui的el-menu組件,結(jié)構(gòu)是(這是用來注釋的,完整代碼在后面)
<el-menu> <template v-for="(item, key) in menuList">-----前端得到的數(shù)據(jù)存放到menuList數(shù)組 <el-submenu :key="key" v-if="item.children && item.children.length!==0" :index="item.m_url">----父級菜單,判斷有子節(jié)點(diǎn),index是路由跳轉(zhuǎn) <template slot="title">----插槽 <i :class="item.m_icon"></i>-----圖標(biāo) <span>{{ item.m_name }}</span>----菜單名稱 </template> <el-menu-item v-for="(val, index) in item.children" :index="val.m_url" :key="index">----二級菜單 <template slot="title"> <i :class="val.m_icon"></i> <span>{{ val.m_name }}</span> </template> </el-menu-item> </el-submenu> <el-submenu v-else :key="item.m_n_id" :index="item.m_url">沒有子節(jié)點(diǎn) <template slot="title"> <i :class="item.m_icon"></i> <span>{{ item.m_name }}</span> </template> </el-submenu> </template> </el-menu>
3.配置路由
跳轉(zhuǎn)到那個頁面是由寫在router目錄下的index.js的component指定的
import Vue from 'vue' import Router from 'vue-router' Vue.use(Router) export default new Router({ // mode: 'history', routes: [ { path: '/', name: 'home', meta: { key: '1' }, component: () => import("@/views/home"), children: [{ path: '/courseApplication', // 這個路徑必須與后端傳回數(shù)據(jù)的m_url字段相對應(yīng) name: 'courseApplication', meta: { key: '1-1' }, component: () => import('@/views/trainManage/courseApplication') // 要跳轉(zhuǎn)的頁面路徑 }] } ] })
4.不出問題這樣就可以實(shí)現(xiàn)動態(tài)路由了
5.完整代碼
menu.vue
<template> ? <div class="menu"> ? ? ?<el-menu ? ? ? class="el-menu-vertical-demo" ? ? ? @open="handleOpen" ? ? ? @close="handleClose" ? ? ? background-color="rgb(255,255,255)" ? ? ? text-color="rgb(28,41,89)" ? ? ? router = router ? ? ? active-text-color="rgb(28,41,89)"> ? ? ? <template v-for="(item, key) in menuList"> ? ? ? ? <el-submenu :key="key" v-if="item.children && item.children.length!==0" :index="item.m_url"> ? ? ? ? ? <template slot="title"> ? ? ? ? ? ? <i :class="item.m_icon"></i> ? ? ? ? ? ? <span>{{ item.m_name }}</span> ? ? ? ? ? </template> ? ? ? ? ? <el-menu-item v-for="(val, index) in item.children" :index="val.m_url" :key="index"> ? ? ? ? ? ? <template slot="title"> ? ? ? ? ? ? ? <i :class="val.m_icon"></i> ? ? ? ? ? ? ? <span>{{ val.m_name }}</span> ? ? ? ? ? ? </template> ? ? ? ? ? </el-menu-item> ? ? ? ? </el-submenu> ? ? ? ? <el-submenu v-else :key="item.m_n_id" :index="item.m_url"> ? ? ? ? ? <template slot="title"> ? ? ? ? ? ? <i :class="item.m_icon"></i> ? ? ? ? ? ? <span>{{ item.m_name }}</span> ? ? ? ? ? </template> ? ? ? ? </el-submenu> ? ? ? </template> ? ? </el-menu> ? </div> </template>
<script> import { mapActions } from 'vuex'; ? export default { ? ? name: "asideItem", ? ? data(){ ? ? ? return{ ? ? ? ? router: true, ? ? ? ? isCollapse: true, ? ? ? ? label: false, ? ? ? ? menuList: [] ? ? ? } ? ? }, ? ? mounted() { ? ? ? this.getMenu() ? ? }, ? ? methods: { ? ? ? ...mapActions([ ? ? ? ? 'getMenuList' ? ? ? ]), ? ? ? handleOpen(key, keyPath) { ? ? ? ? console.log(key, keyPath); ? ? ? }, ? ? ? handleClose(key, keyPath) { ? ? ? ? console.log(key, keyPath); ? ? ? }, ? ? ? labelChange: function() { ? ? ? ? console.log(this.label); ? ? ? }, ? ? ? getMenu: function() { // 從后臺獲取菜單列表 ? ? ? ? this.getMenuList().then(res => { ? ? ? ? ? if(res.errno === 0) { ? ? ? ? ? ? this.menuList = res.data ? ? ? ? ? } else { ? ? ? ? ? ? this.$message.error(res.data) ? ? ? ? ? } ? ? ? ? }).catch(error => { this.$message.error(error) }) ? ? ? } ? ? } ? }; </script>
<style lang="postcss" scoped> ? .menu { ? ? transition: width 0.28s ease-out; ? ? width: 180px; ? ? background: rgb(255, 255, 255); ? ? height: calc(100vh - 46px); ? ? & .el-menu{ ? ? ? width: 100%; ? ? ? border-right: none; ? ? } ? ? & :hover { ? ? }? ?? ? } ?? </style> <style> .el-menu-item:hover{ ? outline: 0 !important; ? background-color: rgb(232,240,255)!important; } .el-menu-item.is-active { ? background: rgb(210,226,255) !important; } .el-submenu__title:focus, .el-submenu__title:hover{ ? outline: 0 !important; ? background: none !important; } </style>
router 下的index.js根據(jù)具體數(shù)據(jù)進(jìn)行配置
import Vue from 'vue' import Router from 'vue-router' Vue.use(Router) export default new Router({ // mode: 'history', routes: [ { path: '/', name: 'home', meta: { key: '1' }, component: () => import("@/views/home"), children: [{ path: '/courseApplication', // 這個路徑必須與后端傳回數(shù)據(jù)的m_url字段相對應(yīng) name: 'courseApplication', meta: { key: '1-1' }, component: () => import('@/views/trainManage/courseApplication') // 要跳轉(zhuǎn)的頁面路徑 }] } ] })
-----------------------這是分割線(以下是修改前的)-----------------------
將目錄作為子目錄添加到首頁下面,可以顯示出來,但是第二次點(diǎn)擊同一個菜單時,會出現(xiàn)
地址疊加的情況,導(dǎo)致頁面不能顯示。而且先點(diǎn)擊到別的頁面也會出現(xiàn)這種情況
解決辦法:在獲取動態(tài)列表的時候,數(shù)據(jù)里面有url和source,不要去獲取source,內(nèi)層外層循環(huán)都獲取url,然后在router/index 里面,path改為跟獲取的url一樣的內(nèi)容
這個path主要是為了匹配菜單,最終調(diào)取頁面是由component完成的。
剛開始的時候還有一個問題:
就是點(diǎn)擊菜單欄的某一項(xiàng),會全屏顯示某一個頁面,而不是懶加載的方式,只顯示在中間部分,解決辦法是將獲取的路由放在跟路由下面,作為子組件呈現(xiàn)出來
完整代碼
<el-menu :default-active="this.$route.path" class="el-menu-vertical" router :collapse="iscollapse" :collapse-transition="false" :active-text-color="variables.menuActiveText" :background-color="variables.menuBg" :text-color="variables.menuText" > <fragment> <template v-for="item in menuList"> <fragment v-if="item != null" :key="item.url"> <el-submenu v-if="item.childMenuInfoTreeSet && item.childMenuInfoTreeSet.length > 0" :key="item.url" :index="item.url.toString()"> <template slot="title"> <i :class="item.iconcls.toString()" class="iconSize" /> <span slot="title">{{ item.menuName }}</span> </template> <el-menu-item v-for="val in item.childMenuInfoTreeSet" :key="val.title" :index="val.url.toString()"> <i :class="val.iconcls.toString()" class="iconSize" /> <span slot="title">{{ val.menuName }}</span> </el-menu-item> </el-submenu> <el-menu-item v-else :key="item.url" :index="item.url.toString()"> <i :class="item.iconcls" class="iconSize" /> <span slot="title">{{ item.menuName }}</span> </el-menu-item> </fragment> </template> </fragment> </el-menu>
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue+elementui 表格分頁限制最大頁碼數(shù)的操作代碼
這篇文章主要介紹了vue+elementui 表格分頁限制最大頁碼數(shù)的操作代碼,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2024-08-08vue封裝全局彈窗警告組件this.$message.success問題
這篇文章主要介紹了vue封裝全局彈窗警告組件this.$message.success問題,具有很的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-09-09vue element-ui v-for循環(huán)el-upload上傳圖片 動態(tài)添加、刪除方式
這篇文章主要介紹了vue element-ui v-for循環(huán)el-upload上傳圖片 動態(tài)添加、刪除方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-10-10關(guān)于IDEA中的.VUE文件報錯 Export declarations are not supported by cu
這篇文章主要介紹了關(guān)于IDEA中的.VUE文件報錯 Export declarations are not supported by current JavaScript version的問題,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-10-10Vue通過URL傳參如何控制全局console.log的開關(guān)詳解
這篇文章主要給大家介紹了關(guān)于Vue根據(jù)URL傳參如何控制全局console.log開關(guān)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。2017-12-12如何用vue-cli3腳手架搭建一個基于ts的基礎(chǔ)腳手架的方法
這篇文章主要介紹了如何用vue-cli3腳手架搭建一個基于ts的基礎(chǔ)腳手架的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12關(guān)于vue的element-ui web端引入高德地圖并獲取經(jīng)緯度
這篇文章主要介紹了關(guān)于vue的element-ui web端引入高德地圖并獲取經(jīng)緯度,高德地圖首先要去申請key和密鑰,文中提供了部分實(shí)現(xiàn)代碼和解決思路,感興趣的朋友可以學(xué)習(xí)一下2023-04-04