Vue实现左右菜单联动实现代码


Posted in Javascript onAugust 12, 2018

本文介绍了Vue实现左右菜单联动实现代码吗,分享给大家,也给自己留个笔记,具体如下:

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]((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)
},

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js 禁止选择功能实现代码(兼容IE/Firefox)
Apr 23 Javascript
Jquery下EasyUI组件中的DataGrid结果集清空方法
Jan 06 Javascript
ajax如何实现页面局部跳转与结果返回
Aug 24 Javascript
jQuery+Ajax实现无刷新分页
Oct 30 Javascript
详解javascript中原始数据类型Null和Undefined
Dec 17 Javascript
一种新的javascript对象创建方式Object.create()
Dec 28 Javascript
下一代Bootstrap的5个特点 超酷炫!
Jun 17 Javascript
深入理解jQuery layui分页控件的使用
Aug 17 Javascript
微信小程序 开发之快递查询功能的实现
Jan 09 Javascript
jQuery手风琴的简单制作
May 12 jQuery
微信小程序 空白页重定向解决办法
Jun 27 Javascript
vue-star评星组件开发实例
Mar 01 Javascript
Vue中的v-for循环key属性注意事项小结
Aug 12 #Javascript
vue实现商品加减计算总价的实例代码
Aug 12 #Javascript
Vue.js中使用iView日期选择器并设置开始时间结束时间校验功能
Aug 12 #Javascript
深入理解Vue父子组件生命周期执行顺序及钩子函数
Aug 12 #Javascript
VUE在for循环里面根据内容值动态的加入class值的方法
Aug 12 #Javascript
JS中的两种数据类型及实现引用类型的深拷贝的方法
Aug 12 #Javascript
原生JS封装_new函数实现new关键字的功能
Aug 12 #Javascript
You might like
深入解析PHP中的(伪)多线程与多进程
2013/07/01 PHP
php中利用str_pad函数生成数字递增形式的产品编号
2013/09/30 PHP
php中smarty实现多模版网站的方法
2015/06/11 PHP
php校验公钥是否可用的实例方法
2019/09/17 PHP
YII2框架中添加自定义模块的方法实例分析
2020/03/18 PHP
漂亮的widgets,支持换肤和后期开发新皮肤
2007/04/23 Javascript
判断JavaScript对象是否可用的最正确方法分析
2008/10/03 Javascript
Javascript脚本实现静态网页加密实例代码
2013/11/05 Javascript
iframe中子父类窗口调用JS的方法及注意事项
2015/08/25 Javascript
js删除局部变量的实现方法
2016/06/25 Javascript
在ABP框架中使用BootstrapTable组件的方法
2017/07/31 Javascript
vue-router中的hash和history两种模式的区别
2018/07/17 Javascript
原生JS实现的轮播图功能详解
2018/08/06 Javascript
element-ui循环显示radio控件信息的方法
2018/08/24 Javascript
vue.js实现带日期星期的数字时钟功能示例
2018/08/28 Javascript
Jquery ajax书写方法代码实例解析
2020/06/12 jQuery
微信小程序实现弹幕墙(祝福墙)
2020/11/18 Javascript
Python实现FTP上传文件或文件夹实例(递归)
2017/01/16 Python
Python实现通过文件路径获取文件hash值的方法
2017/04/29 Python
Python使用QRCode模块生成二维码实例详解
2017/06/14 Python
Python查找两个有序列表中位数的方法【基于归并算法】
2018/04/20 Python
Python3.5 Pandas模块之Series用法实例分析
2019/04/23 Python
Python While循环语句实例演示及原理解析
2020/01/03 Python
Python selenium爬虫实现定时任务过程解析
2020/06/08 Python
python下载的库包存放路径
2020/07/27 Python
python3排序的实例方法
2020/10/20 Python
CSS3网格的三个新特性详解
2014/04/04 HTML / CSS
HTML5中如何显示视频呢 HTML5视频播放demo
2013/06/08 HTML / CSS
密封类可以有虚函数吗
2014/08/11 面试题
自考自我鉴定范文
2013/10/30 职场文书
简历上的自我评价
2014/02/03 职场文书
小学学校评估方案
2014/06/08 职场文书
护理学专业求职信
2014/06/29 职场文书
ktv好的活动方案
2014/08/15 职场文书
网球场地租赁协议范本
2014/10/07 职场文书
巾帼建功标兵先进事迹材料
2016/02/29 职场文书