vue.js2.0 实现better-scroll的滚动效果实例详解


Posted in Javascript onAugust 13, 2018

什么是 better-scroll

better-scroll 是一个移动端滚动的解决方案,它是基于 iscroll 的重写,它和 iscroll 的主要区别在这里 。better-scroll 也很强大,不仅可以做普通的滚动列表,还可以做轮播图、picker 等等。

<template>
  <div>
    <div class="goods">
      <div class="menu-wrapper" ref="menuWrapper">
      </div>
      <div class="food-wrapper" ref="foodWrapper">
      </div>
    </div>
  </div>
</template>

与1.0版本不同的是,我们使用的是ref

<script type="text/ecmascript-6">
  import BScroll from "better-scroll";
  export default {
    data(){
  return {
  currentIndex:1,
  goods:[]
  }  
 },
 created(){
  this.classMap=['decrease','discount','special','invoice','guarantee'];
  this.$http.get('/api/goods').then((response)=>{
  response=response.body;
  if (response.errno===ERR_OK) {
   this.goods=response.data;
  }
        //dom结构加载结束(nextTick这个接口是计算dom相关的,要确保原生dom已经渲染了)
  this.$nextTick(()=>{
   this._initScroll();
  });
  });
 },
 methods:{
  _initScroll(){
        // 使用better-scroll实现的关键代码
  this.menuScroll=new BScroll(this.$refs.menuWrapper,{click:true});
  this.foodScroll=new BScroll(this.$refs.foodWrapper,{click:true});
  }
 }
  };
</script>

很简单这样页面就可以滚动了,如下图

vue.js2.0 实现better-scroll的滚动效果实例详解

但是,这样左右两个页面并没有联动起来,需要我们再定义一个方法来计算滚动的高度,以及在计算属性中计算左侧当前索引在哪里

从而定义左侧边栏的位置

computed:{
  //用来计算左侧当前索引在哪,从而定位到左侧边栏的位置
  currentIndex(){
  for (let i = 0; i < this.listHeight.length; i++) {
   var height1=this.listHeight[i] ;
   var height2=this.listHeight[i+1];
   if(!height2||(this.scrollY >= height1 && this.scrollY < height2)){
   return i;
   }
  }
  return 0;
  }
 },
 methods:{
  _initScroll(){
  // 使用better-scroll实现的关键代码
  this.menuScroll=new BScroll(this.$refs.menuWrapper,{click:true});
  this.foodScroll=new BScroll(this.$refs.foodWrapper,{
   click: true,
          //探针作用,实时监测滚动位置
          probeType: 3
  });
  this.foodScroll.on('scroll',(pos)=>{
   this.scrollY=Math.abs(Math.round(pos.y))
  });
  },
  _calculateHeight(){
  let foodList=this.$refs.foodWrapper.getElementsByClassName('food-list-hook');
  let height=0;
  this.listHeight.push(height);
  for (var i = 0; i < foodList.length; i++) {
   let item=foodList[i];
   height+=item.clientHeight;
   this.listHeight.push(height);
  }
  }
 }
//dom结构加载结束(nextTick这个接口是计算dom相关的,要确保原生dom已经渲染了)
         this.$nextTick(()=>{
           this._initScroll();
           this._calculateHeight();
         });

在dom渲染后,也是需要计算高度的.

滑动右边,实现左边联动已经实现了,接下来就是,点击左边的菜单,右边的食物相应滚动到具体的位置

给左边菜单绑定一个事件:@click="selectMenu(index,$event)"

/左边的菜单项的点击事件
selectMenu(index,event){
//自己默认派发事件时(BScroll),_constructed默认为true.但原生的浏览器并没有这个属性
 if (!event._constructed) {
   return;
 }
 //运用BScroll滚动到相应位置
 //运用index去找到对应的右侧位置
 let foodList=this.$refs.foodWrapper.getElementsByClassName('food-list-hook');
 //滚动到相应的位置
 let el=foodList[index];
 //设置滚动时间
 this.foodScroll.scrollToElement(el,2000);
}

至此,整个联动实现的,完整代码如下

<template>
 <div>
 <div class="goods">
  <div class="menu-wrapper" ref="menuWrapper">
  <ul>
   <li v-for="(item,index) in goods" class="menu-item" :class="{'current':currentIndex===index}" @click="selectMenu(index,$event)">
   <span class="text border-1px">
    <span v-show="item.type>0" class="icon" :class="classMap[item.type]"></span>{{item.name}}
   </span>
   </li>
  </ul>
  </div>
  <div class="food-wrapper" ref="foodWrapper">
  <ul>
   <li v-for="(item,index) in goods" class="food-list food-list-hook">
   <h1 class="title">{{item.name}}</h1>
   <ul>
    <li v-for="food in item.foods" class="food-item border-1px">
    <div class="icon">
     <img :src="food.icon" width="57" height="57" alt="">
    </div>
    <div class="content">
     <h2 class="name">{{food.name}}</h2>
     <p class="desc">{{food.description}}</p>
     <div class="extra">
     <span class="count">月售{{food.sellCount}}份</span>
     <span>好评率{{food.rating}}%</span>
     </div>
     <div class="price">
     <span class="now">¥{{food.price}}</span><span class="old" v-show="food.oldPrice">¥{{food.oldPrice}}</span>
     </div>
    </div>
    </li>
   </ul>
   </li>
  </ul>
  </div>
 </div>
 </div>
</template>
<script type="text/ecmascript-6">
 import BScroll from "better-scroll";
 const ERR_OK=0;
 export default {
 props:{
  seller:{
  type:Object
  }
 },
 data(){
  return {
  goods:[],
  listHeight:[],
  scrollY:0
  }  
 },
 created(){
  this.classMap=['decrease','discount','special','invoice','guarantee'];
  this.$http.get('/api/goods').then((response)=>{
  response=response.body;
  if (response.errno===ERR_OK) {
   this.goods=response.data;
  }
  //dom结构加载结束(nextTick这个接口是计算dom相关的,要确保原生dom已经渲染了)
  this.$nextTick(()=>{
   this._initScroll();
   this._calculateHeight();
  });
  });
 },
 computed:{
  //用来计算左侧当前索引在哪,从而定位到左侧边栏的位置
  currentIndex(){
  for (let i = 0; i < this.listHeight.length; i++) {
   var height1=this.listHeight[i] ;
   var height2=this.listHeight[i+1];
   if(!height2||(this.scrollY >= height1 && this.scrollY < height2)){
   return i;
   }
  }
  return 0;
  }
 },
 methods:{
  _initScroll(){
  // 使用better-scroll实现的关键代码
  this.menuScroll=new BScroll(this.$refs.menuWrapper,{click:true});
  this.foodScroll=new BScroll(this.$refs.foodWrapper,{
   click: true,
          //探针作用,实时监测滚动位置
          probeType: 3
  });
  this.foodScroll.on('scroll',(pos)=>{
   this.scrollY=Math.abs(Math.round(pos.y))
  });
  },
  _calculateHeight(){
  let foodList=this.$refs.foodWrapper.getElementsByClassName('food-list-hook');
  let height=0;
  this.listHeight.push(height);
  for (var i = 0; i < foodList.length; i++) {
   let item=foodList[i];
   height+=item.clientHeight;
   this.listHeight.push(height);
  }
  },
  //左边的菜单项的点击事件
  selectMenu(index,event){
  //自己默认派发事件时(BScroll),_constructed默认为true.但原生的浏览器并没有这个属性
  if (!event._constructed) {
   return;
  }
  //运用BScroll滚动到相应位置
  //运用index去找到对应的右侧位置
  let foodList=this.$refs.foodWrapper.getElementsByClassName('food-list-hook');
  //滚动到相应的位置
  let el=foodList[index];
  //设置滚动时间
  this.foodScroll.scrollToElement(el,2000);
  }
 }
 };
</script>
<style lang="stylus" rel="stylesheet/stylus">
 @import "../../common/stylus/mixin.styl";
 
 .goods
 display:flex
 position:absolute
 top:174px
 bottom:46px
 width:100%
 overflow:hidden
 .menu-wrapper
  flex:0 0 80px
  width: 80px
  background:#f3f5f7
  .menu-item
  display:table
  height:54px
  width:56px
  padding:0 12px
  line-height:14px
  &.current
   position:relative
   z-index:10
   margin-top:-1px
   background:#fff
   font-weight:700
   .text
   border-none()
  .icon
   display:inline-block
   vertical-align:top
   margin-right:2px
   width:12px
   height:12px
   background-size:12px 12px
   background-repeat:no-repeat
   &.decrease
   bg-image('decrease_3')
   &.discount
   bg-image('discount_3') 
   &.guarantee
   bg-image('guarantee_3') 
   &.invoice
   bg-image('invoice_3')
   &.special
   bg-image('special_3')
  .text
   display:table-cell
   vertical-align:middle
   width:56px
   border-1px(rgba(7,17,27,0.1))
   font-size:12px
 .food-wrapper
  flex:1
  .title
  padding-left:14px
  font-size:12px
  color:rgb(147,153,159)
  height:26px
  border-left:2px solid #d9dde1
  line-height:26px
  background:#f3f5f7
  .food-item
  display:flex
  margin:18px
  padding-bottom:18px
  border-1px(rgba(7,17,27,0.1))
  &:last-child
   border-none()
   margin-bottom:0
  .icon
   flex:0 0 57px
   margin-right:10px
  .content
   flex:1
   .name
   margin:2px 0 8px 0
   height:14px
   line-height:14px
   font-size:14px
   color:rgb(7,17,27) 
   .desc,.extra
   line-height:10px
   font-size:10px
   color:rgb(147,153,159)
   .desc   
   margin-bottom:8px
   line-height:12px
   .extra
   .count
    margin-right:12px
   .price
   font-weight:700
   line-height:24px
   .now
    margin-right:8px
    font-size:14px
    color:rgb(240,20,20)
   .old
    text-decoration:line-through
    font-size:10px
    color:rgb(147,153,159)
</style>

总结

以上所述是小编给大家介绍的vue.js2.0 实现better-scroll的滚动效果实例详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
JS获取scrollHeight问题想到的标准问题
May 27 Javascript
浏览器常用高宽的jquery插件
Feb 24 Javascript
javascript事件冒泡详解和捕获、阻止方法
Apr 12 Javascript
js实现飞入星星特效代码
Oct 17 Javascript
学习javascript的闭包,原型,和匿名函数之旅
Oct 18 Javascript
node.js+express制作网页计算器
Jan 17 Javascript
Vue响应式添加、修改数组和对象的值
Mar 20 Javascript
详解Vue 普通对象数据更新与 file 对象数据更新
Apr 26 Javascript
elemetUi 组件--el-upload实现上传Excel文件的实例
Oct 27 Javascript
vue2.0+vuex+localStorage代办事项应用实现详解
May 31 Javascript
vue中设置height:100%无效的问题及解决方法
Jul 27 Javascript
微信小程序实现底部弹出框
Nov 18 Javascript
jQuery实现图片简单轮播功能示例
Aug 13 #jQuery
vue.js 实现评价五角星组件的实例代码
Aug 13 #Javascript
Vue.js实现数据响应的方法
Aug 13 #Javascript
jQuery模拟12306城市选择框功能简单实现方法示例
Aug 13 #jQuery
Bootstrap Table实现定时刷新数据的方法
Aug 13 #Javascript
angular2实现统一的http请求头方法
Aug 13 #Javascript
AngularJS发送异步Get/Post请求方法
Aug 13 #Javascript
You might like
将二维数组转为一维数组的2种方法
2014/05/26 PHP
PHP中使用localhost连接Mysql不成功的解决方法
2014/08/20 PHP
PHP简单字符串过滤方法示例
2016/09/04 PHP
浅谈php处理后端&amp;接口访问超时的解决方法
2016/10/29 PHP
js利用Array.splice实现Array的insert/remove
2009/01/13 Javascript
jQuery图片预加载 等比缩放实现代码
2011/10/04 Javascript
剖析Node.js异步编程中的回调与代码设计模式
2016/02/16 Javascript
JQuery解析XML数据的几个简单实例
2016/05/18 Javascript
基于React实现表单数据的添加和删除详解
2017/03/14 Javascript
vue中遇到的坑之变化检测问题(数组相关)
2017/10/13 Javascript
基于webpack.config.js 参数详解
2018/03/20 Javascript
node.js实现带进度条的多文件上传
2020/03/27 Javascript
JavaScript检测浏览器是否支持CSS变量代码实例
2020/04/03 Javascript
vue.js 解决v-model让select默认选中不生效的问题
2020/07/28 Javascript
python中日志logging模块的性能及多进程详解
2017/07/18 Python
Python操作MySQL模拟银行转账
2018/03/12 Python
pandas数据框,统计某列数据对应的个数方法
2018/04/11 Python
Python cookbook(字符串与文本)在字符串的开头或结尾处进行文本匹配操作
2018/04/20 Python
python KNN算法实现鸢尾花数据集分类
2019/10/24 Python
对python中assert、isinstance的用法详解
2019/11/27 Python
Python日志syslog使用原理详解
2020/02/18 Python
jupyter note 实现将数据保存为word
2020/04/14 Python
python 求两个向量的顺时针夹角操作
2021/03/04 Python
Web页面中八种创建多列等高(等高列布局)的实现技术
2012/12/24 HTML / CSS
基于DOM+CSS3实现OrgChart组织结构图插件
2016/03/02 HTML / CSS
Mamas & Papas沙特阿拉伯:英国最受欢迎的婴儿品牌
2017/11/20 全球购物
纽约复古灵感的现代珠宝品牌:Lulu Frost
2018/03/03 全球购物
用C或者C++语言实现SOCKET通信
2015/02/24 面试题
好邻里事迹材料
2014/01/16 职场文书
《小草和大树》教学反思
2014/02/16 职场文书
社区交通安全实施方案
2014/03/22 职场文书
含预算的公司户外活动方案
2014/08/16 职场文书
质量保证书怎么写
2015/02/27 职场文书
导游词之西安大清真寺
2019/12/17 职场文书
Python pygame实现中国象棋单机版源码
2021/06/20 Python
Nginx缓存设置案例详解
2021/09/15 Servers