本文介绍了Vue实现左右菜单联动实现代码吗,分享给大家,也给自己留个笔记,具体如下:
Github
源码传送门: 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 [] } }, }
在这个业务场景中,我们的实现方式是根据右边菜单滚动的高度来计算左边菜单的位置,当然左边菜单也可以通过点击来确定右边菜单需要滚动多高的距离,那么我们如何获得该容器滚动的距离呢? 之前一直在使用better-scroll,通过阅读文档,我们知道它有有 scroll
事件,我们可以通过监听这个事件来获取滚动的 pos
if (this.listenScroll) { let me = this this.scroll.on('scroll', (pos) => { me.$emit('scroll', pos) }) }
所以我们在右边菜单的 scroll
组件上监听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 "htmlcode">@click="selectLeft(index, $event)"这里加上
$event
是为了区分原生点击事件还是[better-scroll]((https://ustbhuangyi.github.io/better-scroll/doc/zh-hans/#better-scroll 是什么)派发的事件selectLeft (index, event) { if (!event._constructed) { return } let rightItem = this.$refs.rightItem let el = rightItem[index] this.$refs.rightMenu.scrollToElement(el, 300) },到这里我们就基本上完成了这些需求了
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]