使用BetterScroll封装页面滚动及轮播图组件(一文入门移动端页面滚动神器BetterScroll)

使用BetterScroll封装页面滚动及轮播图组件(一文入门移动端页面滚动神器BetterScroll)目录 一 轮播图组件的封装 1 安装 BeterScroll 及 Slide 插件 2 新建 slide vue 文件 3 前往官网复制一个示例 做一个小 demo 4 钩子函数的应用 二 滚动组件的封装 1 新建 scroll 组件 2 初始化 BetterScroll 3 添加属性 3

大家好,我是讯享网,很高兴认识大家。

目录

一、轮播图组件的封装

1. 安装 BeterScroll 及 Slide 插件

2. 新建 slide.vue 文件

3. 前往官网复制一个示例,做一个小 demo

4. 钩子函数的应用

二、滚动组件的封装

1. 新建 scroll 组件

2. 初始化BetterScroll

3. 添加属性

3. 安装并引入observe-dom


一、轮播图组件的封装

1. 安装 BeterScroll 及 Slide 插件

npm install @better-scroll/core --save // or yarn add @better-scroll/core

讯享网
讯享网npm install @better-scroll/slide --save // or yarn add @better-scroll/slide

 这样就表示我们安装完成:


讯享网

2. 新建 slide.vue 文件

在 components 目录下新建 slide/slide.vue 来编写轮播图相关代码

3. 前往官网复制一个示例,做一个小 demo

下面是 slide.vue 的代码:

<template> <div class="slider" ref="rootRef"> <div class="slider-group"> <div class="slider-page" v-for="item in sliders" :key="item.id" > <img :src="item.pic"/> </div> </div> <div class="dots-wrapper"> <span class="dot" v-for="(item, index) in sliders" :key="item.id" :class="{'active': currentPageIndex === index}"> </span> </div> </div> </template> <script> import BScroll from '@better-scroll/core' import Slide from '@better-scroll/slide' import { onMounted, onUnmounted, onActivated, onDeactivated, ref } from 'vue' BScroll.use(Slide) export default { name: 'slider', props: { sliders: { type: Array, default() { return [] } } }, setup(props) { const rootRef = ref(null) const slider = ref(null) const currentPageIndex = ref(0) onMounted(() => { const sliderVal = slider.value = new BScroll(rootRef.value, { click: true, scrollX: true, scrollY: false, momentum: false, bounce: false, probeType: 2, slide: true }) sliderVal.on('slideWillChange', (page) => { currentPageIndex.value = page.pageX }) }) onUnmounted(() => { slider.value.destroy() }) onActivated(() => { slider.value.enable() slider.value.refresh() }) onDeactivated(() => { slider.value.disable() }) return { slider, currentPageIndex, rootRef } } } </script> <style lang="less" scoped> .slider { position :relative; .slider-group { position: relative; overflow: hidden; white-space: nowrap; .slider-page { display: inline-block; transform: translate3d(0, 0, 0); backface-visibility: hidden; a { display: block; width: 100%; } img { display: block; width: 100%; } } } .dots-wrapper { position: absolute; left: 50%; bottom: 12px; line-height: 12px; transform: translateX(-50%); .dot { display: inline-block; margin: 0 4px; width: 8px; height: 8px; border-radius: 50%; background: rgba(255, 255, 255, 0.5); &.active { width: 20px; border-radius: 5px; background:rgba(255, 255, 255, 0.8); } } } } </style> 

轮播的信息通过 props 从父组件传递过来,下面是父组件的代码:

讯享网<template> <header>头部</header> <div> <slide :sliders="list"></slide> </div> </template> <script> import slide from '../components/slider/slider.vue' import { ref } from 'vue' export default { name: 'HomeView', components: { slide }, setup () { const list = ref([ { id: 1, pic: "https://7463-tcb-tjpv7cz5f6ef80-7dw7b0b-.tcb.qcloud.la/swiper/havetea.png" }, { id: 2, pic: "https://7463-tcb-tjpv7cz5f6ef80-7dw7b0b-.tcb.qcloud.la/swiper/谨防诈骗.png" }, { id: 3, pic: "https://7463-tcb-tjpv7cz5f6ef80-7dw7b0b-.tcb.qcloud.la/swiper/首页轮播1.png" } ]) return { list } }, } </script> <style lang="less" scoped> header { height: 30px; width: 100%; background-color: pink; } </style>

启动项目,看一下我们的轮播图:

4. 钩子函数的应用

下面我们再使用 composition api 的方式创建一个钩子函数,把 new slide 的逻辑抽离出去:

我们定义了一个 useSlider 函数,他传入的参数是轮播图的容器,这个是 betterScroll 必须的,返回的是当前页的索引值,下面我们看一下 use-slider.js 的代码:

import { onMounted, onUnmounted, onActivated, onDeactivated, ref } from 'vue' import BScroll from '@better-scroll/core' import Slide from '@better-scroll/slide' BScroll.use(Slide) export default function useSlider(wrapperRef) { const slider = ref(null) const currentPageIndex = ref(0) onMounted(() => { const sliderVal = slider.value = new BScroll(wrapperRef.value, { click: true, scrollX: true, scrollY: false, momentum: false, bounce: false, probeType: 2, slide: true }) sliderVal.on('slideWillChange', (page) => { currentPageIndex.value = page.pageX }) }) onUnmounted(() => { slider.value.destroy() }) onActivated(() => { slider.value.enable() slider.value.refresh() }) onDeactivated(() => { slider.value.disable() }) return { slider, currentPageIndex } }

然后再看一下现在 slider.vue 的代码,就会感受到 composition api 的强大之处了:

讯享网import { ref } from 'vue' import useSlider from './use-slider' export default { name: 'slider', props: { sliders: { type: Array, default() { return [] } } }, setup() { const rootRef = ref(null) const { currentPageIndex } = useSlider(rootRef) return { rootRef, currentPageIndex } } }

这样处理之后,useSlider 函数只跟 slide 轮播图的创建有关,主逻辑部分很清晰。

二、滚动组件的封装

在我们移动端的开发中经常会遇到滚动列表的场景,此时我们用原生的滚动效果是没有回弹及一些其他对交互很友好的动画效果的,类似于这样:

同样借助于 BetterScroll 我们可以轻松的封装一个自己的滚动组件来实现移动端下顺滑的滚动体验

1. 新建 scroll 组件

在 components 目录下新建 scroll / scroll.vue 文件,它的实现非常简单:

<template> <div ref="rootRef"> <slot></slot> </div> </template> <script> export default { name: 'scroll' } </script>

滚动的内容部分我们就放在 slot 插槽中,然后在外层的 div 盒子中通过 BetterScroll 做一些初始化的联动,让内容部分实现滚动。

2. 初始化BetterScroll

和上一讲的 slider 组件一样,我们使用 composition api 和 钩子函数的方式来和 BetterScroll 做初始化,所以我们新建 use-scroll.js 文件,代码如下所示

讯享网import BScroll from '@better-scroll/core' import { onMounted, onUnmounted, ref } from 'vue' BScroll.use(ObserveDOM) export default function useScroll(wrapperRef) { const scroll = ref(null) onMounted(() => { scroll.value = new BScroll(wrapperRef.value) onUnmounted(() => { scroll.value.destroy() }) }

这里的 wrapperRef 就是最外层的 dom ,我们通过 ref 获取他然后作为参数传进来,下一步我们在 scroll 中引入这个钩子函数:

<template> <div ref="rootRef"> <slot></slot> </div> </template> <script> import useScroll from './use-scroll' import { ref } from 'vue' export default { name: 'scroll', setup() { const rootRef = ref(null) const scroll = useScroll(rootRef) return { rootRef } } } </script>

这样我们简单的 scroll 组件就实现了

3. 添加属性

因为 BetterScroll 是支持我们添加很多自定义属性和事件的,比如在官网中可以定义 click 点击事件,它的默认值是 false:

现在我们就给我们的滚动组件添加这个 click 事件,这里的 click 我们想实现自定义配置就应该从使用 scroll 组件的父级传进来,那我们通过 props 接收他就好,然后把 props 作为参数传给需要用到他的钩子函数,这样不论 props 中添加了什么新的属性,钩子函数中都能获取到,因为都包含在 props 中,修改 scroll.vue 代码如下:

讯享网<template> <div ref="rootRef"> <slot></slot> </div> </template> <script> import useScroll from './use-scroll' import { ref } from 'vue' export default { name: 'scroll', props: { click: { type: Boolean, default: true } setup(props) { const rootRef = ref(null) useScroll(rootRef, props, emit) return { rootRef } } } </script>

值得注意的是, scroll 组件只对第一个子节点生效,这也是 BeterScroll 的特性。

如果 BetterScroll 的时候,并没有实现滚动,可以看一下文档中的滚动原理

BetterScroll 判断滚动是在初始化的时候就进行判断,也就是在 new BScroll 的时候进行计算,如果我们在 created 的时候获取列表数据,那显然很有可能我们在数据还没有获取的时候,BetterScroll 已经计算完了,这样页面就滚动不了。

解决这个问题的方法就是 BetterScroll 的一个插件:observe-dom:

这样当 我们的 dom 发生变化时,BetterScroll就能自动感知然后执行刷新操作。

3. 安装并引入observe-dom

npm install @better-scroll/observe-dom --save // or yarn add @better-scroll/observe-dom

 use-scroll.vue:

讯享网import BScroll from '@better-scroll/core' import ObserveDOM from '@better-scroll/observe-dom' import { onMounted, onUnmounted, ref } from 'vue' BScroll.use(ObserveDOM) export default function useScroll(wrapperRef, options) { const scroll = ref(null) onMounted(() => { scroll.value = new BScroll(wrapperRef.value, { observeDOM: true, ...options }) onUnmounted(() => { scroll.value.destroy() }) }

我们试一下使用 scroll.vue 组件后的滚动列表的效果,下面是 Home.vue 的代码:

<template> <div style="position:relative;"> <div class="head">固定的头部</div> <div class="main"> <scroll class="theScroll"> <div> <div v-for="(i,index) in 10" :key="index" style="margin:10px 0"> <van-card num="2" price="2.00" desc="描述信息" title="商品标题" thumb="https://fastly.jsdelivr.net/npm/@vant/assets/ipad.jpeg" /> </div> </div> </scroll> </div> </div> </template> <script> import slide from '../components/slider/slider.vue' import scroll from '../components/scroll/scroll.vue' import { ref } from 'vue' export default { name: 'HomeView', components: { slide, scroll }, setup () { const list = ref([ { id: 1, pic: "https://7463-tcb-tjpv7cz5f6ef80-7dw7b0b-.tcb.qcloud.la/swiper/havetea.png" }, { id: 2, pic: "https://7463-tcb-tjpv7cz5f6ef80-7dw7b0b-.tcb.qcloud.la/swiper/谨防诈骗.png" }, { id: 3, pic: "https://7463-tcb-tjpv7cz5f6ef80-7dw7b0b-.tcb.qcloud.la/swiper/首页轮播1.png" } ]) return { list } }, } </script> <style lang="less" scoped> .head { position: fixed; top: 0; left: 0; height: 50px; width: 100%; background-color: pink; z-index: 999; } .main { position: fixed; top: 50px; bottom: 0; left: 0; right: 0; background-color: rgb(232, 234, 235); .theScroll { height: 100%; overflow: hidden; } } </style>

启动项目,查看效果:

现在我们就实现了带回弹效果的这样顺滑的滚动了。 

小讯
上一篇 2025-01-23 19:04
下一篇 2025-03-23 16:55

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/35907.html