在做移动端商城或者其他页面的时候,经常会遇到左右联动的效果,今天小编vue2.0和better-scroll这个插件一起实现左右联动效果。

实现上面的效果,思路一定很重要,还有需求

1. 左边一级分类和右边二级分类形成联动

2. 当滑动右侧分类列表时, 更新左侧分类选中

3. 点击左侧一级分类项时, 右侧列表滑动到对应位置

在vue脚手架的时候,引入第三方插件better-scroll,如果想了解的话,可以去看看它的中午文档说明,

npm install better-scroll --save直接安装到自己项目当中,并引入

1.页面结构搭建

<div class="search"><!-- 搜索导航 --><SearchNav></SearchNav><div class="shop"><!-- 左边 --><div class="menu-wrapper"><ul><!-- current --><li class="menu-item"v-for="(goods,index) in searchgoods" :key="index":class="{current: index === currentIndex}"@click="clickList(index)"ref="menuList"><span>{{goods.name}}</span></li></ul></div><!-- 右边 --><div class="shop-wrapper"><ul ref="itemList"><li class="shops-li" v-for="(goods, index1) in searchgoods" :key="index1"><div class="shops-title"><h4>{{goods.name}}</h4><a href="">查看更多 > </a></div><ul class="phone-type" v-if="goods.tag === 'phone'"><li v-for="(phone,index) in goods.category" :key="index"><img :src="phone.icon" alt=""></li></ul><ul class="shops-items"><li v-for="(item, index2) in goods.items" :key="index2"><img :src="item.icon" alt=""><span>{{item.title}}</span></li></ul></li></ul></div></div></div> 

css样式

<style lang="stylus" rel="stylesheet/stylus" scoped>@import "../../common/stylus/mixins.styl".searchwidth 100%height 100%background-color #f5f5f5overflow hidden.shop display flexposition absolutetop 60pxbottom 50pxwidth 100%overflow hidden.menu-wrapperbackground-color #e0e0e0width 80pxflex 0 0 80px.menu-item width 100%height 60pxbackground #fafafadisplay flexjustify-content centeralign-items centerfont-family lightercolor #666position relative.currentcolor #e02e24background #ffffff.current::before content ''background-color #e02e24width 4pxheight 30pxposition absoluteleft 0.shop-wrapperflex 1background #fff.shops-titledisplay flexflex-direction rowpadding 0 10pxheight 40pxalign-items centerjustify-content space-betweencolor #9999atext-decoration nonecolor #9c9c9cfont-size 14px.shops-itemsdisplay flex flex-wrap wraplidisplay flexflex-direction columnwidth 33.3%height 90pxjustify-content centeralign-items center img width 60%height 60%margin-bottom 5pxspancolor #151516font-size 13px.phone-typewidth 100%display flexflex-direction rowflex-wrap wrapborder-bottom-1px (#cccccc)liwidth 33.3%display flex justify-content centeralign-items center margin 5px 0imgwidth 70%
</style>  

View Code

页面分为左右两个部分,

先实现左右两边滚动效果,我们需要在methods定义一个方法,但是better-scroll的初始化一定要在数据渲染完成后进行

methods:{
_initBScroll(){
    //左边滚动this.leftBscroll = new BScroll('.menu-wrapper',{});//右边滚动this.rightBscroll = new BScroll('.shop-wrapper',{
probeType:3   //在滚动中触发scroll 事件
    });  

}
}

 我们通过watch监听searchgoods数据是否有,并通过this.$nextTick去调用_initBScroll方法。

 searchgoods是数据存储的地方

watch:{searchgoods(){//监听数据this.$nextTick(() =>{//左右两边滚动this. _initBScroll();
//右边列表高度
this._initRightHeight()

      })}},

2.计算出每一个li标签的高度,并把它存放在一个数组当中

1.需要在data中定义两个变量

data () {return {scrollY:0, //右侧列表滑动的y轴坐标
      rightLiTops:[] //所有分类头部位置}},

2.在methods中定义一个方法,_initRightHeight,这个方法是用于计算每个li标签的高度

 //求出右边列表的高度_initRightHeight(){let itemArray=[]; //定义一个伪数组let top = 0;itemArray.push(top)//获取右边所有li的礼let allList = this.$refs.itemList.getElementsByClassName('shops-li');//allList伪数组转化成真数组Array.prototype.slice.call(allList).forEach(li => {top += li.clientHeight; //获取所有li的每一个高度itemArray.push(top)});this.rightLiTops = itemArray;// console.log(this.rightLiTops)},

通过上面的方法,已经把所有li标签的高度计算出来

3.监听右边滚动事件

通过better-scroll提供的 on 事件,当右边内容滚动的时候计算出滚动的距离,一定要在滚动的时候触发这个事件_initBScroll这个方法当中去写

//监听右边滚动事件this.rightBscroll.on('scroll',(pos) => {this.scrollY = Math.abs(pos.y);console.log(this.scrollY)})

4.动态绑定class样式

1需要给左右的li标签绑定一个:class="{current: index === currentIndex}",通过计算属性,实现这个效果
computed: {//动态绑定class类名currentIndex(index) {const {scrollY,rightLiTops} = this;return rightLiTops.findIndex((tops,index )=>{this._initLeftScroll(index);  //调用左右联调滚动效果return scrollY >= tops && scrollY < rightLiTops[index + 1]})}},

 5.点击左边实现滚动和左右滚动联调

5.1实现点击左边实现滚动效果,需要给左边的li标签绑定一个点击事件@click="clickList(index)",通过index来来计算出点击的位置

this.rightLiTops[index]通过index索引得到点击的时候,会得到每一块li标签的高度通过better-scroll提供的scrollTo来实现具体滚动的位置
clickList(index){this.scrollY = this.rightLiTops[index];this.rightBscroll.scrollTo(0,-this.scrollY,200,)},

5.2当右边内容滚动的时候,滚动一定的程度的时候,希望左边也会随着滚动,

5.2.1通过ref所有所有li标签

let menu = this.$refs.menuList;
5.2.2得到他们每一个索引值
let el = menu[index];
5.2.3通过scrollToElement实现滚动目标元素位置
//左右联调 _initLeftScroll(index){let menu = this.$refs.menuList;let el = menu[index];this.leftBscroll.scrollToElement(el,300,0,-300)}

以上都是基本上完成了这些需求了

最终代码

<template><div class="search"><!-- 搜索导航 --><SearchNav></SearchNav><div class="shop"><!-- 左边 --><div class="menu-wrapper"><ul><!-- current --><li class="menu-item"v-for="(goods,index) in searchgoods" :key="index":class="{current: index === currentIndex}"@click="clickList(index)"ref="menuList"><span>{{goods.name}}</span></li></ul></div><!-- 右边 --><div class="shop-wrapper"><ul ref="itemList"><li class="shops-li" v-for="(goods, index1) in searchgoods" :key="index1"><div class="shops-title"><h4>{{goods.name}}</h4><a href="">查看更多 > </a></div><ul class="phone-type" v-if="goods.tag === 'phone'"><li v-for="(phone,index) in goods.category" :key="index"><img :src="phone.icon" alt=""></li></ul><ul class="shops-items"><li v-for="(item, index2) in goods.items" :key="index2"><img :src="item.icon" alt=""><span>{{item.title}}</span></li></ul></li></ul></div></div></div>
</template><script>
import SearchNav from './Children/SearchNav'
import {mapState} from 'vuex'
import BScroll from 'better-scroll'
export default {name: 'chat',data () {return {scrollY: 0, //右侧列表滑动的y轴坐标
      rightLiTops:[] //所有分类头部位置
    }},computed: {...mapState(['searchgoods']),   //列表数据//动态绑定class类名
    currentIndex(index) {const {scrollY,rightLiTops} = this;return rightLiTops.findIndex((tops,index )=>{this._initLeftScroll(index);return scrollY >= tops && scrollY < rightLiTops[index + 1]})}},mounted() {this.$store.dispatch('reqSearchGoods')},components: {SearchNav},watch:{searchgoods(){//监听数据this.$nextTick(() =>{//左右两边滚动this. _initBScroll();//右边列表高度this._initRightHeight()})}},methods:{_initBScroll() {//左边滚动this.leftBscroll = new BScroll('.menu-wrapper',{});//右边滚动this.rightBscroll = new BScroll('.shop-wrapper',{probeType:3});//监听右边滚动事件this.rightBscroll.on('scroll',(pos) => {this.scrollY = Math.abs(pos.y);// console.log(this.scrollY)
      })},//求出右边列表的高度
    _initRightHeight(){let itemArray=[]; //定义一个伪数组
      let top = 0;itemArray.push(top)//获取右边所有li的礼
      let allList = this.$refs.itemList.getElementsByClassName('shops-li');//allList伪数组转化成真数组
      Array.prototype.slice.call(allList).forEach(li => {top += li.clientHeight; //获取所有li的每一个高度
        itemArray.push(top)});this.rightLiTops = itemArray;// console.log(this.rightLiTops)
    },//点击左边实现滚动
    clickList(index){this.scrollY = this.rightLiTops[index];console.log(this.scrollY)this.rightBscroll.scrollTo(0,-this.scrollY,200,)},//左右联调
    _initLeftScroll(index){let menu = this.$refs.menuList;let el = menu[index];this.leftBscroll.scrollToElement(el,300,0,-300)}}
}
</script><!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="stylus" rel="stylesheet/stylus" scoped>@import "../../common/stylus/mixins.styl".searchwidth 100%height 100%background-color #f5f5f5overflow hidden.shop display flexposition absolutetop 60pxbottom 50pxwidth 100%overflow hidden.menu-wrapperbackground-color #e0e0e0width 80pxflex 0 0 80px.menu-item width 100%height 60pxbackground #fafafadisplay flexjustify-content centeralign-items centerfont-family lightercolor #666position relative.currentcolor #e02e24background #ffffff.current::before content ''background-color #e02e24width 4pxheight 30pxposition absoluteleft 0.shop-wrapperflex 1background #fff.shops-titledisplay flexflex-direction rowpadding 0 10pxheight 40pxalign-items centerjustify-content space-betweencolor #9999atext-decoration nonecolor #9c9c9cfont-size 14px.shops-itemsdisplay flex flex-wrap wraplidisplay flexflex-direction columnwidth 33.3%height 90pxjustify-content centeralign-items center img width 60%height 60%margin-bottom 5pxspancolor #151516font-size 13px.phone-typewidth 100%display flexflex-direction rowflex-wrap wrapborder-bottom-1px (#cccccc)liwidth 33.3%display flex justify-content centeralign-items center margin 5px 0imgwidth 70%
</style>  

View Code

转载于:https://www.cnblogs.com/zhoulifeng/p/9646296.html

vue2.0和better-scroll实现左右联动效果相关推荐

  1. 使用vue2.0 vue-router vuex 模拟ios7操作

    其实你也可以,甚至做得更好... 首先看一下效果:用vue2.0实现SPA:模拟ios7操作 与 通讯录实现 github地址是:https://github.com/QRL909109/ios7 如 ...

  2. vue2.0 如何自定义组件(vue组件的封装)

    一.前言 之前的博客聊过 vue2.0和react的技术选型:聊过vue的axios封装和vuex使用.今天简单聊聊 vue 组件的封装. vue 的ui框架现在是很多的,但是鉴于移动设备的复杂性,兼 ...

  3. 【Vue学习笔记】尚硅谷Vue2.0+Vue3.0全套教程丨vue.js从入门到精通

    尚硅谷Vue2.0+Vue3.0全套教程丨vue.js从入门到精通 1.Vue核心部分 1.1 Vue简介 1.1.1 Vue是什么? Vue是一套用于构建用户界面的渐进式JavaScript框架. ...

  4. vue2.0桌面端框架_vue 专题 vue2.0各大前端移动端ui框架组件展示

    element ★13489 - 饿了么出品的Vue2的web UI工具套件 Vux ★8133 - 基于Vue和WeUI的组件库 iview ★6634 - 基于 Vuejs 的开源 UI 组件库 ...

  5. Vue2.0中的事件修饰符

    Vue2.0中的事件修饰符: 1.prevent:阻止默认事件,原生js里面为event.preventDefault() 2.stop:阻止事件冒泡 3.once:事件只触发一次 4.capture ...

  6. vue 专题 vue2.0各大前端移动端ui框架组件展示

    Vue 专题 一个数据驱动的组件,为现代化的 Web 界面而生.具有可扩展的数据绑定机制,原生对象即模型,简洁明了的 API 组件化 UI 构建 多个轻量库搭配使用 请访问链接: https://ww ...

  7. 下拉刷新和上拉加载 php,怎样操作vue2.0 移动端实现下拉刷新和上拉加载

    这次给大家带来怎样操作vue2.0 移动端实现下拉刷新和上拉加载,操作vue2.0 移动端实现下拉刷新和上拉加载的注意事项有哪些,下面就是实战案例,一起来看一下. 直接上代码,不懂的多看几遍,下面我换 ...

  8. 基于VUE2.0的高仿饿了么分析与总结

    2019独角兽企业重金招聘Python工程师标准>>> 首先,慕课网提供的视频是基于vue1.0的规范写的,因此有一些地方在vue2.0下不能正常运行.虽然课程补充文件也提供了vue ...

  9. 尚硅谷Vue2.0+Vue3.0全套教程视频笔记 + 代码 [P001-050]

    视频链接:尚硅谷Vue2.0+Vue3.0全套教程丨vuejs从入门到精通_哔哩哔哩_bilibili P1-50:当前页面.  P51-100:尚硅谷Vue2.0+Vue3.0全套教程视频笔记 + ...

  10. vue2.0 与 bootstrap datetimepicker的结合使用

    vue2.0 与 bootstrap datetimepicker的结合使用 1.在很多的项目中,我们都会用到日期插件,然后当我在vue中使用bootstrap datetimepicker时发现双向 ...

最新文章

  1. PHP的htmlspecialchars、strip_tags、addslashes解释
  2. 升级到VS.net 2008 sp1并安装卡巴斯基的兄弟们小心了
  3. 研究者展示黑客通过GPU绕过防毒软件查杀的方法
  4. 【操作系统】实验 设计一个按优先权调度算法实现处理器调度的程序
  5. java swing双缓冲_java中的双缓冲技术
  6. 2020年开发者大会资料和武大定量遥感视频分享(部分)
  7. Function语意学之Member的各种调用方式
  8. python的模块和包
  9. VidLoc:A Deep Spatio-Temporal Model for 6-DoF Video-Clip Relocalization用于6-DoF视频片段重新定位的深度时空模型
  10. Cisco ❀ QinQ技术与VXLAN技术的区别
  11. 工具答疑---beyond compar文件无法编辑
  12. Android Home键拦截
  13. matlab处理afm图片,基于MATLAB的增大页岩AFM灰度图分辨率的方法与流程
  14. 【workqueue】flush_work函数解析
  15. 【问题】2.Bind for 0.0.0.0:8887 failed: port is already allocated错误
  16. WeQuant交易策略—5日均线
  17. python反恐精英基础版_python反恐精英
  18. jenkins构建:ERROR: Error fetching remote repo ‘origin‘(hudson.plugins.git.GitException/does not point)
  19. ssd的smt_联合评测 | Intel Optane SSD 有效加速 SmartX 超融合在 Oracle 等场景下的系统性能...
  20. SDWAN组网典型应用

热门文章

  1. 【云服务月刊】2018年第7期:云栖大会门票免费送!阿里云MVP招募,就等你了!...
  2. AJAX Accordion:可折叠面板的集合
  3. 《Producter:让产品从0到1》一导读
  4. Go语言中Path包用法
  5. red hat linux 6.4 DNS配置(怎么不让发表?)
  6. 如何使用虚拟实验室建设思科IPS***防御课程的实验环境
  7. Hibernate的批量处理-批量更新
  8. 浙江商人立下的22条规矩
  9. Daily scrum 10.12
  10. 解决 Python 连不上pip库的问题(使用国内镜像地址)