滚动位置固定:在vue中通过路由切换页面时组件会自动滚动到顶部,需要监听滚动行为才能让滚动位置固定,better-scroll解决了这个问题。

常用效果:移动端很常见的效果,当滑动右边部分的时候,左边会联动显示与当前内容相符合的标题高亮,当点击左边某一个标题的时候,右边会自动滑动到相应的内容。

npm install better-scroll --save

import BScroll from 'better-scroll'

注意使用better-scroll的基本条件

  • 必须包含两个大的div,外层和内层div
  • 外层div设置可视的大小(宽或者高)-有限制宽或高
  • 内层div,包裹整个可以滚动的部分
  • 内层div高度一定大于外层div的宽或高,才能滚动
//创建一个新实例 并且 对class为wrapper对象 实现了一个纵向可点击的滚动效果
let scroll = new BScroll('.wrapper',{
    scrollY: true,
    click: true
})

实现及说明

1.滚动效果

better-scroll在使用的时候需要在dom元素渲染完成之后初始化better-scroll的实例,初始化的时候,先要获取需要滑动的元素,然后在初始化的时候将获取到的元素传递给初始化函数,此时便可实现滑动效果

2.左右联动效果

左右联动效果的实现,是better-scroll通过监听事件实现的。

首先获取到右边内容盒子的高度,然后获取到该盒子中每一项的高度并做前n项高度累加(第n项的高度是前n项的高度和)存储到listHeight数组中。在初始化的时候传递属性probeType=3 (探针的效果,时时获取滚动高度),并给右边的内容盒子对象监听scroll事件,从而时时获取Y轴位置,来与listHeight数组中的数据做比较,时时计算当前的索引值,并给对边对应索引值的项添加背景色高亮,从而实现右边滑动,联动左边。

当点击左边的每一项的时候,获取到当前的索引值,并根据当前的索引值获取到与右边内容盒子中对应索引的元素,右边的盒子元素通过监听scrollToElement,并传递获取到的对应索引元素和动画时间,从而实现点击左边,实现右边联动;

probeType

  • 类型:Number
  • 默认值:0
  • 可选值:1、2、3
  • 作用:有时候我们需要知道滚动的位置。当 probeType 为 1 的时候,会非实时(屏幕滑动超过一定时间后)派发scroll 事件;当 probeType 为 2 的时候,会在屏幕滑动的过程中实时的派发 scroll 事件;当 probeType 为 3 的时候,不仅在屏幕滑动的过程中,而且在 momentum 滚动动画运行过程中实时派发 scroll 事件。
 
 
高级用法
<template>
  <div ref="wrapper">
    <slot></slot>
  </div>
</template>

<script>
import BScroll from 'better-scroll';

export default {

    props: {
      /**
       * 1 滚动的时候会派发scroll事件,会截流。
       * 2 滚动的时候实时派发scroll事件,不会截流。
       * 3 除了实时派发scroll事件,在swipe的情况下仍然能实时派发scroll事件
       */
      probeType: {
        type: Number,
        default: 1
      },
      /**
       * 点击列表是否派发click事件
       */
      click: {
        type: Boolean,
        default: true
      },
      /**
       * 是否开启横向滚动
       */
      scrollX: {
        type: Boolean,
        default: false
      },
      /**
       * 是否派发滚动事件
       */
      listenScroll: {
        type: Boolean,
        default: false
      },
      /**
       * 列表的数据
       */
      data: {
        type: Object,
        default: []
      },
      /**
       * 是否派发滚动到底部的事件,用于上拉加载
       */
      pullup: {
        type: Boolean,
        default: false
      },
      /**
       * 是否派发顶部下拉的事件,用于下拉刷新
       */
      pulldown: {
        type: Boolean,
        default: false
      },
      /**
       * 是否派发列表滚动开始的事件
       */
      beforeScroll: {
        type: Boolean,
        default: false
      },
      /**
       * 当数据更新后,刷新scroll的延时。
       */
      refreshDelay: {
        type: Number,
        default: 20
      }
    },
    mounted() {
      // 保证在DOM渲染完毕后初始化better-scroll
      console.log(this.data);
      setTimeout(() => {
        this._initScroll()
      }, 20)
    },
    methods: {
      _initScroll() {
        if (!this.$refs.wrapper) {
          return
        }
        this.$nextTick(() => {
           if(!this.scroll){
           // better-scroll的初始化
            this.scroll = new BScroll(this.$refs.wrapper, {
              probeType: this.probeType,
              click: this.click,
              scrollX: this.scrollX
            })
          }else{
            this.scroll.refresh();
          }
        })

        // 是否派发滚动事件
        if (this.listenScroll) {
          let me = this
          this.scroll.on('scroll', (pos) => {
            me.$emit('scroll', pos)
            console.log(pos);
          })
        }

        // 是否派发滚动到底部事件,用于上拉加载
        if (this.pullup) {
          this.scroll.on('scrollEnd', () => {
            // 滚动到底部
            if (this.scroll.y <= (this.scroll.maxScrollY + 50)) {
              this.$emit('pullup')
            }
          })
        }

        // 是否派发顶部下拉事件,用于下拉刷新
        if (this.pulldown) {
          this.scroll.on('touchend', (pos) => {
            // 下拉动作
            if (pos.y > 50) {
              this.$emit('pulldown')
            }
          })
        }

        // 是否派发列表滚动开始的事件
        if (this.beforeScroll) {
          this.scroll.on('beforeScrollStart', () => {
            this.$emit('beforeScroll')
          })
        }
      },
      disable() {
        // 代理better-scroll的disable方法
        this.scroll && this.scroll.disable()
      },
      enable() {
        // 代理better-scroll的enable方法
        this.scroll &&this.scroll.enable()
      },
      refresh(){
        // 代理better-scroll的refresh方法
        this.scroll &&this.scroll.refresh()
      },
      scrollTo(){
        // 代理better-scroll的scrollTo方法
        this.scroll &&this.scroll.scrollTo.apply(this.scroll, arguments)
      },
      scrollToElement(){
        // 代理better-scroll的scrollToElement方法
        this.scroll &&this.scroll.scrollToElement.apply(this.scroll, arguments)
      },
    },
    watch:{
        // 监听数据的变化,延时refreshDelay时间后调用refresh方法重新计算,保证滚动效果正常
        data(data){
          console.log(data)
          setTimeout(()=>{this.refresh()},this.refreshDelay)
        }
    }
}
</script>

vue better-scroll用法的更多相关文章

  1. Vue组件基础用法

    前面的话 组件(Component)是Vue.js最强大的功能之一.组件可以扩展HTML元素,封装可重用的代码.根据项目需求,抽象出一些组件,每个组件里包含了展现.功能和样式.每个页面,根据自己所需, ...

  2. checkbox在vue中的用法小结

    关于checkbox多选框是再常见不过的了,几乎很多地方都会用到,这两天在使用vue框架时需要用到checkbox多选功能,实在着实让我头疼,vue和原生checkbox用法不太一样,之前对于vue插 ...

  3. checkbox在vue中的用法总结

    前言 关于checkbox多选框是再常见不过的了,几乎很多地方都会用到,这两天在使用vue框架时需要用到checkbox多选功能,实在着实让我头疼,vue和原生checkbox用法不太一样, 之前对于 ...

  4. Vue slot 插槽用法:自定义列表组件

    Vue 框架的插槽(slot)功能相对于常用的 v-for, v-if 等指令使用频率少得多,但在实现可复用的自定义组件时十分有用.例如,如果经常使用前端组件库的话,就会经常看到类似的用法: < ...

  5. Vue SSR: 基本用法 (二)

    上一篇讲解了ssr的原理,这篇主要讲基本用法: 1.安装 npm install vue vue-server-renderer --save 我们将在整个指南中使用 NPM,但你也可以使用 Yarn ...

  6. cdn模式下vue的基本用法

    我们知道jq是简化了dom操作,而react和vue则是通过使用虚拟dom的方式,不需要频繁的更改ui界面,而是通过更改数据的方式来更新界面. 我们知道些jq插件时会在IFFE中传入jQuery,jQ ...

  7. vue watch详细用法

    在vue中,使用watch来响应数据的变化.watch的用法大致有三种.下面代码是watch的一种简单的用法 html: <input type="text" v-model ...

  8. vue 中scroll事件不触发问题

    在vue项目中需要监听滚动条滚动的位置,结果写了scroll监听事件就是不生效,最后查资料发现是页面有样式设置了over-flow:scroll,去掉之后完美解决.(页面样式中存在over-flow: ...

  9. vue的基本用法

    公共样式---pc版的404报错 动态src 这个是vue组件template部分 <div class="not-found"> <img :src=" ...

  10. vue路由高级用法

    五.路由设置高级用法alias 别名 {path:'/list',component:MyList,alias:'/lists'}redirect 重定向 {path:'/productList',r ...

随机推荐

  1. Linux下对lvm逻辑卷分区大小的调整(针对xfs和ext4不同文件系统)

    当我们在安装系统的时候,由于没有合理分配分区空间,在后续维护过程中,发现有些分区空间不够使用,而有的分区空间却有很多剩余空间.如果这些分区在装系统的时候使用了lvm(前提是这些分区要是lvm逻辑卷分区 ...

  2. 批量修改所有服务器的dbmail配置

    最近遇到这样一个案例,需要修改所有SQL Server的Database Mail的SMTP,原来的SMTP为10.xxx.xxx.xxx, 现在需要修改为192.168.xxx.xxx, 另外需要规 ...

  3. 如何在HTTP客户端与服务器端之间保持状态(转)

    HTTP协议与状态保持 HTTP协议本身是无状态的,这与HTTP协议本来的目的是相符的,客户端只需要简单的向服务器请求下载某些文件,无论是客户端还是服务器都没有必要纪录彼此过去的行为,每一次请求之间都 ...

  4. MyBatis笔记----(2017年)最新的报错:Cannot find class [org.apache.commons.dbcp.BasicDataSource] for bean with name 'dataSource' defined in class path resource [com/ij34/mybatis/applicationContext.xml]; nested e

    四月 05, 2017 4:56:11 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRef ...

  5. 单线程泵问题(com操作时间超过60s报错)

    CLR   无法从   COM   上下文   0x197bf0   转换为   COM   上下文   0x197a80,这种状态已持续   60  秒.拥有目标上下文/单元的线程很有可能执行的是非 ...

  6. MySQL高性能优化实战总结!

    1.1 前言 MySQL对于很多Linux从业者而言,是一个非常棘手的问题,多数情况都是因为对数据库出现问题的情况和处理思路不清晰.在进行MySQL的优化之前必须要了解的就是MySQL的查询过程,很多 ...

  7. Win10 - MySQL-zip安装方法

    Win10 - MySQL-zip安装方法 安装步骤 1.下载,到MySQL官网:https://dev.mysql.com/downloads/mysql/ 2.解压安装包 解压下载的安装包,放到你 ...

  8. Scrapy(爬虫框架)中,Spider类中parse()方法的工作机制

    parse(self,response):当请求url返回网页没有指定回调函数,默认的Request对象的回调函数,用来处理网页返回的response,和生成的Item或者Request对象 以下分析 ...

  9. .gho文件检查

    虽然目前windows10的接受程度越来越广泛,但我接触到的一些非IT人士还是钟爱于windows7系统,本文记录一下在使用ghost还原系统遇到的问题. gho还原失败 在还原ghost系统过程中, ...

  10. Excel 单元格不能设置超链接

    最近在重做系统后  新安装office后 原先的Excel中设置的超链接不能正常使用了  如果新配置的超链接也不能使用 解决方法: 步骤1:打开开始菜单,在运行里输入regedit,回车 步骤2  在 ...