当前位置: 首页 > news >正文

uniapp scroll-view解析

1. uniapp scroll-view解析

      <scroll-viewscroll-ystyle="width: 100%; height: 100%"refresher-enabled:refresher-triggered="triggered"@scrolltolower="onreachBottom"@refresherrefresh="refresherrefresh()"@refresherrestore="refresherrestore()"@refresherabort="refresherabort()"></scroll-view>

1.1. refresher-enabled

  refresher-enabled是scroll-view组件的一个属性,用于开启自定义下拉刷新功能,默认值为false。
在uni-app中,如果需要自定义下拉刷新样式,可以使用scroll-view组件,并通过设置refresher-enabled属性为true来启用该功能。同时,还需要绑定refresher-triggered属性来设置当前下拉刷新状态,以及在data中定义该属性并默认设为false。此外,还需要在scroll-view上绑定refresherrefresh事件,用于处理下拉刷新的逻辑。

1.2. refresher-triggered

   refresher-triggered属性用于控制下拉刷新的状态。
在使用scroll-view组件实现下拉刷新功能时,需要在scroll-view上绑定refresher-triggered属性,并在data中定义该属性,默认设置为false。当用户下拉触发刷新时,将refresher-triggered属性设置为true,表示下拉刷新已被触发。在数据刷新完成后,将refresher-triggered属性重新设置为false,以关闭下拉刷新状态。

1.3. @scrolltolower

  @scrolltolower事件用于监听滚动到底部的事件。当用户滚动页面到底部时,这个事件会被触发,通常用于实现无限滚动或者加载更多数据的功能。

1.4. @scrolltolower

  @refresherrefresh是自定义下拉刷新的事件。
当用户在scroll-view组件中下拉并释放时,如果自定义下拉刷新功能已启用(通过设置refresher-enabled为true),就会触发@refresherrefresh事件。开发者可以在该事件的处理函数中执行数据刷新操作,如发起网络请求获取最新数据。在处理完数据刷新后,通常需要将refresher-triggered的状态重置为false,以允许下一次的下拉刷新操作。

1.5. @refresherrestore

  @refresherrestore事件用于在下拉刷新完成后恢复视图状态。
@refresherrestore事件在下拉刷新完成后触发,用于恢复视图状态。通常在下拉刷新完成后,需要将refresher-triggered属性设置为false,以隐藏刷新图标并恢复视图状态。

1.5.1. 代码示例

<template><scroll-view:refresher-enabled="true":refresher-triggered="isRefreshing"@refresherrefresh="onRefresh"@refresherrestore="onRestore"scroll-y><!-- 列表内容 --><view v-for="(item, index) in items" :key="index">{{ item }}</view></scroll-view>
</template><script>
export default {data() {return {isRefreshing: false,items: [] // 列表数据};},methods: {async onRefresh() {this.isRefreshing = true;try {// 模拟网络请求await this.fetchData();} catch (error) {console.error('刷新失败:', error);} finally {this.isRefreshing = false;}},onRestore() {console.log('下拉刷新已完成,视图已恢复');},async fetchData() {// 模拟网络请求return new Promise(resolve => {setTimeout(() => {// 更新列表数据this.items = ['新数据1', '新数据2', '新数据3'];resolve();}, 2000);});}}
};
</script>
<style>
/* 样式可以根据需要自定义 */
</style>

1.5.2. 代码解释

  (1)模板部分:
scroll-view组件的refresher-enabled属性设置为true,启用下拉刷新功能。
refresher-triggered属性绑定到isRefreshing,用于控制下拉刷新状态。
@refresherrefresh事件绑定到onRefresh方法,处理下拉刷新逻辑。
@refresherrestore事件绑定到onRestore方法,处理下拉刷新完成后的恢复逻辑。
(2)脚本部分:
data函数返回组件的初始数据,包括isRefreshing和items。
onRefresh方法在下拉刷新时被调用,将isRefreshing设置为true,模拟网络请求后更新列表数据,最后将isRefreshing设置为false。
onRestore方法在下拉刷新完成后被调用,用于恢复视图状态。
fetchData方法模拟网络请求,更新列表数据。
通过以上步骤,你可以实现uni-app中scroll-view组件的下拉刷新功能,并在刷新完成后恢复视图状态。

1.6.@refresherabort

  在 UniApp 中,@refresherabort 是 scroll-view 组件的一个事件,当用户在下拉刷新过程中取消刷新操作时,会触发 @refresherabort 事件。你可以通过定义 refresherabort 方法来处理这个事件。
在这里插入图片描述
在这里插入图片描述

1.7.1. listRefreshPage.vue

<template><view class="page-layout"><view class="header-layout"></view><view id="swiperBox" :style="{ height: scrollHeight + 'px' }"><scroll-viewscroll-ystyle="width: 100%; height: 100%"refresher-enabled:refresher-triggered="triggered"@scrolltolower="onreachBottom"@refresherrefresh="refresherrefresh()"@refresherrestore="refresherrestore()"@refresherabort="refresherabort()"><view class="list-layout"><view class="list-item-layout"v-for="(item, index) in contentList":key="index"><view class="list-item-title">{{ item.name }}</view><view class="list-item-body"><!--任务名称--><view class="list-item-row"><view class="list-item-label"> 任务名称:</view><view class="list-item-label">{{ item.taskName }}</view></view><!--走访时间--><view class="list-item-row"><view class="list-item-label"> 走访时间:</view><view class="list-item-label">{{ item.taskStartDate.slice(0, 10) }}{{ item.taskEndDate.slice(0, 10) }}</view></view></view></view><view class="list-load-more"><list-load-more :status="status"/></view></view></scroll-view></view></view>
</template><script>
import listRefeshData from '../../../data/listRefeshLoad.json'
import ListLoadMore from "./list-load-more.vue";export default {components: {ListLoadMore: ListLoadMore},data() {return {scrollHeight: 0,listRefeshData: listRefeshData,contentList: [],triggered: false,status: "loadmore",taskName: "走访任务名称",params: {current: 1,size: 10,name: null,status: "",},current: 0,};},onLoad(params) {this.params.current = 1;this.contentList = [];this.getList();},onReady() {let that = this;//获取屏幕信息uni.getSystemInfo({success(screenObj) {let {windowWidth, windowHeight, safeArea} = screenObj;const query = uni.createSelectorQuery().in(that);query.select("#swiperBox").boundingClientRect((data) => {that.scrollHeight = safeArea.bottom - data.top;}).exec();},});},methods: {getList(override, search) {let that = this;if (override) {that.params.current = 1;}let {records, current, pages, code} = this.listRefeshData.data;const {size} = that.params;if (that.contentList.length > size) {that.status = "nomore";return} else {that.status = "loadmore";}if (override) {// 下拉刷新that.contentList = records;that.page = pages;} else {// 触底刷新进这个that.contentList = that.contentList.concat(records);}that.params.current++;if (search) {that.showSearch = false;}uni.stopPullDownRefresh();},/*** 界面下拉触发,triggered可能不是true,要设为true* @param index*/refresherrefresh(index) {let that = this;if (that.triggered) {return;}that.triggered = true;//界面下拉触发,triggered可能不是true,要设为trueif (!that.triggered) {that.triggered = true;}setTimeout(() => {that.triggered = false; //触发onRestore,并关闭刷新图标that.triggered = false;this.getList(true);}, 100);},/***  刷新停止*/refresherrestore(index) {let that = this;that.triggered = false;},/***  刷新停止*/refresherabort(index) {let that = this;that.triggered = false;},/***  scroll-view到底部加载更多*/onreachBottom() {let current = this.current;this.status = "loading";setTimeout(() => {this.getList();}, 100);},},
};
</script>
<style scoped lang="scss">
.page-layout {background: #efefef;
}.header-layout {height: 80px;
}.list-layout {padding: 10px 15px;
}.list-item-layout {background: #ffffff;border-radius: 20px;margin-top: 20px;overflow: hidden;//&:not(:last-of-type) {//  border-bottom: 2px solid #e4e7ed;//}
}.list-item-title {display: flex;flex-direction: column;align-items: start;padding: 8px 15px;background: linear-gradient(90deg,#d8ebff 0%,rgba(216, 235, 255, 0) 100%);
}.list-item-body {padding: 30px 25px;
}.list-item-row {display: flex;flex-direction: row;align-items: center;padding: 10px 5px;
}.list-item-label {color: #333;font-size: 16px;
}.list-load-more {padding: 30px 20px;
}
</style>

1.7.2. list-load-loading.vue

<template><view class="page-layout"><view class="header-layout"></view><view id="swiperBox" :style="{ height: scrollHeight + 'px' }"><scroll-viewscroll-ystyle="width: 100%; height: 100%"refresher-enabled:refresher-triggered="triggered"@scrolltolower="onreachBottom"@refresherrefresh="refresherrefresh()"@refresherrestore="refresherrestore()"@refresherabort="refresherabort()"><view class="list-layout"><view class="list-item-layout"v-for="(item, index) in contentList":key="index"><view class="list-item-title">{{ item.name }}</view><view class="list-item-body"><!--任务名称--><view class="list-item-row"><view class="list-item-label"> 任务名称:</view><view class="list-item-label">{{ item.taskName }}</view></view><!--走访时间--><view class="list-item-row"><view class="list-item-label"> 走访时间:</view><view class="list-item-label">{{ item.taskStartDate.slice(0, 10) }}{{ item.taskEndDate.slice(0, 10) }}</view></view></view></view><view class="list-load-more"><list-load-more :status="status"/></view></view></scroll-view></view></view>
</template><script>
import listRefeshData from '../../../data/listRefeshLoad.json'
import ListLoadMore from "./list-load-more.vue";export default {components: {ListLoadMore: ListLoadMore},data() {return {scrollHeight: 0,listRefeshData: listRefeshData,contentList: [],triggered: false,status: "loadmore",taskName: "走访任务名称",params: {current: 1,size: 10,name: null,status: "",},current: 0,};},onLoad(params) {this.params.current = 1;this.contentList = [];this.getList();},onReady() {let that = this;//获取屏幕信息uni.getSystemInfo({success(screenObj) {let {windowWidth, windowHeight, safeArea} = screenObj;const query = uni.createSelectorQuery().in(that);query.select("#swiperBox").boundingClientRect((data) => {that.scrollHeight = safeArea.bottom - data.top;}).exec();},});},methods: {getList(override, search) {let that = this;if (override) {that.params.current = 1;}let {records, current, pages, code} = this.listRefeshData.data;const {size} = that.params;if (that.contentList.length > size) {that.status = "nomore";return} else {that.status = "loadmore";}if (override) {// 下拉刷新that.contentList = records;that.page = pages;} else {// 触底刷新进这个that.contentList = that.contentList.concat(records);}that.params.current++;if (search) {that.showSearch = false;}uni.stopPullDownRefresh();},/*** 界面下拉触发,triggered可能不是true,要设为true* @param index*/refresherrefresh(index) {let that = this;if (that.triggered) {return;}that.triggered = true;//界面下拉触发,triggered可能不是true,要设为trueif (!that.triggered) {that.triggered = true;}setTimeout(() => {that.triggered = false; //触发onRestore,并关闭刷新图标that.triggered = false;this.getList(true);}, 100);},/***  刷新停止*/refresherrestore(index) {let that = this;that.triggered = false;},/***  刷新停止*/refresherabort(index) {let that = this;that.triggered = false;},/***  scroll-view到底部加载更多*/onreachBottom() {let current = this.current;this.status = "loading";setTimeout(() => {this.getList();}, 100);},},
};
</script>
<style scoped lang="scss">
.page-layout {background: #efefef;
}.header-layout {height: 80px;
}.list-layout {padding: 10px 15px;
}.list-item-layout {background: #ffffff;border-radius: 20px;margin-top: 20px;overflow: hidden;//&:not(:last-of-type) {//  border-bottom: 2px solid #e4e7ed;//}
}.list-item-title {display: flex;flex-direction: column;align-items: start;padding: 8px 15px;background: linear-gradient(90deg,#d8ebff 0%,rgba(216, 235, 255, 0) 100%);
}.list-item-body {padding: 30px 25px;
}.list-item-row {display: flex;flex-direction: row;align-items: center;padding: 10px 5px;
}.list-item-label {color: #333;font-size: 16px;
}.list-load-more {padding: 30px 20px;
}
</style>

1.7.3. list-load-more.vue

<template><view class="list-load-more-layout" :style="{backgroundColor: bgColor,height: addUnit(height)	}"><view :class="status == 'loadmore'  || status == 'nomore'? 'list-load-more-more' : ''" class="list-load-more-inner"><view class="list-load-more-icon-layout"><list-load-loading class="list-load-more-icon-icon" :color="iconColor":mode="iconType == 'circle' ? 'circle' : 'flower'":show="status == 'loading' && icon"></list-load-loading></view><!-- 如果没有更多的状态下,显示内容为dot(粗点),加载特定样式 --><view class="list-load-more-txt" @tap="loadMore">{{ showText }}</view></view></view>
</template><script>
import ListLoadLoading from "./list-load-loading.vue";/*** loadmore 加载更多* @description 此组件一般用于标识页面底部加载数据时的状态。* @tutorial https://www.uviewui.com/components/loadMore.html* @property {String} status 组件状态(默认loadmore)* @property {String} bg-color 组件背景颜色,在页面是非白色时会用到(默认#ffffff)* @property {Boolean} icon 加载中时是否显示图标(默认true)* @property {String} icon-type 加载中时的图标类型(默认circle)* @property {String} icon-color icon-type为circle时有效,* 加载中的动画图标的颜色(默认#b7b7b7)* @property {Boolean} is-dot status为nomore时,内容显示为一个"●"(默认false)* @property {String} color 字体颜色(默认#606266)* @property {Object} load-text 自定义显示的文字,见上方说明示例* @event {Function} loadmore status为loadmore时,点击组件会发出此事件* @example <u-loadmore :status="status" icon-type="iconType"* load-text="loadText" />*/
export default {name: "u-loadmore",components: {ListLoadLoading: ListLoadLoading},props: {// 组件背景色bgColor: {type: String,default: 'transparent'},// 是否显示加载中的图标icon: {type: Boolean,default: true},// 字体大小fontSize: {type: String,default: '16'},// 字体颜色color: {type: String,default: '#606266'},// 组件状态,loadmore-加载前的状态,loading-加载中的状态,nomore-没有更多的状态status: {type: String,default: 'loadmore'},// 加载中状态的图标,flower-花朵状图标,circle-圆圈状图标iconType: {type: String,default: 'circle'},// 显示的文字loadText: {type: Object,default() {return {loadmore: '加载更多',loading: '正在加载...',nomore: '没有更多了'}}},// 在“没有更多”状态下,是否显示粗点isDot: {type: Boolean,default: false},// 加载中显示圆圈动画时,动画的颜色iconColor: {type: String,default: '#b7b7b7'},// 高度,单位pxheight: {type: [String, Number],default: 'auto'}},data() {return {// 粗点dotText: "●"}},computed: {// 加载中圆圈动画的样式cricleStyle() {return {borderColor: `#e5e5e5 #e5e5e5 #e5e5e5 ${this.circleColor}`}},// 显示的提示文字showText() {let text = '';if (this.status == 'loadmore') text = this.loadText.loadmore;else if (this.status == 'loading') text = this.loadText.loading;else if (this.status == 'nomore' && this.isDot) text = this.dotText;else text = this.loadText.nomore;return text;}},methods: {addUnit(num) {if (!num)return 0;if (typeof num === "number")return num + "px";return num;},loadMore() {// 只有在“加载更多”的状态下才发送点击事件,// 内容不满一屏时无法触发底部上拉事件,所以需要点击来触发if (this.status == 'loadmore') this.$emit('loadmore');}}
}
</script><style scoped lang="scss">
.list-load-more-layout {justify-content: center;align-items: center;
}
.list-load-more-inner {display: flex;flex-direction: row;justify-content: center;align-items: center;padding: 0 12px;
}.list-load-more-more {position: relative;justify-content: center;
}.list-load-more-icon-layout {margin-right: 8px;
}.list-load-more-icon-icon {align-items: center;justify-content: center;
}.list-load-more-txt {color: black;font-size: 16px;
}</style>

1.7.4. listRefeshLoad.json

{"code": 200,"success": true,"data": {"records": [{"id": "33496","name": "张三","taskStartDate": "2025-07-28","taskEndDate": "2025-08-03","taskName": "12314314"},{"id": "32921","name": "曹十八","taskStartDate": "2025-07-28","taskEndDate": "2025-08-03","taskName": "32154352"},{"id": "329231","name": "刘一","taskStartDate": "2025-07-28","taskEndDate": "2025-08-03","taskName": "23515346"}],"total": 3,"size": 10,"current": 1,"pages": 1},"msg": "操作成功"
}

1.7.5. listRefreshPage.vue

// An highlighted block
var foo = 'bar';
http://www.dtcms.com/a/311335.html

相关文章:

  • 常用git命令
  • 算法训练营DAY46 第九章 动态规划part13
  • 【龙芯99派新世界】buildroot快速使用笔记
  • SPI通信中CS片选的两种实现方案:硬件片选与软件片选
  • 电力系统分析学习笔记(二)- 标幺值计算与变压器建模
  • QT5.12.8 QTabWidget 透明样式QSS
  • Flask + YARA-Python*实现文件扫描功能
  • C++音视频开发:基础面试题
  • STM32 GPIO 中8种配置模式
  • 图漾AGV行业常用相机使用文档
  • 快速了解机器学习
  • 【机器学习】非线性分类算法详解(下):决策树(最佳分裂特征选择的艺术)与支持向量机(最大间隔和核技巧)
  • Python Pandas.unique函数解析与实战教程
  • mac中使用gvm install没有效果
  • 【Android】进度条ProgressBar 可拖拽进度条Seekbar
  • 云运维解决方案(word)
  • Python 入门指南:从零基础到环境搭建
  • 数字化转型-灯塔工厂建设
  • StyleX:Meta推出的高性能零运行时CSS-in-JS解决方案
  • 数字图像处理(冈萨雷斯)第三版:第一章绪论主要内容和重点——(数字图像处理的一些概念)
  • C语言数据结构(4)单链表专题2.单链表的应用
  • 什么是需量跟随
  • Baumer工业相机堡盟工业相机如何通过YoloV8深度学习模型实现道路上头盔的检测识别(C#代码,UI界面版)
  • Linux 嵌入式开发全流程
  • C语言(长期更新)第7讲:VS实用调试技巧
  • LVGL + ESP-Brookesia 在Windows下的编译和运行
  • Elasticsearch+Logstash+Filebeat+Kibana单机部署
  • 卡尔曼滤波轨迹跟踪算法与MATLAB实现
  • GitHub 趋势日报 (2025年08月01日)
  • Kubernetes Service 全面详解:从概念到实践