vue遞歸組件實現elementUI多級菜單
本文實例為大傢分享瞭vue遞歸組件實現elementUI多級菜單的具體代碼,供大傢參考,具體內容如下
先看效果:
一、子組件
<template> <div class="myDiv"> <!-- 這裡的listAll用於接收父組件傳遞進來的菜單列表 --> <template v-for="(item,i) in listAll"> <!-- 有child就顯示child的下拉型菜單,有小箭頭 --> <el-submenu :index="item.index" :key="i" v-if="item.child.length!=0"> <template slot="title"> <img :src="item.img" alt=""> <span>{{item.title}}</span> </template> <!-- 再次調用自身組件,傳入子集,進行循環遞歸調用 --> <Menu :listAll="item.child"></Menu> </el-submenu> <!-- 沒有child,就顯示單個目錄,沒有小箭頭 --> <el-menu-item :index="item.index" v-else :key="i" @click="handleSelect(item.path,item.title,item.index)"> <span slot="title"><img :src="item.img" alt="">{{item.title}}</span> </el-menu-item> </template> </div> </template> <script> export default { name: 'Menu', components: {}, props: ['listAll'], data() { return { realList: this.listAll, } }, methods: { //設置路由跳轉 handleSelect(path, name, selfIndex) { this.$router.push( { path: "/" + path, query: { r_n: name, index: selfIndex } } ) }, }, } </script>
二、菜單數據準備
菜單中包含索引,圖片,名稱,跳轉路徑,這裡我給出一部分數據,路由直接用數字瞭,你們最好定義為組件的英文名稱,這樣方便維護。
export function menuJson() { var data = [{ title: "元數據管理", img: "../../../static/img/manager.png", index: '1', child: [ { "title": "元數據信息描述管理", "path": "main/02/005", "img": "../../../static/img/manager.png", "index": "1-2", "child": [] }, { "title": "元數據分組定義管理", "path": "main/02/007", "img": "../../../static/img/manager.png", "index": "1-3", "child": [] }, { "title": "元數據信息管理", "path": "main/02", "img": "../../../static/img/manager.png", "index": "1-1", "child": [ { "title": "采集元數據", "path": "main/02/001", "index": "1-1-1", "img": "../../../static/img/blood.png", "child": [] }, { "title": "元模型", "path": "main/02/004", "index": "1-2-1", "img": "../../../static/img/blood.png", "child": [] }, ] }, { "title": "元數據統計分析管理", "path": "main/01", "index": "1-4", "img": "../../../static/img/manager.png", "child": [ { "title": "元數據變更管理", "path": "main/01/001", "index": "1-4-1", "img": "../../../static/img/blood.png", "child": [] }, { "title": "數據地圖", "path": "main/01/002", "index": "1-4-2", "img": "../../../static/img/blood.png", "child": [] }, { "title": "元數據分析", "path": "main/01/003", "index": "1-4-3", "img": "../../../static/img/yuanfenxi.png", "child": [ { "title": "血緣分析", "path": "main/01/003/0001", "index": "1-4-3-1", "img": "../../../static/img/blood.png", "child": [] }, { "title": "屬性差異分析", "path": "main/01/003/0003", "index": "1-4-3-2", "img": "../../../static/img/chayi.png", "child": [] }, { "title": "影響分析", "path": "main/01/003/0004", "index": "1-4-3-3", "img": "../../../static/img/impact.png", "child": [] }, ] }, ] }, ] }, { title: "規則管理", img: "../../../static/img/manager.png", index: '2', child: [ { "title": "數據接口定義管理", "index": "2-1", "path": "main/03/001", "img": "../../../static/img/source.png", "child": [] }, { "title": "數據轉換規則管理", "index": "2-2", "path": "main/03/004", "img": "../../../static/img/modify.png", "child": [] }, ] } ] return data }
三、父組件調用
<template> <div class="content menu"> <div class="menu_com" :style="{height:scrollHeight+'px'}"> <el-col :span="24"> <el-menu :default-active="activeIndex" class="el-menu-vertical-demo" :default-openeds="defalutIndex" background-color="#003289" text-color="#fff" active-text-color="#ffd04b"> //調用子組件 <Menu :listAll="listAll"></Menu> </el-menu> </el-col> </div> </div> </template> <script> import Menu from './menu' import { menuJson } from '../../assets/common/http' //調用js文件中的菜單數據 export default { name: "Menus", mixins: [mixin], components: { Menu }, data() { return { scrollHeight: 400, listAll: [], activeIndex: "-1", defalutIndex: [] } }, created() { //設置點擊菜單的索引,可以使得刷新後菜單仍保持原來查看的頁面 this.activeIndex = String(this.$route.query.index); this.listAll = menuJson() //通過調用函數menuJson,獲取菜單 }, watch: { $route(to, from) { this.activeIndex = this.$route.query.index; } }, } </script> <style scoped lang="less"> @color: #003289; .menu { background: @color; > div { width: 100%; padding-top: 20px; // height: 100%; color: #ffffff; overflow-y: scroll; overflow-x: hidden; &::-webkit-scrollbar { display: none; } h1 { font-size: 20px; text-align: center; padding: 15px 0 25px 0; } } } .el-menu-demo { position: absolute; height: 58px !important; left: 25%; top: 0%; } </style>
補充(面包屑的展示):
有菜單,肯定需要面包屑的展示,例如
這裡我用的方法是,根據當前頁面名稱,從樹形菜單數據中查找它的所有父級來實現面包屑導航欄的展示。
html:
<el-breadcrumb separator-class="el-icon-arrow-right"> <el-breadcrumb-item v-for="(item,index) in listMenu" :key="index">{{item}}</el-breadcrumb-item> </el-breadcrumb>
methods:
methods: { //獲取樹形數據的某個元素的所有父節點 getTreePath(tree, func, path) { if (!tree) return [] for (const data of tree) { // 這裡按照你的需求來存放最後返回的內容吧 //這裡的title是我的菜單數據裡面的名稱字段,你可以改成你的 path.push(data.title) if (func(data)) return path if (data.child) { //獲取到子數據,遞歸調用 const findChildren = this.getTreePath(data.child, func, path) if (findChildren.length) return findChildren } path.pop() } return [] }, // 獲取面包屑 getNavList() { var name = this.$route.query.r_n //先獲取當前路由名稱 var tree = menuJson() //獲取菜單數據,menuJson這個函數上面用瞭,返回的事菜單數據 this.path = [] //path用於存放所有父級,調用前需要清空 //data => data.title === name查找數據中的title是否和當前路由名稱相等 this.getTreePath(tree, data => data.title === name, this.path) this.listMenu = this.path //找到之後賦值給面包屑路由數組 console.log(this.listMenu) } }
以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。
推薦閱讀:
- vue遞歸實現自定義tree組件
- vue.js使用Element-ui中實現導航菜單
- vue router-view的嵌套顯示實現
- Nuxt3 佈局layouts和NuxtLayout的使用詳解
- 聊聊element-ui 側邊欄的router問題