vue遇见better-scroll

better-scroll

better-scroll 是一款重点解决移动端(现已支持 PC 端)各种滚动场景需求的插件。它的核心是借鉴的 iscroll 的实现,它的 API 设计基本兼容 iscroll,在 iscroll 的基础上又扩展了一些 feature 以及做了一些性能优化。

better-scroll 是基于原生 JS 实现的,不依赖任何框架。它编译后的代码大小是 63kb,压缩后是 35kb,gzip 后仅有 9kb,是一款非常轻量的 JS lib。

GIT地址:https://github.com/ustbhuangyi/better-scroll

 

 

文档用法

HTML

<div class="wrapper">
  <ul class="content">
    <li>...</li>
    <li>...</li>
    ...
  </ul>
  <!-- 这里可以放一些其它的 DOM,但不会影响滚动 -->
</div>

上面的代码中 better-scroll 是作用在外层 wrapper 容器上的,滚动的部分是 content 元素。这里要注意的是,better-scroll 只处理容器(wrapper)的第一个子元素(content)的滚动,其它的元素都会被忽略。

JS

import BScroll from 'better-scroll'
const wrapper = document.querySelector('.wrapper')
const scroll = new BScroll(wrapper)

脑壳疼。。我按照文档上的方法试了一下,发现不行,可能是其他地方影响到了。下次再试下

 

未调用data.json的用法

这时候数据未加载

HTML

<template>
    <div class="seller" ref="seller">
      <div class="seller-content">
         内容.......
      </div>
    </div>
</template>

JS

import BScroll from 'better-scroll'
export default {
  created () {
    this.$nextTick(() => {
      this.scroll = new BScroll(this.$refs.seller, {
        click: true
      })
    })    
  }    
}

这个还是有问题。。。刷新的时候加载没有反应,但是没效果。。考虑应该是数据未加载

 

调用data.json的用法

数据已加载

HTML

<template>
    <div class="seller" ref="seller">
      <div class="seller-content">
         内容.......
      </div>
    </div>
</template>

JS

export default {
  created () {
    this.$http.get('/api/seller').then((response) => {
      response = response.body
      if (response.errno === 0) {
        // this.seller = response.data
        this.$nextTick(() => {
          this.scroll = new BScroll(this.$refs.seller, {
            click: true
          })
        })
      }
    })
  }
}

这样等数据响应以后再调用,就灵性了很多

水平滑动

this.picScroll = new BScroll(this.$refs.picWrapper, {
              // 允许点击事件
              click: true,
              // 水平滚动
              scrollX: true,
              // eventPassthrough: 'vertical'
})

 

 

 

左右联动滚动

左右菜单滚动时联动,并且点击左边右边滚动到相应位置  

 

点击按钮滚动到指定位置

例,点击按钮在300毫秒内滚动到指定位置

let el = document.getElementsByClassName('right-list')
this.scroll_right.scrollToElement(el[8], 300)

HTML
<button @click="abc">abc</button>
JS
created () {
    this.$nextTick(() => {
      this.scroll_right = new BScroll(this.$refs.hc_right, {
        click: true
      })
    })
  },
  methods: {
    abc () {
      let el = document.getElementsByClassName('right-list')
      this.scroll_right.scrollToElement(el[8], 300)
    }
  }

 

获取滚动时的Y值

<div class="hc-right" ref="hc_right">
      <ul>
        <li class="right-list" v-for="(number,index) of num" v-bind:key="index">{{number}}{{number}}</li>
      </ul>
</div>

 

created () {
    this.$nextTick(() => {
      this.scroll_right = new BScroll(this.$refs.hc_right, {
        // 允许执行点击事件
        click: true,
        // 滚动的探针---加了这个才能在滚动时获取到数据
        probeType: 3
      })
      // 右侧滚动时获取到Y值
      this.scroll_right.on('scroll', (pos) => {
        this.scrollY = Math.abs(Math.round(pos.y))
      })
    })
  },

 

 

全部代码

左右侧联动。

点击左边,右边滑动到对应位置。

滑动右边,左边滚动到对应位置。

原理:左右侧对应的index值是一样的,滚动时保持index值相同。

这里有个问题就是,如果右侧的内容高度太低,就会使得左侧无法拉倒最下面,因为未达到最下面的选项,右侧已经显示出了内容。

 

效果-----

 

HTML-----

<template>
  <div class="hello">
    <div class="hc-left" ref="hc_left">
      <ul>
        <li class="left-list" :class="{'current':current == index}" v-for="(number,index) of num" @click="clickMove(index)" v-bind:key="index">{{number}}</li>
      </ul>
    </div>
    <div class="hc-right" ref="hc_right">
      <ul>
        <li class="right-list" v-for="(number,index) of num" v-bind:key="index">{{number}}{{number}}</li>
      </ul>
    </div>
  </div>
</template>

JS-----

<script>
import BScroll from 'better-scroll'
export default {
  data () {
    return {
      num: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],
      // 高度数组
      heightArr: [],
      // 速度
      speed: 300,
      // 当前index
      current: 0
    }
  },
  created () {
    this.$nextTick(() => {
      this.scroll_left = new BScroll(this.$refs.hc_left, {
        // 允许执行点击事件
        click: true
      })
      this.scroll_right = new BScroll(this.$refs.hc_right, {
        // 允许执行点击事件
        click: true,
        // 滚动的探针---加了这个才能在滚动时获取到数据
        probeType: 3
      })
      // 右侧滚动时获取到Y值
      this.scroll_right.on('scroll', (pos) => {
        // 取整的绝对值
        this.scrollY = Math.abs(Math.round(pos.y))
        let i = 0
        let el = document.getElementsByClassName('left-list')
        // 比较数组大小,得出对应的index
        for (i; i < this.heightArr.length; i++) {
          // 当大于时则跳出循环
          if (this.scrollY < this.heightArr[i]) {
            // 跳出循环
            break
          }
        }
        // 左侧滚动到与右侧对应的位置
        this.scroll_left.scrollToElement(el[i],this.speed)
        this.current = i
      })
      // 调用右侧的高度数组
      this._calculateHeight()
    })
  },
  methods: {
    // 点击左侧跳转到对应位置
    clickMove (index) {
      let el = document.getElementsByClassName('right-list')
      this.scroll_right.scrollToElement(el[index], this.speed)
      this.current = index
    },
    // 计算右侧的高度数组
    _calculateHeight () {
      let el = document.getElementsByClassName('right-list')
      let heightAll = 0
      for (let i = 0; i < el.length; i++) {
        heightAll = heightAll + el[i].clientHeight
        this.heightArr.push(heightAll)
      }
    }
  }
}
</script>

CSS----

<style scoped>
.hello{
  position: absolute;
  top: 174px;
  left: 0;
  bottom: 0;
  width: 100%;
  display: flex;
  overflow: hidden;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  width: 100%;
  line-height: 60px;
  border: 1px solid red;
  text-align: center
}
a {
  color: #42b983;
}
.hello-content{
  display: flex;
}
.hc-left{
  width: 100px;
  flex: 0 0 100px
}
.hc-right{
  flex: 1
}
.hc-right li{
  line-height: 100px
}
.right-list:nth-child(2n+1){
  line-height: 200px
}
.hc-left .current{
  background-color: red;
  color: white;
}
</style>

 

posted @ 2018-08-20 16:45  泠风lj  阅读(305)  评论(0编辑  收藏  举报