移动端-vue-BScroll用法教程

移动端-vue-BScroll用法教程

  • 简介
  • 官网
  • 安装
  • 使用
  • 移动端滚动使用
  • 移动端联合滚动实现懒加载
      • 页面使用
    • 扩展-什么是防抖和节流
      • 相同点
      • 区别

简介

BetterScroll 是一款重点解决移动端(已支持 PC)各种滚动场景需求的插件,是最接近与原生的滚动插件,兼容pc和移动端。

官网

https://better-scroll.github.io/docs/zh-CN/

安装

npm install better-scroll --save

使用

import BScroll from "better-scroll";let bs = new BScroll('.wrapper', {scrollbar: true,//是否显示滚动条bounce: true, //回弹动画click: true,//派发点击事件scrollX: false, //是否横向滚动
})bs.on("pullingDown", async () => {//下拉刷新      //当使用监听事件下拉刷新,但是pullingDown回调完函数,要在最后添加finishPullDown(); // 作用是事情做完,需要调用此方法告诉    better-scroll 数据已加载,否则下拉事件只会执行一次bs.finishPullDown();bs&& bs.refresh(); //重新计算 BetterScroll});bs.on("pullingUp", async () => {//上拉加载//上拉同理与下拉,否则上拉事件只会执行一次。bs.finishPullUp();bs&&bs.refresh(); //重新计算 BetterScroll});

移动端滚动使用

<template><divclass="scroll"ref="scrollRef"><div class="scroll-wrap"><divclass="pulldown"v-if="pullDownRefresh"><div v-show="beforePullDown"><span>继续下拉以刷新</span></div><div v-show="!beforePullDown"><div v-show="isPullingDown"><span>加载中</span></div><div v-show="!isPullingDown"><span>加载完成</span></div></div></div><slot></slot><divclass="pullup"v-if="pullUpRefresh"><divv-if="!isPullUpLoad && !loading"class="before-trigger"><span class="pullup-txt">{{ finished ? "暂无更多数据" : "上拉加载更多数据" }}</span></div><divv-elseclass="after-trigger"><span class="pullup-txt">加载中...</span></div></div></div></div>
</template><script lang="ts">
import { defineComponent, ref, onMounted, nextTick, watch } from "vue";
import BScroll from "better-scroll";export default defineComponent({name: "BetterScroll",props: {loading: {//加载type: Boolean,default: false,},refresh: {//是否刷新type: Boolean,default: false,},pullDownRefresh: {//是否下拉加载type: Boolean,default: false,},downRefresh: {//下拉加载方法type: Function,default: async () => {},},pullUpRefresh: {//是否上拉刷新type: Boolean,default: false,},upRefresh: {//上拉刷新方法type: Function,default: async () => {},},scrollX: {// 是否横向滚动type: Boolean,default: false,},finished: {// 是否滚动到底-数据加载完成type: Boolean,default: false,},bounce: {// 是否需要回弹动画 当滚动超过边缘的时候会有一小段回弹动画type: Boolean,default: true,},},setup(props, context) {const scrollRef = ref<HTMLElement | null>(null); //滚动父盒子const bs = ref<BScroll | null>(null); //滚动值const beforePullDown = ref(true); //显示继续下拉以刷新const isPullingDown = ref(false); //显示下拉加载中const isPullUpLoad = ref(false); //显示上拉加载中watch(() => props.refresh,async () => {if (props.refresh) {await nextTick(); //视图更新后setTimeout(() => {bs.value && bs.value.refresh();// 新查询数据后重新计算 BetterScroll}, 500);context.emit("update:refresh", false);// 将refresh状态改变 达到监听refresh的目的 为了重新计算BetterScroll}});// 完成下拉事件const finishPullDown = async () => {if (bs.value) {//当使用监听事件下拉刷新,但是pullingDown回调完函数,要在最后添加finishPullDown();// 作用是事情做完,需要调用此方法告诉    better-scroll 数据已加载,否则下拉事件只会执行一次bs.value.finishPullDown();bs.value && bs.value.refresh();setTimeout(() => {beforePullDown.value = true; //数据加载完成,显示初始上拉已刷新}, 100);}};onMounted(() => {if (scrollRef.value) {//Record的内部定义,接收两个泛型参数;Record后面的泛型就是对象键和值的类型//作用 :定义一个对象的 key 和 value 类型const options: Record<string, any> = {scrollbar: true, //是否展示滚动条bounce: props.bounce, //回弹动画click: true, //单独点击事件scrollX: props.scrollX, //当设置为 true 的时候,可以开启横向滚动。};if (props.pullDownRefresh) {// 当顶部下拉距离超过阈值 pullDownRefresh为true 执行pullingDown事件options.pullDownRefresh = true;}if (props.pullUpRefresh) {//当底部下拉距离超过阈值 pullUpLoad为true 执行pullingUp事件options.pullUpLoad = true;}bs.value = new BScroll(scrollRef.value, options); //创建实例bs.value.on("pullingDown", async () => {if (!props.pullDownRefresh) {//pullDownRefresh值为false 则不执行return;}beforePullDown.value = false; //显示加载中/加载完成isPullingDown.value = true; //加载中await props.downRefresh(); //下拉刷新数据 初始化数据isPullingDown.value = false; //加载完成finishPullDown();});bs.value.on("pullingUp", async () => {if (props.finished || !props.pullUpRefresh) {// 如果数据已加载完成,或pullUpRefresh为false 则不执行该事件return;}isPullUpLoad.value = true; //显示上拉加载await props.upRefresh(); //上拉获取数据if (bs.value) {//当使用监听事件下拉刷新,但是pullingUp回调完函数,要在最后添加finishPullUp();// 作用是事情做完,需要调用此方法告诉better-scroll 数据已加载,否则上拉事件只会执行一次bs.value.finishPullUp();bs.value.refresh();}isPullUpLoad.value = false;});}});return {scrollRef,isPullingDown,isPullUpLoad,beforePullDown,};},
});
</script><style lang="less" scoped>
.scroll {overflow: hidden;width: 100%;height: 100%;position: relative;z-index: 2;
}
.pulldown {position: absolute;width: 100%;padding: 20px;box-sizing: border-box;transform: translateY(-100%) translateZ(0);text-align: center;color: #999;
}
.pullup {padding: 20px;text-align: center;color: #999;
}
</style>

移动端联合滚动实现懒加载

<!-- loading:加载pullDownRefresh:是否下拉刷新pullUpRefresh:是否上拉加载refresh:是否改变刷新状态-用于强制重新计算BetterScroll值finished:是否完成状态downRefresh:下拉刷新事件-分页为一upRefresh:上拉加载事件-分页加一--><template><better-scroll:loading="loading":pullDownRefresh="true":pullUpRefresh="true"v-model:refresh="isRefresh":finished="finished":downRefresh="downRefresh":upRefresh="upRefresh"><templatev-for="(item, index) in data":key="index"><slotname="content":data="item":index="index"></slot></template></better-scroll>
</template><script lang="ts">
import { defineComponent, ref, watch, reactive, computed, SetupContext } from "vue";
import betterScroll from "./betterScroll.vue";
interface PropsType {order: string;apiService: (query: any, url?: string) => Promise<any>;query: object;refresh: boolean;
}interface PageQueryType {currentPage: number;pageSize: number;
}export default defineComponent({name: "scrollList",components: {betterScroll,},props: {// 数据调用接口apiService: {type: Function,default: new Promise(() => {}),},// 传参query: {type: [Object, Array],default: () => {},},// 是否更新BetterScroll位置refresh: {type: Boolean,default: false,},// 排序字段orderBy: {type: String,default: "captureDate",},},setup(props, context) {const { data, isRefresh, finished, downRefresh, upRefresh } = useSearch(props, context);return {data,isRefresh,finished,upRefresh,downRefresh,};},
});// 搜索
function useSearch(props: PropsType, context: SetupContext) {//context:SetupContext,即是setup函数的上下文 用于获取propsconst page = reactive<PageQueryType>({currentPage: 1,pageSize: 10,}); //初始化分页const data = ref([]); //数据const totalNum = ref<Nullable<number>>(null); //数据总条数const finished = computed(() => {return totalNum.value !== null ? data.value.length >= totalNum.value : false;}); //通过数据长度和总数据条数判断是否加载完const queryTimer = ref<Nullable<NodeJS.Timer>>(null);watch(() => props.query, //监听到查询条件async () => {isRefresh.value = true; //isRefresh设为true 因为有查询条件会重新加载数据 需要重新计算BetterScroll 使数据回到顶部位置// 采用防抖执行下拉刷新事件 多次快速查询只触发最后一个事件if (queryTimer.value) {clearTimeout(queryTimer.value);queryTimer.value = null;}queryTimer.value = setTimeout(async () => {data.value = [];await downRefresh();}, 50);},{deep: true,});watch(() => props.refresh,async () => {isRefresh.value = true;if (props.refresh) {data.value = [];context.emit("update:refresh", false);await downRefresh();}});// 下拉刷新事件const downRefresh = async () => {page.currentPage = 1;totalNum.value = null;data.value = await getData(props.query);return finished.value; //重新更新finished状态};// 上拉加载事件const upRefresh = async () => {page.currentPage += 1;const resData = await getData(props.query);data.value = data.value.concat(resData);return finished.value; //重新更新finished状态};const isRefresh = ref(false);// 获取数据const getData = async (query: object) => {try {const { data, total } = await props.apiService({...page,...query,});totalNum.value = total;isRefresh.value = true;return data || [];} catch (e) {totalNum.value = 0;isRefresh.value = true;return [];}};queryTimer.value = setTimeout(async () => {downRefresh();}, 50);return {data,isRefresh,finished,upRefresh,downRefresh,};
}
</script><style lang="less" scoped>
.scroll {height: 100%;
}
</style>

页面使用

import scrollList from "./scrollList.vue";
....
<scroll-list:apiService="请求方法":query="query"><template #content="{ data }"><!-- 内容们 --></template><scroll-list>

扩展-什么是防抖和节流

相同点

防抖和节流都是为了阻止操作高频触发,从而浪费性能。

区别

// 防抖是触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。
//适用于可以多次触发但触发只生效最后一次的场景。
//如王者的回城,在回城中途可能会被频繁打断,但是只有经历完整5s,也就是最后一次能够回城成功。
function debounce(fn, delay){let timer = null;return function(){clearTimeout(timer);timer = setTimeout(()=> {fn.apply(this, arguments);}, delay)}
}
//节流是高频事件触发,但在n秒内只会执行一次,如果n秒内触发多次函数,只有一次生效,节流会稀释函数的执行频率
//适用于可以在一段时间内触发只生效一次的场景。
//如王者每一个英雄在使用一个技能后,该技能都会有一个固定的冷却时间。冷却时间过后即可再次使用。在技能冷却时间,无论我们连续点击多少次都不会触发技能,而该技能只在单位时间内触发一次。
function throttling(fn, delay) {let timer = null;return (n) => {if (!timer) {timer = setTimeout(() => {fn.call(this, n);clearTimeout(timer)timer = null;}, delay)}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/600675.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

51单片机定时/计数器相关知识点

51单片机定时/计数器相关知识点 结构组成 51单片机的定时/计数器中有两个寄存器&#xff1a; T0&#xff1a;低位&#xff1a;TL0&#xff08;字节地址8AH&#xff09;高位&#xff1a;TH0&#xff08;字节地址8CH&#xff09;T1&#xff1a;低位&#xff1a;TL1&#xff08…

【教学类-综合练习-03】20231214 大3班 数字加减法练习(数字火车、X—Y加法减法、X乘法、X—Y数字分合)

第二次来大3班投放综合学具 第二次做综合题&#xff0c;大3班孩子选择的内容就跟更多了 今天高手没有来&#xff0c;每人能做“加减乘”

vue封装组件(一)标签和下拉框组合实现添加数据

背景: 最近接入短剧内容&#xff0c;需要添加短剧合作方。在详情页需要支持添加组件 方案一&#xff1a;标签tag加上输入框实现添加数据。图片见下 这个是刚开始做的&#xff0c;后来产品觉得这样会造成随意修改数据&#xff0c;需要改成下拉框形式添加 方案二&#xff1a;标签…

算法每日一题:在链表中插入最大公约数 | 链表 | 最大公约数

hello&#xff0c;大家好&#xff0c;我是星恒 今天的题目是有关链表和最大公约数的题目&#xff0c;比较简单&#xff0c;核心在于求解最大公约数&#xff0c;我们题解中使用辗转相除法来求解&#xff0c;然后我们会在最后给大家拓展一下求解最大公约数的四个方法&#xff0c;…

vue3学习 【2】vite起步和开发工具基本配置

vite的简介 官方文档 刚起步学习&#xff0c;所以我们只需要按照官方文档的入门流程即可。推荐阅读一下官网的为什么使用vite vite目前需要的node版本是18&#xff0c;可以参考上一篇文章的安装nvm&#xff0c;用来进行多版本的node管理。 vite安装与使用 npm create vitela…

Android两个APP之间跳转+手机图标修改

APP之间跳转 两个APP之间跳转同样使用Intent进行跳转&#xff0c;将需要跳转的APP都下载到手机中&#xff0c;通过主APP调用需要跳转的APP包名进行跳转。 最好在其中加上try-catch语句&#xff0c;当需要跳转的APP不存在时进行错误抓取。 代码如下&#xff1a; Intent mInten…

MySQL索引简介(包含索引优化,索引失效,最左前缀简洁版)

一、索引的基本概念 1.什么是索引 索引是一种数据结构&#xff0c;用于快速查找和访问数据库中的数据。它类似于书本的目录&#xff0c;可以帮助数据库管理系统快速定位到存储数据的位置。通过创建索引&#xff0c;我们可以加快数据库的查询速度并提高系统的性能。索引可以基于…

Notepad++ v7.7.1 安装及添加插件

1、notepad_v7.7.1.zip npp.7.7.1.Installer.x64.exe npp.7.7.1.Installer.x86.exe notepad_v7.7.1.ziphttps://www.123pan.com/s/VTMXjv-X6H6v.html 2、notepad插件包_64bit_4.zip ComparePlugin ---->文件对比插件 ComparePlugin.dllNppFTP ---->FTP、FTPES和SFTP …

苹果Mac图像修图软件Photomator和Pixelmator Pro 有什么区别?

同为一个团队设计的Mac修图软件Photomator和Pixelmator Pro有哪些区别呢&#xff1f;有哪些不一样的功能&#xff1f; Photomator和Pixelmator Pro区别如下&#xff1a; 1、用途不同 Photomator 和 Pixelmator Pro 是两个功能强大的应用程序&#xff0c;具有两个不同的用途。…

第8课 将推流端与播放端合并为一对一音视频聊天功能

在第二章的第7课&#xff0c;我们实现了一个推流端&#xff0c;可以把音视频推送到rtmp服务器&#xff1b;在第一章的第4课&#xff0c;我们实现了一个播放器&#xff0c;可以正常播放rtmp音视频流。聪明的你应该可以想到了&#xff1a;把推流端和播放端合并在一起&#xff0c;…

宋仕强论道之华强北的劣势(十八)

华强北微观上的劣势。华强北的企业同质化严重&#xff0c;经营策略和定价方式都差不多&#xff0c;内卷现象突出&#xff0c;价格战、恶性竞争频发&#xff0c;小企业利润空间不断被挤压。如华强北的手机配件市场&#xff0c;很多商户销售相同品牌、相同型号的手机壳、充电器、…

10款以上开源工具,用于大型语言模型应用开发

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

intersection observer实现图片懒加载

图片懒加载&#xff08;Lazy Load&#xff09;是一种优化网页性能的技术&#xff0c;它可以延迟图片的加载时间&#xff0c;只有当用户滚动到该图片的位置时才会进行加载。这样可以减少页面的初始加载时间&#xff0c;提高页面的响应速度和用户体验。 以下是使用浏览器原生支持…

skimage图像处理(全)

文章目录 一、简介二、安装三、模块简介&#xff1a;API reference四、项目实战4.1、2D图像处理4.1.1、打印图像属性4.1.2、读取 / 显示 / 保存图像&#xff1a;skimage.io.imread() skimage.io.imshow() skimage.io.imsave()4.1.3、颜色空间转换&#xff1a;skimage.color.r…

LeetCode2807. Insert Greatest Common Divisors in Linked List

文章目录 一、题目二、题解 一、题目 Given the head of a linked list head, in which each node contains an integer value. Between every pair of adjacent nodes, insert a new node with a value equal to the greatest common divisor of them. Return the linked l…

2401d,d理解模板映射

原文 关于映射带模板参数的函数,我惊讶地发现它仍可同运行时确定的函数,甚至是闭包等工作.我想理解它背后的机制. 注释掉的行会导致错误,即编译时无法确定choice(funcs),这是公平的,但它为何与上面两行的func不一样?我猜是因为函数在编译时是可见的字面,但闭包使这可疑. impo…

Python画草莓熊

前言 今天&#xff0c;我们来画草莓熊。 一、草莓熊 草莓熊&#xff0c;英文名Lotso&#xff0c;迪士尼公司和皮克斯动画工作室公司于2010年合作推出的动画片《玩具总动员3》(Toy Story3)的反派角色。Lotso就是大受欢迎的反派"草莓熊"--这是一个特殊的角色&#x…

C#的StringBuilder方法

一、StringBuilder方法 StringBuilder方法Append()向此实例追加指定对象的字符串表示形式。AppendFormat()向此实例追加通过处理复合格式字符串&#xff08;包含零个或更多格式项&#xff09;而返回的字符串。 每个格式项都由相应的对象自变量的字符串表示形式替换。AppendJoi…

计算机二级Python选择题考点——公共基础部分

计算机完成一条指令所花费的时间称为一个指令周期。(指令周期越短&#xff0c;指令执行就越快)顺序程序不具有并发性。(具有顺序性、封闭性和可再现性)结构化程序设计强调程序的易读性。系统软件&#xff1a;操作系统、编译程序、数据库管理系统 应用软件&#xff1a;杀毒软件在…

设置docker容器的时区

目录 基于Alpine镜像的Docker容器的Dockerfile中 基于dpkg包管理且使用APT的Linux发行版镜像的docker容器的Dockerfile中 基于Alpine镜像的Docker容器的Dockerfile中 # 替换国内源&#xff0c;可按需添加 RUN set -eux && sed -i s/dl-cdn.alpinelinux.org/mirrors.…