未加星标

Vue实现左右菜单联动实现

字体大小 | |
[前端(javascript) 所属分类 前端(javascript) | 发布者 店小二04 | 时间 2018 | 作者 红领巾 ] 0人收藏点击收藏

title: Vue实现左右菜单联动实现 date: 2018-08-11 16:31:34 tags:

Vue 左右联动 top: 100 copyright: true

知乎

个人博客

Github

源码传送门: Rain120/vue-study

之前在外卖软件上看到这个左右联动的效果,觉得很有意思,所以就尝试使用 Vue 来实现,将这个联动抽离成为一个单独的组件,废话少说,先来一张效果图。


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 [] } }, } 复制代码
Vue实现左右菜单联动实现

在这个业务场景中,我们的实现方式是根据右边菜单滚动的高度来计算左边菜单的位置,当然左边菜单也可以通过点击来确定右边菜单需要滚动多高的距离,那么我们如何获得该容器滚动的距离呢? 之前一直在使用better-scroll,通过阅读文档,我们知道它有有 scroll 事件,我们可以通过监听这个事件来获取滚动的 pos


Vue实现左右菜单联动实现
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打出来看看


Vue实现左右菜单联动实现

我们可以看到控制台打出了当前滚动的pos信息,因为在移动端开发时,坐标轴和我们数学中的坐标轴相反,所以上滑时y轴的值是负数


Vue实现左右菜单联动实现

所以我们要得到每一块 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) } 复制代码
Vue实现左右菜单联动实现

当用户在滚动时,我们需要计算当前滚动距离实在那个区间内,并拿到他的 index


Vue实现左右菜单联动实现
Vue实现左右菜单联动实现
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](( ustbhuangyi.github.io/better-scro… )派发的事件 selectLeft (index, event) { if (!event._constructed) { return } let rightItem = this.$refs.rightItem let el = rightItem[index] this.$refs.rightMenu.scrollToElement(el, 300) }, 复制代码

到这里我们就基本上完成了这些需求了

本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程

tags: gt,lt,index,scroll,菜单,class,rightHeight,div,li,height,pos,let
分页:12
转载请注明
本文标题:Vue实现左右菜单联动实现
本站链接:https://www.codesec.net/view/586903.html


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 前端(javascript) | 评论(0) | 阅读(15)