| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- <!--
- * @Author: jmy
- * @Date: 2026-01-07 12:02:41
- * @LastEditors: Please set LastEditors
- * @LastEditTime: 2026-01-07 15:02:10
- * @Description:
- -->
- <template>
- <!--
- scroll-view 组件内部,在uni-app/小程序中,
- scroll-view 会创建独立的滚动上下文,导致内部的 fixed 定位元素相对于
- scroll-view 容器定位,而非整个视窗,因此会随内容滚动。 -->
- <scroll-view @scrolltolower="loadMore" :scroll-y="isScroll" :scroll-with-animation="true"
- @refresherpulling="handlePulling" @refresherrefresh="handleRefresh" @refresherrestore="handleRefreshStore"
- @refresherabort="handleRefreshAbort" @scroll="onScroll" :refresher-enabled="refresherEnabled"
- :scroll-top="scrollTop" :refresher-threshold="80" :refresher-triggered="isTrigger" refresher-default-style="none"
- :refresher-background="refresherBackground" class="scs-scroll">
- <template slot="refresher">
- <view class="scs-scroll-refresher">
- {{ refresherText }}
- <text class="scroll-loading" :class="{ 'scroll-rotate': refresherText === '正在加载' }"></text>
- </view>
- </template>
- <slot name="list" />
- </scroll-view>
- </template>
- <script>
- export default {
- props: {
- isScroll: {
- type: Boolean,
- default: true,
- },
- list: {
- type: Array,
- default: () => {
- return [];
- },
- },
- refresherBackground: {
- type: String,
- default: "#FFF",
- },
- refresherEnabled: {
- type: Boolean,
- default: false,
- },
- },
- data() {
- return {
- isTrigger: false,
- scrollTop: 0,
- oldScrollTop: 0, //记录上次滚动位置
- refresherText: "下拉刷新",
- threshold: 15, // 设定触发显示隐藏的滚动距离阈值
- isShowToTop: true, //是否显示返回顶部按钮
- };
- },
- methods: {
- //返回顶部
- goTop(e) {
- //视图会发生重新渲染
- this.scrollTop = this.oldScrollTop;
- //当视图渲染结束 重新设置为0
- this.$nextTick(() => {
- this.scrollTop = 0;
- });
- },
- //滚动时触发
- onScroll(e) {
- this.isShowToTop = e.detail.scrollTop > 200;
- this.$emit("scroll");
- // console.log("scroll", e.detail.scrollTop);
- // e.detail.scrollTop 是当前滚动位置
- const scrollTop = e.detail.scrollTop;
- // 只有当滚动距离超过阈值时才触发显示隐藏
- if (Math.abs(scrollTop - this.oldScrollTop) > this.threshold) {
- // 根据滚动方向来确定是显示还是隐藏
- let isShow = !(scrollTop > this.oldScrollTop);
- this.$emit("updateIsTab", isShow);
- }
- // 记录上次滚动位置
- this.oldScrollTop = scrollTop;
- //判断是否显示返回顶部按钮
- this.$emit("handleScroll", scrollTop);
- },
- goTop(e) {
- //视图会发生重新渲染
- this.scrollTop = this.oldScrollTop;
- //当视图渲染结束 重新设置为0
- this.$nextTick(() => {
- this.scrollTop = 0;
- });
- },
- //滚动到底部加载更多
- loadMore() {
- this.$emit("loadMore");
- },
- //自定义下拉刷新控件被下拉
- handlePulling(e) {
- const self = this;
- let y = e.detail.deltaY;
- this.$emit("updateIsTab", true);
- if (y >= 80) {
- self.refresherText = "释放刷新";
- } else {
- self.refresherText = "下拉刷新";
- }
- },
- //自定义下拉刷新被触发
- handleRefresh() {
- const self = this;
- // self.goTop();
- self.$emit("onfresher");
- self.refresherText = "正在加载";
- },
- //自定义下拉刷新被复位
- handleRefreshStore() {
- const self = this;
- self.refresherText = "下拉刷新";
- },
- //自定义下拉刷新被中止
- handleRefreshAbort() {
- const self = this;
- self.refresherText = "下拉刷新";
- self.isTrigger = false;
- },
- },
- };
- </script>
- <style lang="less" scoped>
- // 隐藏scroll-view滚动条
- ::v-deep.scs-scroll {
- height: 99.9%;
- .uni-scroll-view::-webkit-scrollbar {
- width: 0;
- height: 0;
- display: none;
- }
- }
- ::v-deep .scs-scroll-refresher {
- height: 100%;
- width: 100vw;
- display: flex;
- align-items: center;
- justify-content: center;
- gap: 10rpx;
- color: #999999;
- font-size: 30rpx;
- text-align: center;
- }
- </style>
|