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滚动条多种样式,推荐
Feb 05 Javascript
WordPress 插件——CoolCode使用方法与下载
Jul 02 Javascript
图片onload事件触发问题解决方法
Jul 31 Javascript
js中parseFloat(参数1,参数2)定义和用法及注意事项
Jan 27 Javascript
在JavaScript中typeof的用途介绍
Apr 11 Javascript
JS使用getComputedStyle()方法获取CSS属性值
Apr 23 Javascript
javascript最基本的函数汇总
Jun 25 Javascript
使用jquery的jsonp如何发起跨域请求及其原理详解
Aug 17 jQuery
详解在vue-cli中使用路由
Sep 25 Javascript
Vue官方文档梳理之全局配置
Nov 22 Javascript
微信小程序实现两边小中间大的轮播效果的示例代码
Dec 07 Javascript
vue路由对不同界面进行传参及跳转的总结
Apr 20 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构造方法中析构方法在继承中的表现
2016/04/12 PHP
yii2 页面底部加载css和js的技巧
2016/04/21 PHP
php使用escapeshellarg时中文被过滤的解决方法
2016/07/10 PHP
PHP图片裁剪与缩放示例(无损裁剪图片)
2017/02/08 PHP
在Yii2特定页面如何禁用调试工具栏Debug Toolbar详解
2017/08/07 PHP
PHP7变量处理机制修改
2021/03/09 PHP
一个网马的tips实现分析
2010/11/28 Javascript
jQuery(非HTML5)可编辑表格实现代码
2012/12/11 Javascript
jQuery 1.9.1源码分析系列(十)事件系统之绑定事件
2015/11/19 Javascript
javascript表单事件处理方法详解
2016/05/15 Javascript
Jquery修改image的src属性,图片不加载问题的解决方法
2016/05/17 Javascript
后端接收不到AngularJs中$http.post发送的数据原因分析及解决办法
2016/07/05 Javascript
JS作用域深度解析
2016/12/29 Javascript
vue-resource 拦截器(interceptor)的使用详解
2017/07/04 Javascript
vue 自定义提示框(Toast)组件的实现代码
2018/08/17 Javascript
jquery.param()实现数组或对象的序列化方法
2018/10/08 jQuery
JavaScript Canvas编写炫彩的网页时钟
2019/10/16 Javascript
微信小程序获取公众号文章列表及显示文章的示例代码
2020/03/10 Javascript
vue使用nprogress加载路由进度条的方法
2020/06/04 Javascript
Javascript基于OOP实实现探测器功能代码实例
2020/08/26 Javascript
[14:00]DOTA2国际邀请赛史上最长大战 赛后专访B神
2013/08/10 DOTA
在Django的上下文中设置变量的方法
2015/07/20 Python
python中ImageTk.PhotoImage()不显示图片却不报错问题解决
2018/12/06 Python
python中时间模块的基本使用教程
2019/05/14 Python
Python实现语音识别和语音合成功能
2019/09/20 Python
基于python traceback实现异常的获取与处理
2019/12/13 Python
python实现猜拳游戏
2020/03/04 Python
基于tensorflow __init__、build 和call的使用小结
2021/02/26 Python
animation和transition的区别
2020/10/12 HTML / CSS
质检员岗位职责
2013/12/17 职场文书
高级护理专业毕业生推荐信
2013/12/25 职场文书
秋季运动会加油稿200字
2014/01/11 职场文书
学生周末长期请假条
2014/02/15 职场文书
2014年党员承诺书范文
2014/05/20 职场文书
拔河比赛口号
2014/06/10 职场文书
javascript的var与let,const之间的区别详解
2022/02/18 Javascript