vue.js - vue2如何实现多级嵌套菜单的点击效果(点击后当前元素和兄弟元素均需要添加一个class)
本文介绍了vue.js - vue2如何实现多级嵌套菜单的点击效果(点击后当前元素和兄弟元素均需要添加一个class)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
问 题
效果:
点击后:
一个点击后展开列表的多级菜单效果,第一级是两个li,点击的时候,点击的li加上open的class,(隐藏自己并展现子级菜单),其他的li加上hide的class(隐藏自己),back是在子级菜单中,点击后回到上个列表,点击子级菜单后和之前效果一样。
目前: 有一个currentIndex(判断当前索引)和currentLevel(判断当前层级),然后用v-for的index和数组里的level来赋值,
open: index === currentIndex && item.level === currentLevel
hide: item.level === currentLevel && index !== currentIndex
<li v-for="(item,index) in items" class="has-sub" :class="{'open': index === currentIndex && item.level === currentLevel, 'hide': item.level === currentLevel && index !== currentIndex }" >
<a @click="expandList(item, index)" href="#">{{item.title}}<span v-if="item.children" class="i caret"></span></a>
<ul v-if="item.children" class="dropdown-menu level-2">
<li class="visible-xs"><a @click="backUp" href="javascript:;"><i class="i"></i>Back</a></li>
<li class="has-sub" v-for="(child, i ) of item.children" :class="{'open': i === currentIndex && child.level === currentLevel, 'hide': child.level === currentLevel && i !== currentIndex}">
<i v-if="child.children" @click.prevent="expandList(child,i)" class="i"></i><span>{{child.title}}</span>
<ul class="dropdown-menu level-3">
......
</ul>
</li>
</ul>
</li>
items: [
{
title:"Trade fair ",
level: 1,
children:[
{
title: 'Exhibition profile',
level: 2,
children:[
]
},
{
title: 'At the fair',
level: 2
}
]
},
{
......
}
],
currentLevel: '',
currentIndex: '',
hideFalg: false,
backFlag: false
expandList: function (item,index) {
this.currentIndex = index
this.currentLevel = item.level
}
一级菜单下打开二级菜单没什么问题,但是要从二级菜单打开三级菜单的时候,上一级菜单绑定class的条件就不成立了,子级菜单要打开的前提是父级那两个open和hide状态不变
(这是在改的一个项目,不是从头写的。不知道有什么思路可以还原原本用操作dom方式写的效果,如果这个思路不可行的话有没有什么办法改造一下来达到这个效果呢?搜了一下多级菜单有找到element的Tree 树形控件,但是这个不是我需要的效果额 )
解决方案
<ul class="nav navbar-nav level-1">
<li v-for="(item,index) in items" :key="item" class="has-sub" :class="{'open': index === cur[item.level].currentIndex && item.level === cur[item.level].currentLevel && cur[item.level].backFlag == false, 'hide': item.level === cur[item.level].currentLevel && index !== cur[item.level].currentIndex && cur[item.level].backFlag == false }" >
<a @click="expandList(item, index)" href="#">{{item.title}}<span v-if="item.children" class="i caret"></span></a>
<ul v-if="item.children" class="dropdown-menu level-2">
<li class="visible-xs" :class="{hide: cur[item.level].hideBack}"><a @click="backUp(item)" href="javascript:;"><i class="i"></i>Back</a></li>
<li class="has-sub" v-for="(item2, index) in item.children" :key="item2" :class="{'open': index === cur[item2.level].currentIndex && item2.level === cur[item2.level].currentLevel && cur[item2.level].backFlag == false, 'hide': item2.level === cur[item2.level].currentLevel && index !== cur[item2.level].currentIndex && cur[item2.level].backFlag == false}">
<i v-if="item2.children" @click="expandList(item2,index)" class="i"></i><span>{{item2.title}}</span>
<ul class="dropdown-menu level-3">
<li class="visible-xs" :class="{hide: cur[item2.level].hideBack}"><a @click="backUp(item2)" href="javascript:;"><i class="i"></i>Back</a></li>
<li class="has-sub" v-for="(item3, index) in item2.children" :key="item3" :class="{'open': index === cur[item3.level].currentIndex && item3.level === cur[item3.level].currentLevel && cur[item3.level].backFlag == false, 'hide': item3.level === cur[item3.level].currentLevel && index !== cur[item3.level].currentIndex && cur[item3.level].backFlag == false }">
<a href="#">{{item3.title}}</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
export default {
data () {
return {
slideFlag : false,
items: [ ],
hideFalg: false,
cur: [
{
currentIndex: '',
currentLevel: '',
backFlag: false,
hideBack: false
},
{
currentIndex: '',
currentLevel: '',
backFlag: false,
hideBack: false
},
{
currentIndex: '',
currentLevel: '',
backFlag: false,
hideBack: false
}
]
}
},
mounted() {
this.$nextTick(function() {
this.axios.get('./static/api/data.json').then( response => {
let res = response.data
if(res.status == 0) {
this.items = res.result.HeaderList
}
})
})
},
methods: {
ToggleSlideBar: function () {
this.slideFlag = !this.slideFlag
this.$emit('message', this.slideFlag)
},
expandList: function (item,index) {
this.cur[item.level].currentIndex = index
this.cur[item.level].currentLevel = item.level
if(item.children){
this.cur[item.level].backFlag = false
if(item.level > 0) {
this.cur[item.level - 1].hideBack = true
}
}
},
backUp: function (item) {
this.cur[item.level].backFlag = true;
if(item.level > 0){
this.cur[item.level - 1].hideBack = false;
}
}
}
}
虽然是个笨方法,不过貌似实现没问题了。。。 就是在想把每层bind的样式提取出来直接给返回值不要写那么长的时候,发现套用官网的方法没用,不能传值进去,像这样 :class="classObject(item,index)"
。
这篇关于vue.js - vue2如何实现多级嵌套菜单的点击效果(点击后当前元素和兄弟元素均需要添加一个class)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文