el-menu无限递归组件完美版本
备注:修复菜单和子菜单高亮问题,及刷新后被点击子菜单依旧打开的bug
效果
代码
index.vue (递归组件)
<template>
<div class="proMain">
<div class="left">
<menu-sun :menuList="menuList"></menu-sun>
</div>
<div class="right">
<router-view></router-view>
</div>
</div>
</template>
<script>
import MenuSun from '../components/menutree.vue'
export default {
components: {
MenuSun
},
data() {
return {
menuList: [
{
name: '一组',
id: '1',
children: [
{
name: '子1',
id: '1-1'
},
{
name: '子2',
id: '1-2'
}
]
},
{
name: '二组',
id: '2',
children: [
{
name: '子1',
id: '2-1'
},
{
name: '子2',
id: '2-2'
},
]
},
{
name: '三组',
id: '3'
},
{
name: '四组',
id: '4'
}
]
}
},
}
</script>
<style lang="less" scoped>
.proMain {
height: 1000px;
display: flex;
.left {
flex: 2;
padding-left: 20px;
background-color: #fff;
border-right: 1px solid #ccc;
}
.right {
flex: 10;
padding-left: 20px;
}
}
</style>
router.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
Vue.use(VueRouter)
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
}
const routes = [
{
path: '/Home',
name: 'Home',
component: Home
},
{
path: '/',
name: 'Header',
component: () => import(/* webpackChunkName: "header" */ '../views/header.vue'),
children: [
{
path: '/model/onesetchildone', // 一组子1路由
name: 'onesetchildone',
component: () => import(/* webpackChunkName: "onesetchildone" */ '../views/model/onesetchildone.vue')
},
{
path: '/model/onesetchildtwo', // 一组子2路由
name: 'onesetchildtwo',
component: () => import(/* webpackChunkName: "onesetchildtwo" */ '../views/model/onesetchildtwo.vue')
},
{
path: '/model/twosetchildone', // 二组子1路由
name: 'twosetchildone',
component: () => import(/* webpackChunkName: "twosetchildone" */ '../views/model/twosetchildone.vue')
},
{
path: '/model/twosetchildtwo', // 二组子2路由
name: 'twosetchildtwo',
component: () => import(/* webpackChunkName: "twosetchildtwo" */ '../views/model/twosetchildtwo.vue')
},
{
path: '/model/threeset', // 三组路由
name: 'threeset',
component: () => import(/* webpackChunkName: "threeset" */ '../views/model/threeset.vue')
},
{
path: '/model/fourset', // 四组路由
name: 'fourset',
component: () => import(/* webpackChunkName: "fourset" */ '../views/model/fourset.vue')
},
]
}
]
const router = new VueRouter({
routes
})
export default router
menutree.vue
<template>
<div>
<el-menu
:default-active="currentActive"
active-text-color="#2b98f7"
:default-openeds="openeds"
unique-opened
>
<template v-for="(item) in menuList">
<el-submenu v-if="item.children&&item.children.length>0" :key="item.id" :index="item.id">
<template slot="title">
<i v-if="item.id == '1'" class="el-icon-s-help"></i> <!-- 有子菜单的父菜单前面的图标 -->
<i v-if="item.id == '2'" class="el-icon-s-custom"></i>
<span class="sizeTit">{{item.name}}</span>
</template>
<menu-sun :menuList="item.children"/>
</el-submenu>
<el-menu-item v-else :key="item.id" :index="item.id" @click="hClick(item)">
<!-- <img v-if="item.id == '3'" :src=" bd3 == false ? require(' ../img/a.svg ') : require('../img/a1.svg') " /> 无子菜单的父菜单前面的图标
<imgv-if="item.id=='4'" :src=" bd4 == false ? require(' ../img/b.svg ') : require('../img/b1.svg') "/> -->
<span :class="item.id == '3'||item.id == '4' ? 'sizeTit' : 'childSty'">{{item.name}}</span> <!-- 为无子菜单的父菜单设置样式 -->
</el-menu-item>
</template>
</el-menu>
</div>
</template>
<script>
import MenuSun from "@/components/menutree.vue";
export default {
name: "MenuSun",
components: {
MenuSun
},
props: {
menuList: {} // 菜单的数据
},
data(){
return {
currentActive: '',
bd3: false,
bd4: false,
pathMap: { // 路由名映射菜单id 都是子菜单和无子菜单
'onesetchildone': '1-1',
'onesetchildtwo': '1-2',
'twosetchildone': '2-1',
'twosetchildtwo': '2-2',
'threeset': '3',
'fourset': '4'
},
}
},
computed: {
ativePath(){
let v = this.$route.name
if(v == 'threeset') {
this.bd3 = true
} else {
this.bd3 = false
}
if(v == 'fourset') {
this.bd4 = true
} else {
this.bd4 = false
}
return v
},
openeds(){ // 设置刷新被点击子菜单的父菜单展开
var name = this.$route.name
var arr1 = ['onesetchildone', 'onesetchildtwo'] // 第一个父菜单下所有子路由名
var arr2 = ['twosetchildone', 'twosetchildtwo'] // 第二个父菜单下所有子路由名
// 浏览器url路由名在哪个数组,该父菜单就会打开
if(arr1.indexOf(name) != -1){
return ['1']
} else if (arr2.indexOf(name) != -1){
return ['2']
} else {
return []
}
}
},
watch:{
ativePath(v){
this.currentActive = this.pathMap[v]
if(v == 'threeset') {
this.bd3 = true
} else {
this.bd3 = false
}
if(v == 'fourset') {
this.bd4 = true
} else {
this.bd4 = false
}
}
},
mounted(){
var name = this.$route.name
this.currentActive = this.pathMap[name]
},
methods: {
hClick(i){ // 点击无子菜单的菜单或子菜单
if(i.id == '1-1'){
this.$router.push({name: 'onesetchildone'})
} else if (i.id == '1-2'){
this.$router.push({name: 'onesetchildtwo'})
} else if (i.id == '2-1'){
this.$router.push({name: 'twosetchildone'})
} else if (i.id == '2-2'){
this.$router.push({name: 'twosetchildtwo'})
} else if (i.id == '3'){
this.$router.push({name: 'threeset'})
} else if (i.id == '4'){
this.$router.push({name: 'fourset'})
}
}
}
};
</script>
<style lang="less" scoped>
.sizeTit {
font-size: 18px;
font-weight: 700;
}
.childSty{
padding-left: 28px; // 子菜单缩进
}
</style>
上面代码18-22行使用的是ui切的svg,下面代码这几行是使用elementui的图标
总结:拿到浏览器url里的当前路由名字,监听,让这个名字和菜单id做映射,成功的就高亮