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 相关文章推荐
javascript 系统文件夹文件操作及参数介绍
Jan 08 Javascript
jQuery阻止同类型事件小结
Apr 19 Javascript
JavaScript将相对地址转换为绝对地址示例代码
Jul 19 Javascript
js的延迟执行问题分析
Jun 23 Javascript
jQuery中slideUp()方法用法分析
Dec 24 Javascript
JavaScript中用getDate()方法返回指定日期的教程
Jun 09 Javascript
使用Node.js实现HTTP 206内容分片的教程
Jun 23 Javascript
Angular Js文件上传之form-data
Aug 28 Javascript
微信小程序-详解数据缓存
Nov 24 Javascript
什么是Vue.js框架 为什么选择它?
Oct 17 Javascript
使用Bootstrap和Vue实现用户信息的编辑删除功能
Oct 25 Javascript
Quasar Input:type=&quot;number&quot; 去掉上下小箭头 实现加减按钮样式功能
Apr 09 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
mysql_num_rows VS COUNT 效率问题分析
2011/04/23 PHP
Symfony查询方法实例小结
2017/06/28 PHP
PHP实现将几张照片拼接到一起的合成图片功能【便于整体打印输出】
2017/11/14 PHP
Yii Framework框架开发微信公众平台示例
2020/04/26 PHP
百度留言本js 大家可以参考下
2009/10/13 Javascript
jQuery的each终止或跳过示例代码
2013/12/12 Javascript
JavaScript获取当前网页标题(title)的方法
2015/04/03 Javascript
js中substr,substring,indexOf,lastIndexOf,split,replace的用法详解
2015/11/09 Javascript
深入解析Backbone.js框架的依赖库Underscore.js的作用
2016/05/07 Javascript
javascript显示系统当前时间代码
2016/12/29 Javascript
网页中右键功能的实现方法之contextMenu的使用
2017/02/20 Javascript
js指定步长实现单方向匀速运动
2017/07/17 Javascript
React 路由懒加载的几种实现方案
2018/10/23 Javascript
Vue 实现前进刷新后退不刷新的效果
2019/06/14 Javascript
layui 地区三级联动 form select 渲染的实例
2019/09/27 Javascript
微信小程序中weui用法解析
2019/10/21 Javascript
Node.js API详解之 Error模块用法实例分析
2020/05/14 Javascript
详解Vue.js3.0 组件是如何渲染为DOM的
2020/11/10 Javascript
ReactRouter的实现方法
2021/01/25 Javascript
[04:07]显微镜下的DOTA2第八期——英雄复活动作
2014/06/24 DOTA
python网络编程示例(客户端与服务端)
2014/04/24 Python
从零学python系列之数据处理编程实例(二)
2014/05/22 Python
python snownlp情感分析简易demo(分享)
2017/06/04 Python
Python使用Matplotlib实现Logos设计代码
2017/12/25 Python
python selenium 获取标签的属性值、内容、状态方法
2018/06/22 Python
python 去除txt文本中的空格、数字、特定字母等方法
2018/07/24 Python
python实现while循环打印星星的四种形状
2019/11/23 Python
python实现交并比IOU教程
2020/04/16 Python
浅谈keras中Dropout在预测过程中是否仍要起作用
2020/07/09 Python
CSS3转换功能transform主要属性值分析及实现分享
2012/05/06 HTML / CSS
HTML5所有标签汇总及标签意义解释
2015/03/12 HTML / CSS
大学生专科毕业生自我评价
2013/11/17 职场文书
公务员总结性个人自我评价
2013/12/05 职场文书
工程项目建议书范文
2014/03/12 职场文书
初中教师业务学习材料
2014/05/12 职场文书
病人写给医生的感谢信
2015/01/23 职场文书