今天在做美团的二级菜单的时候, 使用了一种很原始的方式, 在 li 下直接添加一个 div , 当鼠标 hover 上去的时候, 显示出来. 这样的 li 在美团这个项目中, 足足16个, 就会多出16个 div.
<ul>
<li>
<a>123456</a>
<div>二级菜单</div>
</li>
</ul>
但是我使用的是 vue, 使用这种方式真的很 low , 这也是因为我对 vue 的使用不够灵活, 对 vue 的理解不够深刻.
vue 下, 一个很简单的二级菜单做法是用鼠标事件, 需要给 li 和 div 分绑定鼠标移入移出事件, 这是麻烦之处, 但是这么做只需要使用一个 div 就可以搞定.
<template>
<div class="wrapper clearfix">
<ul>
<li v-for="(i, index) in list" :key="index" class="list-item" @mouseenter="liEnter(i)" @mouseleave="liLeave">
<span>{{i.title}}</span>
</li>
</ul>
<div class="second" v-if="this.curItem" @mouseenter="listEnter" @mouseleave="listLeave">
<ul>
<li v-for="(i, index) in curItem.children" :key="index" class="list-item-s">
<span v-for="(item, index) in i.children" :key="index">{{item}}</span>
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
name: 'App',
data () {
return {
curItem: null,
list: [
{
title: '美食',
children: [
{
title: '美食',
children: ['火锅', '串串', '蛋饼', '水煮鱼']
}
]
},
{
title: '旅行酒店',
children: [
{
title: '酒店',
children: ['经典', '三星', '四星', '五星']
}
]
},
{
title: '榛果民宿',
children: [
{
title: '热门城市',
children: ['北京', '上海', '天津', '杭州']
}
]
}
]
}
},
methods: {
liEnter (item) {
setTimeout(() => {
this.curItem = item
}, 201)
},
liLeave () {
this.timer = setTimeout(() => {
this.curItem = null
}, 200)
},
listEnter () {
clearTimeout(this.timer)
},
listLeave () {
this.curItem = null
}
}
}
</script>
<style lang="scss">
.wrapper {
width: 300px;
border: 1px solid #ccc;
position: relative;
padding-bottom: 400px;
ul {
float: left;
.list-item {
width: 100px;
text-align: center;
background: #31bbac;
}
}
.second {
border: 1px solid #000;
width: 150px;
float: left;
}
}
</style>
这里绑定事件需要使用到定时器, 而且我设置了一个比较极端的延迟时间, 只要在鼠标移动需要的时间之内, enter 需要比 leave 慢一点点就好了. 至于为什么就不多解释了.