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 EasyUI 使用介绍
Apr 01 Javascript
this和执行上下文实现代码
Jul 01 Javascript
使用CDN和AJAX加速WordPress中jQuery的加载
Dec 05 Javascript
微信小程序 数据访问实例详解
Oct 08 Javascript
基于JS快速实现导航下拉菜单动画效果附源码下载
Oct 27 Javascript
JS识别浏览器类型(电脑浏览器和手机浏览器)
Nov 18 Javascript
ajax异步请求详解
Jan 06 Javascript
ES6中Proxy代理用法实例浅析
Apr 06 Javascript
使用mint-ui开发项目的一些心得(分享)
Sep 07 Javascript
利用JS判断客户端类型你应该知道的四种方法
Dec 22 Javascript
vue改变对象或数组时的刷新机制的方法总结
Apr 24 Javascript
解决vuex改变了state的值,但是页面没有更新的问题
Nov 12 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将字符串随机分割成不同长度数组的方法
2015/06/01 PHP
在Mac OS上搭建Nginx+PHP+MySQL开发环境的教程
2015/12/21 PHP
PHP+Ajax实现验证码的实时验证
2016/07/20 PHP
jquery 插件之仿“卓越亚马逊”首页弹出菜单效果
2008/12/25 Javascript
跨浏览器开发经验总结(四) 怎么写入剪贴板
2010/05/13 Javascript
基于node.js的快速开发透明代理
2010/12/25 Javascript
eval与window.eval的差别分析
2011/03/17 Javascript
jquery 卷帘效果实现代码(不同方向)
2013/02/05 Javascript
如何阻止复制剪切和粘贴事件为了表单内容的安全
2013/05/23 Javascript
文本有关的样式和jQuery求对象的高宽问题分别说明
2013/08/30 Javascript
扒一扒JavaScript 预解释
2015/01/28 Javascript
JSON字符串和对象之间的转换详解
2015/05/26 Javascript
javascript背景时钟实现方法
2015/06/18 Javascript
JavaScript 不支持 indexof 该如何解决
2016/03/30 Javascript
js 实现数值的千分位及保存小数方法(推荐)
2016/08/01 Javascript
jQuery动态生成Bootstrap表格
2016/11/01 Javascript
js原生之焦点图转换加定时器实例
2016/12/12 Javascript
javaScript生成支持中文带logo的二维码(jquery.qrcode.js)
2017/01/03 Javascript
js实现网页定位导航功能
2017/03/07 Javascript
Linux系统中利用node.js提取Word(doc/docx)及PDF文本的内容
2017/06/17 Javascript
JavaScript轮播停留效果的实现思路
2018/05/24 Javascript
angularJS实现不同视图同步刷新详解
2018/10/09 Javascript
vue-cli3+typescript初体验小结
2019/02/28 Javascript
JS实现选项卡效果的代码实例
2019/05/20 Javascript
Python自定义线程池实现方法分析
2018/02/07 Python
python自动化测试三部曲之unittest框架的实现
2020/10/07 Python
matplotlib之pyplot模块坐标轴标签设置使用(xlabel()、ylabel())
2021/02/22 Python
HTML5的文档结构和新增标签完全解析
2017/04/21 HTML / CSS
澳大利亚正品化妆品之家:Cosmetic Capital
2017/07/03 全球购物
elf彩妆英国官网:e.l.f. Cosmetics英国(美国平价彩妆品牌)
2017/11/02 全球购物
澳大利亚百货公司:David Jones
2018/02/08 全球购物
美国购买汽车零件网站:Buy Auto Parts
2018/04/02 全球购物
2014年无财产无子女离婚协议书范本
2014/10/09 职场文书
2015年社区宣传工作总结
2015/05/20 职场文书
于丹论语心得观后感
2015/06/15 职场文书
golang 实现菜单树的生成方式
2021/04/28 Golang