因为elementUI的菜单组件不能实现祖级以及父级的点中效果,只能点到最后一级别,所以自己写了一个简UI的DEMO【代码可以直接使用】
1、异步组件实现递归
2、展开和收起效果和element一致
3、对比饿了吗,此DEMO每一级别均可点击,且可以自动滚动到菜单的位置
<style scoped>
aside {
width: 200px;
height: 300px;
overflow: auto;
}
</style>
<template>
<div class="home">
<aside>
<tab-list
v-bind:active="active"
v-bind:list="data"
v-on:tabClick="tabClickHandler"
/>
</aside>
</div>
</template>
<script>
import TabList from '@/components/TabList'
export default {
name: 'Home',
data () {
return {
active: '7',
data: [
{
id: '1',
name: '一级',
children: [
{
id: '1-1',
name: '二级',
children: [
{
id: '1-1-1',
name: '三级',
children: []
}
]
},
{
id: '1-2',
name: '二级',
children: []
}
]
},
{
id: '2',
name: '一级2',
children: [
{
id: '2-2',
name: '二级2',
children: [
{
id: '2-2-2',
name: '三级2',
children: []
}
]
}
]
},
{
id: '4',
name: '一级',
children: []
},
{
id: '5',
name: '一级',
children: []
},
{
id: '6',
name: '一级',
children: []
},
{
id: '7',
name: '一级',
children: []
},
{
id: '8',
name: '一级',
children: []
},
{
id: '9',
name: '一级',
children: []
},
{
id: '10',
name: '一级',
children: []
}
]
}
},
methods: {
tabClickHandler (item) {
this.active = item.id
}
},
components: {
[TabList.name]: TabList
}
}
</script>
<style scoped>
ul {
margin: 0;
padding: 0 0 0 20px;
}
</style>
<template>
<ul class="tab-list">
<tab-item
v-for="item in list"
v-bind:item="item"
v-bind:active="active"
v-bind:key="item.id"
v-on:tabClick="tabClick"
/>
</ul>
</template>
<script>
import TabItem from './TabItem.vue'
export default {
name: 'TabList',
props: {
list: {
type: Array,
default: []
},
active: {
type: String,
default: ''
}
},
methods: {
tabClick (item) {
this.$emit('tabClick', item)
}
},
components: {
[TabItem.name]: TabItem
}
}
</script>
<style scoped>
li {
list-style: none;
}
section {
line-height: 50px;
cursor: pointer;
}
section:hover {
background-color: #409eff;
}
section.active {
color: #409eff;
background-color: inherit;
}
.tab-list {
max-height: 0;
overflow: hidden;
transition: max-height 0.25s;
}
.tab-list.open {
max-height: 999px;
}
</style>
<template>
<li class="tab-item">
<section
v-bind:class="{active: active === item.id}"
v-on:click="tabItemClick(item)"
>
<span>{{ item.name }}</span>
<i v-if="item.children.length">
{{ toggle ? '折叠' : '展开' }}
</i>
</section>
<tab-list
v-if="item.children.length"
v-bind:class="{ open: toggle }"
v-bind:list="item.children"
v-bind:active="active"
v-on:tabClick="tabClick"
/>
</li>
</template>
<script>
function findChildren (list, id) {
for (let i = 0; i < list.length; i++) {
let item = list[i]
if (item.id === id) {
return item
} else {
let result = findChildren(item.children, id)
if (result) {
return result
}
}
}
}
export default {
name: 'TabItem',
props: {
item: {
type: Object,
default: {
id: '',
name: '',
children: []
}
},
active: {
type: String,
default: ''
}
},
data () {
return {
toggle: false
}
},
created () {
this.toggle = !!findChildren(this.item.children, this.active)
},
mounted () {
if (this.item.id === this.active) {
this.$el.scrollIntoView({ behavior: 'smooth', block: 'center' })
}
},
methods: {
tabItemClick (item) {
this.toggle = !this.toggle
this.tabClick(item)
},
tabClick (item) {
this.$emit('tabClick', item)
}
},
components: {
TabList: () => import('./TabList.vue')
}
}
</script>