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 相关文章推荐
利用JQuery制作符合Web标准的QQ弹出消息
Jan 14 Javascript
Javascript中arguments和arguments.callee的区别浅析
Apr 24 Javascript
js验证框架实现代码分享
May 18 Javascript
Bootstrap CSS组件之大屏幕展播
Dec 17 Javascript
vue父组件中获取子组件中的数据(实例讲解)
Sep 27 Javascript
jquery实现左右轮播图效果
Sep 28 jQuery
微信小程序实现之手势锁功能实例代码
Jul 19 Javascript
解决JQuery的ajax函数执行失败alert函数弹框一闪而过问题
Apr 10 jQuery
layUI实现前端分页和后端分页
Jul 27 Javascript
jQuery实现中奖播报功能(让文本滚动起来) 简单设置数值即可
Mar 20 jQuery
详解JavaScript匿名函数和闭包
Jul 10 Javascript
Vue自动构建发布脚本的方法示例
Jul 24 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快速url重写更新版[需php 5.30以上]
2010/04/25 PHP
CI使用Tank Auth转移数据库导致密码用户错误的解决办法
2014/06/12 PHP
php对关联数组循环遍历的实现方法
2015/03/13 PHP
在Mac OS上搭建PHP的Yii框架及相关测试环境
2016/02/14 PHP
Zend Framework路由器用法实例详解
2016/12/11 PHP
使用PHP+JQuery+Ajax分页的实现
2013/04/23 Javascript
配置Grunt的Task时通配符支持和动态生成文件名问题
2015/09/06 Javascript
CSS中position属性之fixed实现div居中
2015/12/14 Javascript
详解JS获取HTML DOM元素的8种方法
2017/06/17 Javascript
js 简易版滚动条实例(适用于移动端H5开发)
2017/06/26 Javascript
Angular实现的内置过滤器orderBy排序与模糊查询功能示例
2017/12/29 Javascript
vue cli3.0结合echarts3.0与地图的使用方法示例
2019/03/26 Javascript
vue.js实现二级菜单效果
2019/10/19 Javascript
Vue中多元素过渡特效的解决方案
2020/02/05 Javascript
vue+canvas实现移动端手写签名
2020/05/21 Javascript
JQuery通过键盘控制键盘按下与松开触发事件
2020/08/07 jQuery
[01:30:54]《加油DOTA》 第三期
2014/08/18 DOTA
python进阶教程之动态类型详解
2014/08/30 Python
详解Python中的元组与逻辑运算符
2015/10/13 Python
利用Tkinter(python3.6)实现一个简单计算器
2017/12/21 Python
python3中函数参数的四种简单用法
2018/07/09 Python
Python多进程fork()函数详解
2019/02/22 Python
python自动化工具之pywinauto实例详解
2019/08/26 Python
tensorflow如何批量读取图片
2019/08/29 Python
基于python实现雪花算法过程详解
2019/11/16 Python
Tensorflow 定义变量,函数,数值计算等名字的更新方式
2020/02/10 Python
pyCharm 设置调试输出窗口中文显示方式(字符码转换)
2020/06/09 Python
python支持多继承吗
2020/06/19 Python
俄罗斯街头服装品牌:Black Star Wear
2017/03/01 全球购物
历史学专业推荐信
2013/11/06 职场文书
回门宴父母答谢词
2014/01/26 职场文书
外贸专业求职信
2014/03/09 职场文书
母亲节感恩活动记录
2014/03/16 职场文书
公司联欢会策划方案
2014/05/19 职场文书
小学师德标兵先进事迹材料
2014/05/25 职场文书
学校趣味运动会开幕词
2016/03/04 职场文书