scroll实现菜单映射功能方法

<template> <div> <!--左侧区域--> <div ref="left"> <ul> <li :class="{'current':currentIndex===index}" v-for="(item,index) in dataLlist.goods" :key="index" @click="selectIndex(index,$event)" ref="menuList" > <div> <goods-icon v-show="item.type>0" :index="item.type"></goods-icon> {{item.name}} </div> </li> </ul> </div> <!--右侧区域--> <div ref="right"> <ul> <li v-for="(item,index) in dataLlist.goods" :key="index"> <!--标题区域--> <h1>{{item.name}}</h1> <ul> <li v-for="(foodItem,index) in item.foods" > <div> <img :src="foodItem.icon" alt="foodItem.name"> </div> <div> <div>{{foodItem.name}}</div> <div>{{foodItem.description}}</div> <div> <div>月售{{foodItem.sellCount}}份</div> <div>好评率{{foodItem.rating}}%</div> </div> <div> <div>¥{{foodItem.price}}</div> <div v-show="foodItem.oldPrice">¥{{foodItem.oldPrice}}</div> </div> </div> </li> </ul> </li> </ul> </div> </div> </template> <script> import Icon from '../../common/iconType/Icon'; import BScroll from 'better-scroll' export default { name: "Goods", props:['dataLlist'], data(){ return{ listHeight:[], scrollY:0 ,//为了实现左右区域映射 } }, computed:{ currentIndex(){ //这个返回的是下标,当这个currentIndex的值与goods的下标一致的时候, // 左侧区域就会呈现高亮现象 for (let i = 0; i < this.listHeight.length; i++) { let height1 = this.listHeight[i]; let height2 = this.listHeight[i + 1]; if (!height2 || (this.scrollY >= height1 && this.scrollY < height2)) { this._followScroll(i) //实现当滑动的时候,左侧隐藏的食物类型显示 return i; } } return 0; } }, created(){ //dataLlist数据是异步加载,直接用new BScroll时,dom可能还没有更新 this.$nextTick(()=>{ //this.$nextTick()将回调延迟到下次 DOM 更新循环之后执行,使用$nextTick异步初始化Bscroll this.meunScroll=new BScroll(this.$refs.left,{ click:true }); this.foodScroll=new BScroll(this.$refs.right,{ probeType: 3 //可以派发scroll事件,检测到实时滚动的位置 }); this.foodScroll.on('scroll',(pos) =>{ //参数pos就是在右侧区域滑动的实时位置 //Math.round()取整数,Math.abs取绝对值 this.scrollY =Math.abs( Math.round(pos.y)); }); this._calculateHeight(); //这个方法为了获取每个商品类的最大区间的高度 }) }, methods:{ _followScroll(index) { if(index > 0 ){ let menuList = this.$refs.menuList; let el = menuList[index]; this.meunScroll.scrollToElement(el, 300, 0, -100);//better-scroll的scrollToElement方法滚动到指定位置 } }, _calculateHeight(){ //这个方法为了获取每个商品类的最大区间的高度 let height = 0; let foodLsit = this.$refs.right.getElementsByClassName('food-list-hook'); this.listHeight.push(height); //listHeight这个数组是用来存放右侧商品中每个类型商品的最大区间高度的集合 for(var i=0;i<foodLsit.length;i++){ let item = foodLsit[i]; //clientHeight代表元素的高度 height += item.clientHeight; //每个元素的高度等于自身高度加上上一个元素的高度 this.listHeight.push(height); //最终listHeight集合了所有li[类为food-list-hook]到最顶部的高度 } }, selectIndex(index,ele){ //better-scroll 会禁止移动端的点击事件,需要重新派发,同时在PC端会点击两次,此处需要做判断 if(!ele._constructed){ //better-scroll的派发事件scroll的event和pc端浏览器的点击事件的event有个 // 属性区别_constructed,pc端浏览器的点击事件的event中是没有这个属性的 return; } let rightItem =this.$refs.right.getElementsByClassName('food-list-hook'); let item = rightItem[index]; //找到相应的li this.foodScroll.scrollToElement(item, 250) //better-scroll的scrollToElement方法滚动到指定位置 } // scrollToElement(el, time, offsetX, offsetY, easing) //第一个值接收目标元素,第二个是滚动时间,第三第四个是相对于目标元素的偏移量。 }, components:{ 'goods-icon': Icon } } </script> <style scoped lang="stylus"> @import "../../assets/stylus/mixin.styl" .goods position absolute top 3.6rem bottom .92rem display flex width: 100% overflow: hidden .menu-wrapper flex 0 0 1.6rem width 1.6rem background-color #f3f5f7 .menu-item height 1.08rem display flex align-items center justify-content left &.border-bottom::before color rgba(7,17,27,.1) .text font-weight 200 font-size .24rem line-height .28rem margin 0 .24rem .text-ico margin-right -.08rem vertical-align top; &.current font-size .24rem line-height .28rem color rgb(240,20,20) background-color #ffffff .foods-wrapper flex 1 .food-list h1 width 100% height .52rem line-height .52rem padding-left .28rem background-color #f3f5f7 font-size .24rem color rgb(147,153,159) &.border-left::before border-color #d9dde1 border-width .1rem .food-item display flex padding .36rem &:last-child.border-bottom border none .food-desc margin-left .2rem font-size .2rem color rgb(147,153,159) .title font-size:.28rem color rgb(7,17,27) margin-top .04rem line-height .28rem .desc margin .15rem auto line-height:.28rem .num display flex margin 0 0 .16rem 0 .sellCount margin-right .24rem .price display flex align-items center .new-price color rgb(220,20,60) font-weight 700 line-height .48rem margin-right .16rem font-size .28rem .old-price &.border-bottom::before position absolute top: 25%; border-width: 0.08rem; </style>

Vue项目中使用better-scroll实现菜单滑动功能

安装和在组件中引入better-scroll

npm install better-scroll --save

引入import BScroll from 'better-scroll' 【在组件中引入,在后续的export default中就可以直接使用封装好的better-scroll功能了】

better-scroll实现的下面功能

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/864cbaf84b83cdedac0efb83a026c0e7.html