vue如何從后臺獲取數(shù)據(jù)生成動態(tài)菜單列表
1.數(shù)據(jù)準(zhǔn)備
樹形菜單基本數(shù)據(jù)很簡單,只需要菜單id,菜單名稱,路由地址,圖標(biāo)。下圖中的節(jié)點id和父節(jié)點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é)點,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é)點
<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.不出問題這樣就可以實現(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ù)進行配置
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)的頁面路徑
}]
}
]
})
-----------------------這是分割線(以下是修改前的)-----------------------

將目錄作為子目錄添加到首頁下面,可以顯示出來,但是第二次點擊同一個菜單時,會出現(xiàn)

地址疊加的情況,導(dǎo)致頁面不能顯示。而且先點擊到別的頁面也會出現(xiàn)這種情況

解決辦法:在獲取動態(tài)列表的時候,數(shù)據(jù)里面有url和source,不要去獲取source,內(nèi)層外層循環(huán)都獲取url,然后在router/index 里面,path改為跟獲取的url一樣的內(nèi)容



這個path主要是為了匹配菜單,最終調(diào)取頁面是由component完成的。
剛開始的時候還有一個問題:
就是點擊菜單欄的某一項,會全屏顯示某一個頁面,而不是懶加載的方式,只顯示在中間部分,解決辦法是將獲取的路由放在跟路由下面,作為子組件呈現(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)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue2+Element-ui實現(xiàn)el-table表格自適應(yīng)高度的案例
這篇文章主要介紹了Vue2+Element-ui實現(xiàn)el-table表格自適應(yīng)高度的案例,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-06-06
vue3和vue2掛載實例到全局(自定義消息提示框組件方式)
這篇文章主要介紹了vue3和vue2掛載實例到全局(自定義消息提示框組件方式),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-04-04
vue把頁面轉(zhuǎn)換成圖片導(dǎo)出方式(html2canvas導(dǎo)出不全問題)
這篇文章主要介紹了vue把頁面轉(zhuǎn)換成圖片導(dǎo)出方式(html2canvas導(dǎo)出不全問題),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-10-10

