vue遞歸組件實現(xiàn)elementUI多級菜單
本文實例為大家分享了vue遞歸組件實現(xiàn)elementUI多級菜單的具體代碼,供大家參考,具體內(nèi)容如下
先看效果:
一、子組件
<template> ? ? <div class="myDiv"> ? ? ? ? <!-- 這里的listAll用于接收父組件傳遞進(jìn)來的菜單列表 --> ? ? ? ? <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> ? ? ? ? ? ? ? ? <!-- 再次調(diào)用自身組件,傳入子集,進(jìn)行循環(huán)遞歸調(diào)用 --> ? ? ? ? ? ? ? ? <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: { ? ? ? ? //設(shè)置路由跳轉(zhuǎn) ? ? ? ? handleSelect(path, name, selfIndex) { ? ? ? ? ? ? this.$router.push( ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? path: "/" + path, ? ? ? ? ? ? ? ? ? ? query: { ? ? ? ? ? ? ? ? ? ? ? ? r_n: name, ? ? ? ? ? ? ? ? ? ? ? ? index: selfIndex ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ) ? ? ? ? }, ? ? ? ? ? ? }, } </script>
二、菜單數(shù)據(jù)準(zhǔn)備
菜單中包含索引,圖片,名稱,跳轉(zhuǎn)路徑,這里我給出一部分?jǐn)?shù)據(jù),路由直接用數(shù)字了,你們最好定義為組件的英文名稱,這樣方便維護(hù)。
export function menuJson() { ? var data = [{ ? ? title: "元數(shù)據(jù)管理", ? ? img: "../../../static/img/manager.png", ? ? index: '1', ? ? child: [ ? ? ? { ? ? ? ? "title": "元數(shù)據(jù)信息描述管理", "path": "main/02/005", "img": "../../../static/img/manager.png", "index": "1-2", "child": [] ? ? ? }, ? ? ? { ? ? ? ? "title": "元數(shù)據(jù)分組定義管理", "path": "main/02/007", "img": "../../../static/img/manager.png", "index": "1-3", "child": [] ? ? ? }, ? ? ? { ? ? ? ? "title": "元數(shù)據(jù)信息管理", "path": "main/02", "img": "../../../static/img/manager.png", "index": "1-1", "child": [ ? ? ? ? ? { "title": "采集元數(shù)據(jù)", "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": "元數(shù)據(jù)統(tǒng)計分析管理", "path": "main/01", "index": "1-4", "img": "../../../static/img/manager.png", "child": [ ? ? ? ? ? { "title": "元數(shù)據(jù)變更管理", "path": "main/01/001", "index": "1-4-1", "img": "../../../static/img/blood.png", "child": [] }, ? ? ? ? ? { "title": "數(shù)據(jù)地圖", "path": "main/01/002", "index": "1-4-2", "img": "../../../static/img/blood.png", "child": [] }, ? ? ? ? ? { ? ? ? ? ? ? "title": "元數(shù)據(jù)分析", "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: "規(guī)則管理", ? ? img: "../../../static/img/manager.png", ? ? index: '2', ? ? child: [ ? ? ? { "title": "數(shù)據(jù)接口定義管理", "index": "2-1", "path": "main/03/001", "img": "../../../static/img/source.png", "child": [] }, ? ? ? { "title": "數(shù)據(jù)轉(zhuǎn)換規(guī)則管理", "index": "2-2", "path": "main/03/004", "img": "../../../static/img/modify.png", "child": [] }, ? ? ] ? } ? ] ? return data }
三、父組件調(diào)用
<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"> ? ? ? ? ? ? ? ? ? ? //調(diào)用子組件 ? ? ? ? ? ? ? ? ? ? <Menu :listAll="listAll"></Menu> ? ? ? ? ? ? ? ? </el-menu> ? ? ? ? ? ? </el-col> ? ? ? ? </div> ? ? </div> </template> ? <script> import Menu from './menu' import { menuJson } from '../../assets/common/http' //調(diào)用js文件中的菜單數(shù)據(jù) export default { ? ? name: "Menus", ? ? mixins: [mixin], ? ? components: { Menu }, ? ? data() { ? ? ? ? return { ? ? ? ? ? ? scrollHeight: 400, ? ? ? ? ? ? listAll: [], ? ? ? ? ? ? activeIndex: "-1", ? ? ? ? ? ? defalutIndex: [] ? ? ? ? } ? ? }, ? ? created() { ? ? ? ? //設(shè)置點擊菜單的索引,可以使得刷新后菜單仍保持原來查看的頁面 ? ? ? ? this.activeIndex = String(this.$route.query.index); ? ? ? ? this.listAll = menuJson() //通過調(diào)用函數(shù)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>
補充(面包屑的展示):
有菜單,肯定需要面包屑的展示,例如
這里我用的方法是,根據(jù)當(dāng)前頁面名稱,從樹形菜單數(shù)據(jù)中查找它的所有父級來實現(xiàn)面包屑導(dǎo)航欄的展示。
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: { ?//獲取樹形數(shù)據(jù)的某個元素的所有父節(jié)點 ? ? ? ? getTreePath(tree, func, path) { ? ? ? ? ? ? if (!tree) return [] ? ? ? ? ? ? for (const data of tree) { ? ? ? ? ? ? ? ? // 這里按照你的需求來存放最后返回的內(nèi)容吧 ? ? ? ? ? ? ? ? //這里的title是我的菜單數(shù)據(jù)里面的名稱字段,你可以改成你的 ? ? ? ? ? ? ? ? path.push(data.title) ? ? ? ? ? ? ? ? if (func(data)) return path ? ? ? ? ? ? ? ? if (data.child) { ? ? ? ? ? ? ? ? ? ? //獲取到子數(shù)據(jù),遞歸調(diào)用 ? ? ? ? ? ? ? ? ? ? const findChildren = this.getTreePath(data.child, func, path) ? ? ? ? ? ? ? ? ? ? if (findChildren.length) return findChildren ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? path.pop() ? ? ? ? ? ? } ? ? ? ? ? ? return [] ? ? ? ? }, ? ? ? ? // 獲取面包屑 ? ? ? ? getNavList() { ? ? ? ? ? ? var name = this.$route.query.r_n //先獲取當(dāng)前路由名稱 ? ? ? ? ? ? var tree = menuJson() ?//獲取菜單數(shù)據(jù),menuJson這個函數(shù)上面用了,返回的事菜單數(shù)據(jù) ? ? ? ? ? ? this.path = [] //path用于存放所有父級,調(diào)用前需要清空 ? ? ? ? ? ? //data => data.title === name查找數(shù)據(jù)中的title是否和當(dāng)前路由名稱相等 ? ? ? ? ? ? this.getTreePath(tree, data => data.title === name, this.path) ? ? ? ? ? ? this.listMenu = this.path ?//找到之后賦值給面包屑路由數(shù)組 ? ? ? ? ? ? console.log(this.listMenu) ? ? ? ? } ? ? }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
vue前端測試開發(fā)watch監(jiān)聽data的數(shù)據(jù)變化
這篇文章主要為大家介紹了vue測試開發(fā)watch監(jiān)聽data的數(shù)據(jù)變化,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05vue動態(tài)綁定多個類名方法詳解(:class動態(tài)綁定多個類名)
vue中可以通過:class=""這樣來根據(jù)一定的條件來動態(tài)添加class,但是有時候需要判斷的條件比較多,需要動態(tài)添加的class也比較多,下面這篇文章主要給大家介紹了關(guān)于vue動態(tài)綁定多個類名(:class動態(tài)綁定多個類名)的相關(guān)資料,需要的朋友可以參考下2022-11-11Vue 實現(xiàn)v-for循環(huán)的時候更改 class的樣式名稱
這篇文章主要介紹了Vue 實現(xiàn)v-for循環(huán)的時候更改 class的樣式名稱,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07Message組件實現(xiàn)發(fā)財U(kuò)I?示例詳解
這篇文章主要為大家介紹了Message組件實現(xiàn)發(fā)財U(kuò)I的手寫示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08