Vue实现左右菜单联动实现代码
本文介绍了vue实现左右菜单联动实现代码吗,分享给大家,也给自己留个笔记,具体如下:
源码传送门: rain120/vue-study
之前在外卖软件上看到这个左右联动的效果,觉得很有意思,所以就尝试使用 vue
来实现,将这个联动抽离成为一个单独的组件,废话少说,先来一张效果图。
这个组件分为两个部分,1、左菜单;2、右菜单。 左菜单的 dom
结构
<scroll class="left-menu" :data="leftmenu" ref="leftmenu"> <div class="left-menu-container"> <ul> <li class="left-item" ref="leftitem" :class="{'current': currentindex === index}" @click="selectleft(index, $event)" v-for="(item, index) in leftmenu" :key="index"> <p class="text">{{item}}</p> </li> </ul> </div> </scroll>
右菜单的 dom
结构
<scroll class="right-menu" :data="rightmenu" ref="rightmenu" @scroll="scrollheight" :listenscroll="true" :probetype="3"> <div class="right-menu-container"> <ul> <li class="right-item" ref="rightitem" v-for="(items, i) in rightmenu" :key="i"> <div class="data-wrapper"> <div class="title">{{items.title}}</div> <div class="data" v-for="(item, j) in items.data" :key="j">{{item}}</div> </div> </li> </ul> </div> </scroll>
这里是为了做 demo
,所以在数据上只是单纯捏造。
当然因为这是个子组件,我们将通过父组件传递 props
,所以定义 props
props: { leftmenu: { required: true, type: array, default () { return [] } }, rightmenu: { required: true, type: array, default () { return [] } }, }
在这个业务场景中,我们的实现方式是根据右边菜单滚动的高度来计算左边菜单的位置,当然左边菜单也可以通过点击来确定右边菜单需要滚动多高的距离,那么我们如何获得该容器滚动的距离呢? 之前一直在使用,通过阅读文档,我们知道它有有 scroll
事件,我们可以通过监听这个事件来获取滚动的 pos
if (this.listenscroll) { let me = this this.scroll.on('scroll', (pos) => { me.$emit('scroll', pos) }) }
所以我们在右边菜单的 scroll
组件上监听事件
@scroll="scrollheight"
method
scrollheight (pos) { console.log(pos); this.scrolly = math.abs(math.round(pos.y)) },
我们将监听得到的pos打出来看看
我们可以看到控制台打出了当前滚动的pos信息,因为在移动端开发时,坐标轴和我们数学中的坐标轴相反,所以上滑时y轴的值是负数
所以我们要得到每一块 li
的高度,我们可以通过拿到他们的 dom
_calculateheight() { let lis = this.$refs.rightitem; let height = 0 this.rightheight.push(height) array.prototype.slice.call(lis).foreach(li => { height += li.clientheight this.rightheight.push(height) }) console.log(this.rightheight) }
我们在 created
这个 hook
之后调用这个计算高度的函数
_calculateheight() { let lis = this.$refs.rightitem; let height = 0 this.rightheight.push(height) array.prototype.slice.call(lis).foreach(li => { height += li.clientheight this.rightheight.push(height) }) console.log(this.rightheight) }
当用户在滚动时,我们需要计算当前滚动距离实在那个区间内,并拿到他的 index
computed: { currentindex () { const { scrolly, rightheight } = this const index = rightheight.findindex((height, index) => { return scrolly >= rightheight[index] && scrolly < rightheight[index + 1] }) return index > 0 ? index : 0 } }
所以当前应该是左边菜单 index = 1
的菜单项 active
以上是左边菜单根据右边菜单的滑动联动的实现,用户也可以通过点击左边菜单来实现右边菜单的联动,此时,我们给菜单项加上 click事件
@click="selectleft(index, $event)"
这里加上 $event
是为了区分原生点击事件还是[better-scroll](( 是什么)派发的事件
selectleft (index, event) { if (!event._constructed) { return } let rightitem = this.$refs.rightitem let el = rightitem[index] this.$refs.rightmenu.scrolltoelement(el, 300) },
到这里我们就基本上完成了这些需求了
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: HTML的select控件美化