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 相关文章推荐
找到一点可怜的关于dojo资料,谢谢作者!
Dec 06 Javascript
基于Jquery的表格隔行换色,移动换色,点击换色插件
Dec 22 Javascript
使用js如何实现全选与全不选
Dec 30 Javascript
玩转NODE.JS(四)-搭建简单的聊天室的代码
Nov 11 Javascript
JavaScript实现二叉树定义、遍历及查找的方法详解
Dec 20 Javascript
jQuery实现鼠标移到某个对象时弹出显示层功能
Aug 23 jQuery
微信小程序实现带缩略图轮播效果
Nov 04 Javascript
JavaScript 格式化数字、金额、千分位、保留几位小数、舍入舍去
Jul 23 Javascript
用VsCode编辑TypeScript的实现方法
May 07 Javascript
uni-app从安装到卸载的入门教程
May 15 Javascript
vue实现数字滚动效果
Jun 29 Javascript
vue.js click点击事件获取当前元素对象的操作
Aug 07 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
ThinkPHP CURD方法之where方法详解
2014/06/18 PHP
PHP5.3与5.5废弃与过期函数整理汇总
2014/07/10 PHP
php实现基于微信公众平台开发SDK(demo)扩展的方法
2014/12/22 PHP
Zend Framework框架实现类似Google搜索分页效果
2016/11/25 PHP
ThinkPHP使用getlist方法实现数据搜索功能示例
2017/05/08 PHP
PHP封装的PDO数据库操作类实例
2017/06/21 PHP
php-fpm超时时间设置request_terminate_timeout资源问题分析
2019/09/27 PHP
ejs v9 javascript模板系统
2012/03/21 Javascript
JQuery为textarea添加maxlength属性并且兼容IE
2013/04/25 Javascript
js实现同一个页面多个渐变效果的方法
2015/04/10 Javascript
JavaScript中函数表达式和函数声明及函数声明与函数表达式的不同
2015/11/15 Javascript
学习JavaScript设计模式(封装)
2015/11/26 Javascript
jquery对dom节点的操作【推荐】
2016/04/15 Javascript
Bootstrap网格系统详解
2016/04/26 Javascript
Bootstrap实现导航栏的2种方式
2016/11/28 Javascript
JavaScript利用正则表达式替换字符串中的内容
2016/12/12 Javascript
Angular4编程之表单响应功能示例
2017/12/13 Javascript
详解mpvue小程序中怎么引入iconfont字体图标
2018/10/01 Javascript
vue实现父子组件之间的通信以及兄弟组件的通信功能示例
2019/01/29 Javascript
原生JS实现天气预报
2020/06/16 Javascript
[36:19]2018DOTA2亚洲邀请赛 小组赛 A组加赛 Newbee vs LGD
2018/04/03 DOTA
Python自动化运维之IP地址处理模块详解
2017/12/10 Python
spark: RDD与DataFrame之间的相互转换方法
2018/06/07 Python
python 在某.py文件中调用其他.py内的函数的方法
2019/06/25 Python
Python整数与Numpy数据溢出问题解决
2019/09/11 Python
python实现布隆过滤器及原理解析
2019/12/08 Python
全方位了解CSS3的Regions扩展
2015/08/07 HTML / CSS
天猫国际进口超市直营:官方直采,一站购齐
2017/12/11 全球购物
100%法国制造的游戏和玩具:Les Jouets Français
2021/03/02 全球购物
函授本科个人自我鉴定
2014/03/25 职场文书
蓝颜请假条
2014/04/11 职场文书
感恩父母的演讲稿
2014/05/06 职场文书
2015年村级财务管理制度
2015/08/04 职场文书
python实现自动化群控的步骤
2021/04/11 Python
gateway与spring-boot-starter-web冲突问题的解决
2021/07/16 Java/Android
【海涛dota解说】一房久违的影魔魂守二连发
2022/04/01 DOTA