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>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了