更新zpaging组件版本至最新;新增自定义导航栏组件

This commit is contained in:
wangyifeng 2025-01-24 11:18:26 +08:00
parent 4f57419c5d
commit 8704691821
33 changed files with 2839 additions and 354 deletions

View File

@ -13,6 +13,7 @@
custom-class="custom-btn-class"
@click="clickBtn"
:disabled="props?.disabled"
:class="[props?.disabled ? 'custom-btn-class-disabled' : '']"
>
{{ props.btnText }}
</wd-button>
@ -65,6 +66,7 @@ const clickBtn = () => {
width: 100%;
background-color: #fff;
padding: 14rpx 0 72rpx;
box-shadow: 0 1px 0 2px rgba(231, 231, 231, 1);
}
.apposition-btn-style {
padding: 14rpx 30rpx 72rpx;
@ -76,4 +78,8 @@ const clickBtn = () => {
padding: 18rpx 124rpx;
}
}
.custom-btn-class-disabled {
background-color: #e6e6e6 !important;
color: #bebebe !important;
}
</style>

View File

@ -0,0 +1,35 @@
<template>
<tm-navbar
:hideBack="props.hideBack"
hideHome
:title="props.title"
:shadow="0"
:fontSize="34"
/>
</template>
<script setup>
import tmNavbar from '@/uni_modules/tmui/components/tm-navbar/tm-navbar.vue'
import { defineProps } from 'vue'
const props = defineProps({
title: {
//
type: String,
default: '',
},
hideBack: {
//
type: Boolean,
default: false,
},
})
</script>
<style scoped lang="scss">
::v-deep .text-view {
text {
font-weight: 500;
line-height: 48rpx;
}
}
</style>

View File

@ -1,11 +0,0 @@
<script setup>
import tmNavbar from '@/uni_modules/tmui/components/tm-navbar/tm-navbar.vue';
import {useStatus} from "@/store/status"
const {currentNavbar} = useStatus()
</script>
<template>
<tm-navbar :hideBack="false" hideHome :title="currentNavbar.title"/>
</template>
<style scoped lang="scss">
</style>

View File

@ -1,52 +1,55 @@
import customNavbar from '@/components/custom-navbar/index'
import { createSSRApp } from 'vue'
import App from './App.vue'
import dayjs from "dayjs";
import dayjs from 'dayjs'
import 'virtual:uno.css'
import VConsole from "vconsole";
import VConsole from 'vconsole'
import '@/utils/uni.webview.js'
import tmui from "@/uni_modules/tmui"
import {config} from "@/config/tmui/index.js";
import 'dayjs/locale/zh-cn';
import xLoaderror from '@/components/x-loaderror/index.vue'
import { vLoading } from "@/components/x-loading/index.js"
import tmui from '@/uni_modules/tmui'
import { config } from '@/config/tmui/index.js'
import 'dayjs/locale/zh-cn'
import xLoaderror from '@/components/x-loaderror/index.vue'
import { vLoading } from '@/components/x-loading/index.js'
import messagePopup from '@/components/x-message/useMessagePopup'
import pageAnimation from '@/components/page-animation/index.vue'
import * as plugins from './plugins'
const {showMessage}=messagePopup()
const { showMessage } = messagePopup()
dayjs.locale('zh-cn')
if (import.meta.env.VITE_SHOW_CONSOLE){
if (import.meta.env.VITE_SHOW_CONSOLE) {
new VConsole()
}
export function createApp() {
const app = createSSRApp(App)
plugins.setPinia(app)
plugins.setComponents(app)
app.use(tmui,{...config})
app.directive("loading", vLoading)
app.use(tmui, { ...config })
app.directive('loading', vLoading)
app.mixin(pageAnimation)
app.component('x-loaderror',xLoaderror)
app.component('customNavbar', customNavbar)
app.component('x-loaderror', xLoaderror)
app.directive('no-space', {
mounted(el) {
el.addEventListener('input', (e) => {
const originalValue = e.target.value;
const newValue = originalValue.replace(/\s/g, '');
const originalValue = e.target.value
const newValue = originalValue.replace(/\s/g, '')
if (originalValue !== newValue) {
e.target.value = newValue;
e.target.dispatchEvent(new Event('input'));
e.target.value = newValue
e.target.dispatchEvent(new Event('input'))
}
});
}
})
},
})
window.message = ['success', 'error', 'warning'].reduce((acc, type) => {
acc[type] = (message) => {
if (typeof message === 'string') {
showMessage({ type, message });
showMessage({ type, message })
} else if (typeof message === 'object') {
showMessage({ type, ...message });
showMessage({ type, ...message })
}
};
return acc;
}, {});
}
return acc
}, {})
return {
app,
}

View File

@ -1,18 +1,13 @@
<template>
<div class="outer-layer">
<div>
<tm-navbar
:hideBack="false"
hideHome
title="发起群聊"
:leftWidth="220"
></tm-navbar>
</div>
<div class="root">
<div class="w-full pl-[32rpx] pr-[32rpx] mb-[20rpx]">
<div class="w-full mt-[60rpx] flex justify-center">
<div v-if="groupActiveIndex === -1" class="avatar-placeholder"></div>
<div class="mb-[40rpx]" v-else>
<div class="create-group-chat-page">
<zPaging ref="zPaging" :show-scrollbar="false">
<template #top>
<customNavbar :title="$t('pageTitle.create.group')"></customNavbar>
</template>
<div class="create-group-chat flex flex-col">
<div class="group-avatar flex items-center justify-center">
<div class="avatar-placeholder" v-if="groupActiveIndex === -1"></div>
<div v-else>
<tm-image
:width="192"
:height="192"
@ -188,26 +183,21 @@
</div>
</div>
</div>
<div class="h-[162rpx] flex justify-center bg-[#FFFFFF]">
<div class="mt-[14rpx] btnBox">
<tm-button
@click="handleConfirm"
color="#46299D"
:disabled="confirmBtnStatus"
disabledColor="#E6E6E6"
:margin="[0]"
:shadow="0"
:width="426"
:height="76"
size="large"
label="发起群聊"
></tm-button>
</div>
</div>
</div>
<template #bottom>
<customBtn
:isBottom="true"
:btnText="$t('pageTitle.create.group')"
@click="handleConfirm"
:disabled="confirmBtnStatus"
></customBtn>
</template>
</zPaging>
</div>
</template>
<script setup>
import zPaging from '@/uni_modules/z-paging/components/z-paging/z-paging.vue'
import customBtn from '@/components/custom-btn/custom-btn.vue'
import { ref, watch, computed } from 'vue'
import { onShow, onLoad } from '@dcloudio/uni-app'
import { useChatList } from '@/store/chatList/index.js'
@ -366,46 +356,35 @@ onShow(() => {
})
</script>
<style scoped lang="scss">
uni-page-body,
page {
::v-deep .zp-paging-container-content {
height: 100%;
display: flex;
}
.outer-layer {
overflow-y: auto;
flex: 1;
.create-group-chat {
background-image: url('@/static/image/clockIn/z3280@3x.png');
background-size: cover;
padding-bottom: 0;
display: flex;
flex-direction: column;
}
.root {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
width: 100%;
padding: 0 32rpx;
.group-avatar {
padding: 60rpx 0;
.avatar-placeholder {
width: 192rpx;
height: 192rpx;
background-color: #e0e0e0;
border-radius: 50%;
}
}
}
.divider {
height: 1rpx;
background-color: #7c7c7c;
opacity: 0.6;
}
.avatar-placeholder {
width: 192rpx;
height: 192rpx;
background-color: #e0e0e0;
border-radius: 50%;
margin-bottom: 40rpx;
}
.input-group {
background-color: #fff;
padding-top: 38rpx;
padding-bottom: 32rpx;
padding-left: 32rpx;
padding-right: 40rpx;
// display: flex;
// align-items: center;
// justify-content: space-between;
padding: 38rpx 40rpx 32rpx 32rpx;
}
.input-item {
line-height: 40rpx;

View File

@ -137,5 +137,6 @@
"index.mine.normal": "普通",
"select.member.remove": "选择要移除的人",
"select.member.num": "已选择",
"statistic.unit.person": "人"
"statistic.unit.person": "人",
"pageTitle.create.group": "发起群聊"
}

View File

@ -1,74 +1,24 @@
## 2.7.112024-06-28
1.`新增` 方法`updateVirtualListRender`,支持手动触发虚拟列表渲染更新。
2.`新增` 延迟加载列表演示。
3.`修复` v2.7.8引出的vue3+npm+微信小程序中,`uni.$zp`配置失效的问题。
4.`修复` 在本地分页+虚拟列表情况下虚拟列表cell未被正常销毁的问题。
5.`修复` 打开调试模式下无法获取getApp导致的`cannot read property 'zp_handleQueryCallback' of undefined`的报错。
6.`修复` 极小概率出现的分页请求较快且快速滚动到底部时未能加载更多的问题。
## 2.7.102024-05-10
1.`修复` v2.7.8引出的vue3+npm+微信小程序中uni.$zp配置失效的问题。
## 2.7.92024-05-10
1.`修复` 在新版HbuilderX+vue3+微信小程序中可能出现的加载第二页数据后返回顶部无法下拉的问题。
2.`修复` 在vue3+抖音小程序中可能出现的首次加载reload没有触发的问题。
3.`优化` ts类型中`ZPagingInstance`泛型不必填,默认为`any`。
## 2.7.82024-05-09
1.`新增` typescript类型声明文件感谢小何同学提供。
2.`新增` 添加极简写法fetch相关配置及示例。
3.`新增` `fixed-cellHeight`配置支持在虚拟列表中自定义固定的cell高度。
4.`新增` `refresher-refreshing-scrollable`配置,支持自定义下拉刷新中是否允许列表滚动。
5.`修复` 在新版HubilderX+vue3+h5中`swiper-demo`模式`slot=top`被导航栏遮挡的问题。
6.`修复` 下拉进入二楼偶现的二楼高度未铺满全屏的问题。
7.`修复` 虚拟列表中complete若传相同对象会导致key重复的问题。
8.`修复` 在虚拟列表中调用refresh后缓存高度原始数据未清空的问题。
9.`修复` 聊天记录模式删除记录时顶部显示loading的问题。
9.`优化` `scrollIntoViewByIndex`支持在虚拟列表中滚动到指定cell。
10.`优化` `content-z-index`默认值修改为1。
## 2.7.72024-04-01
1.`新增` 下拉进入二楼功能及相关配置&demo。
2.`新增` 虚拟列表写法添加【非内置列表】写法可良好兼容vue3中的各平台并有较优的性能表现。
3.`新增` `z-paging-cell`补充`@touchstart`事件。
4.`修复` 页面滚动模式设置了`auto-full-height`后可能出现的依然有异常空白占位的问题和下拉刷新时列表数据被切割的问题。
## 2.7.62024-02-29
1.`新增` `max-width`,支持设置`z-paging`的最大宽度,默认`z-paging`宽度铺满窗口。
2.`新增` `chat-adjust-position-offset`,支持设置使用聊天记录模式中键盘弹出时占位高度偏移距离。
3.`修复` 由于renderjs中聊天记录模式判断不准确导致的可能出现的从聊天记录页面跳转到其他页面后返回页面无法滚动的问题。
4.`修复` 聊天记录模式首次加载失败后,发送消息顶部会显示加载失败文字的问题。
5.`修复` 聊天记录模式nvue可能出现的键盘弹出无法滚动到底部的问题。
6.`修复` 聊天记录模式+nvue滚动条无法展示的问题&底部会显示加载中的问题。
7.`修复` 聊天记录模式监听键盘弹出可能出现的无法正常销毁的问题。
8.`修复` 直接修改dataList的值组件内部的值未更新的问题。
## 2.7.52024-01-23
1.`新增` props`chat-loading-more-default-as-loading`,支持设置在聊天记录模式中滑动到顶部状态为默认状态时,以加载中的状态展示。
2.`新增` slots`chatNoMore`支持自定义聊天记录模式没有更多数据view。
3.`修复` 固定在底部view可能出现默认黄色的问题。
4.`优化` 聊天记录加载更多样式,与普通模式对齐,支持点击加载更多&点击重试,并支持加载更多相关配置。
5.`优化` 微调下拉刷新和底部加载更多样式。
6.`优化` 聊天记录模式自动滚动到底部添加延时以避免可能出现的滚动到底部位置不正确的问题。
7.`优化` 使用新的判断滚动到顶部算法以解决在安卓设备中可能出现的因滚动到顶部时scrollTop不为0导致的下拉刷新被禁用的问题。
## 2.7.42024-01-14
1.`新增` props:`auto-adjust-position-when-chat`支持设置使用聊天记录模式中键盘弹出时是否自动调整slot="bottom"高度。
2.`新增` props:`auto-to-bottom-when-chat`,支持设置使用聊天记录模式中键盘弹出时是否自动滚动到底部。
3.`新增` props:`show-chat-loading-when-reload`支持设置使用聊天记录模式中reload时是否显示chatLoading。
4.`修复` 在聊天记录模式中`scrollIntoViewById`和`scrollIntoViewByNodeTop`无效的问题。
5.`优化` 聊天记录模式底部安全区域针对键盘开启/关闭兼容处理。
6.`优化` 更新内置的空数据图&加载失败图感谢图鸟UI提供的免费可商用的空数据图和加载失败图
## 2.7.32024-01-10
1.`新增` 聊天记录模式支持虚拟列表&添加相关demo。
2.`新增` nvue中list添加`@scrollend`监听。
3.`优化` 聊天记录模式+vue第一页并且没有更多时不倒置列表。
4.`优化` 聊天记录模式+nvue中数据不满屏时默认从顶部开始不进行列表倒置。
## 2.7.22024-01-09
1.`修复` `vue3+h5`中报错`uni.onKeyboardHeightChange is not a function`的问题。
2.`优化` 聊天记录模式细节:表情面板在触摸列表时隐藏&添加隐藏动画。
## 2.7.12024-01-08
1.`新增` `keyboardHeightChange` event支持监听键盘高度改变。
2.`新增` 聊天记录模式新增切换表情面板/键盘demo。
3.`优化` 键盘弹出占位添加动画效果。
## 2.7.02024-01-07
2024新年快乐祝大家在新的一年里工作顺利事事顺心
1.`新增` 全新的聊天记录模式设计将vue中的聊天记录模式与nvue中对齐完全解决了聊天记录模式滚动到顶部加载更多在vue中抖动的问题同时将聊天记录模式键盘自动弹出自动上推页面交由`z-paging`处理,解决了由此引发的各种问题,尤其是在微信小程序中导航栏被键盘顶出屏幕外的问题。如果您使用了`z-paging`的聊天记录模式强烈建议更新写法有一定变更具体请参见demo。
2.`新增` `swiper-demo`新增`onShow`时候调用reload演示。
3.`修复` 修复滚动相关方法在微信小程序中首次滚动动画无效的问题。
4.`修复` props设置单位单位为px时报错的问题。
5.`修复` 在某些情况下`z-paging`加载了但是未渲染时reload无效的问题。
6.`修复` 底部loading动画未生效的问题。
## 2.8.42024-12-02
1.`修复` 在虚拟列表+vue2中顶部占位采用transformY方案在虚拟列表+vue3中顶部占位采用view占位方案。以解决在vue2+微信小程序+安卓+兼容模式中,可能出现的虚拟列表闪动的问题。
2.`修复` 在列表渲染时(尤其是在虚拟列表中)偶现的【点击加载更多】闪现的问题。
3.`优化` 统一在RefresherStatus枚举中Loading取值。
4.`优化` `defaultPageNo`&`defaultPageSize`修改为只允许number类型。
5.`优化` 提升兼容性&细节优化。
## 2.8.32024-11-27
1.`修复` `doInsertVirtualListItem`插入数据无效的问题。
2.`优化` 提升兼容性&细节优化。
## 2.8.22024-11-25
1.`优化` types中`ZPagingRef`和`ZPagingInstance`支持泛型。
## 2.8.12024-11-24
1.`新增` 完整的`props`、`slots`、`methods`、`events`的typescript types声明可在ts中获得绝佳的代码提示体验。
2.`新增` `virtual-cell-id-prefix`虚拟列表cell id的前缀适用于一个页面有多个虚拟列表的情况用以区分不同虚拟列表cell的id。
3.`修复` 在vue3+(微信小程序或QQ小程序)中,使用非内置列表写法时,若`z-paging`在`swiper-item`标签内的情况下存在的无法获取slot插入的cell高度的问题。
4.`修复` 在虚拟列表中分页数据小于1页时插入新数据虚拟列表未生效的问题。
5.`修复` 在虚拟列表中调用`refresh`时cell的index计算不正确的问题。
6.`修复` 在快手小程序中内容较少或空数据时`z-paging`未能铺满全屏的问题。
7.`优化` `events`中的参数涉及枚举的部分统一由之前的number类型修改为string类型展示更直观涉及的events`@query`中的`from`参数;`@refresherStatusChange`中的`status`参数;`@loadingStatusChange`中的`status`参数;`slot=refresher`中的`refresherStatus`参数;`slot=chatLoading`中的`loadingMoreStatus`参数。更新版本请特别留意!
## 2.8.02024-10-21
1.`新增` 全面支持鸿蒙Next。
2.`修复` 设置了`refresher-complete-delay`后在下拉刷新期间调用reload导致的无法再次下拉刷新的问题。
3.`优化` 废弃虚拟列表transformY顶部占位方案修改为空view占位。解决因使用旧方案导致的vue3中可能出现的虚拟列表闪动问题。提升虚拟列表的兼容性。

View File

@ -55,8 +55,12 @@
},
//
ownLoadingMoreText() {
const statusTextArr = [this.c.defaultText,this.c.loadingText,this.c.noMoreText,this.c.failText];
return statusTextArr[this.finalStatus];
return {
[this.M.Default]: this.c.defaultText,
[this.M.Loading]: this.c.loadingText,
[this.M.NoMore]: this.c.noMoreText,
[this.M.Fail]: this.c.failText,
}[this.finalStatus];
},
//
finalStatus() {

View File

@ -57,14 +57,21 @@
ts() {
return this.defaultThemeStyle;
},
//
statusTextArr() {
// Map
statusTextMap() {
this.updateTime();
return [this.defaultText, this.pullingText, this.refreshingText, this.completeText, this.goF2Text];
const { R, defaultText, pullingText, refreshingText, completeText, goF2Text } = this;
return {
[R.Default]: defaultText,
[R.ReleaseToRefresh]: pullingText,
[R.Loading]: refreshingText,
[R.Complete]: completeText,
[R.GoF2]: goF2Text,
};
},
//
currentTitle() {
return this.statusTextArr[this.status] || this.defaultText;
return this.statusTextMap[this.status] || this.defaultText;
},
// class
leftImageClass() {

View File

@ -193,6 +193,10 @@
z-index: 999;
}
.zp-back-to-top-img-inversion {
transform: rotate(180deg);
}
.zp-empty-view {
/* #ifdef APP-NVUE */
height: 100%;

View File

@ -89,10 +89,10 @@ export default {
!callbacked && this._handleToTop();
})
},
// 处理滚动到顶部
// 处理滚动到顶部(聊天记录模式中为滚动到底部)
_handleToTop() {
!this.backToTopWithAnimate && this._checkShouldShowBackToTop(0);
this.scrollToTop(this.backToTopWithAnimate);
!this.useChatRecordMode ? this.scrollToTop(this.backToTopWithAnimate) : this.scrollToBottom(this.backToTopWithAnimate);
},
// 判断是否要显示返回顶部按钮
_checkShouldShowBackToTop(scrollTop) {

View File

@ -82,7 +82,7 @@ export default {
})
},
// 获取节点尺寸
_getNodeClientRect(select, inDom = true, scrollOffset = false) {
_getNodeClientRect(select, inDom = true, scrollOffset = false, inParent = false) {
if (this.isReadyDestroy) {
return Promise.resolve(false);
};
@ -106,7 +106,8 @@ export default {
//#ifdef MP-ALIPAY
inDom = false;
//#endif
let res = !!inDom ? uni.createSelectorQuery().in(inDom === true ? this : inDom) : uni.createSelectorQuery();
const inDomObj = inParent ? this.$parent : this;
let res = inDom || inParent ? uni.createSelectorQuery().in(inDomObj) : uni.createSelectorQuery();
scrollOffset ? res.select(select).scrollOffset() : res.select(select).boundingClientRect();
return new Promise((resolve, reject) => {
res.exec(data => {

View File

@ -8,7 +8,7 @@ export default {
props: {
// 自定义初始的pageNo默认为1
defaultPageNo: {
type: [Number, String],
type: Number,
default: u.gc('defaultPageNo', 1),
observer: function(newVal) {
this.pageNo = newVal;
@ -16,7 +16,7 @@ export default {
},
// 自定义pageSize默认为10
defaultPageSize: {
type: [Number, String],
type: Number,
default: u.gc('defaultPageSize', 10),
validator: (value) => {
if (value <= 0) u.consoleErr('default-page-size必须大于0');
@ -473,14 +473,10 @@ export default {
if (!isLocal && tempIsUserPullDown && this.isFirstPage) {
this.isUserPullDown = false;
}
if (!this.isFirstPage) {
this.listRendering = true;
this.$nextTick(() => {
u.delay(() => this.listRendering = false);
})
} else {
this.listRendering = false;
}
this.listRendering = true;
this.$nextTick(() => {
u.delay(() => this.listRendering = false);
})
let dataTypeRes = this._checkDataType(data, success, isLocal);
data = dataTypeRes.data;
success = dataTypeRes.success;
@ -511,7 +507,9 @@ export default {
const localPageNo = this.defaultPageNo;
const localPageSize = this.queryFrom !== Enum.QueryFrom.Refresh ? this.defaultPageSize : this.currentRefreshPageSize;
this._localPagingQueryList(localPageNo, localPageSize, 0, res => {
this.completeByTotal(res, this.totalLocalPagingList.length);
u.delay(() => {
this.completeByTotal(res, this.totalLocalPagingList.length);;
}, 0)
})
} else {
// 如果当前不是本地分页,则按照正常分页逻辑进行数据处理&emit数据
@ -538,7 +536,7 @@ export default {
this._callDataPromise(false);
this.loadingStatus = Enum.More.Fail;
this.isHandlingRefreshToPage = false;
if (this.loadingType === Enum.LoadingType.LoadingMore) {
if (this.loadingType === Enum.LoadingType.LoadMore) {
this.pageNo --;
}
}

View File

@ -179,12 +179,16 @@ export default {
// 是否显示自定义状态下的底部加载更多
showLoadingMoreCustom() {
return this._showLoadingMore('Custom');
}
},
// 底部加载更多固定高度
loadingMoreFixedHeight() {
return u.addUnit('80rpx', this.unit);
},
},
methods: {
// 页面滚动到底部时通知z-paging进行进一步处理
pageReachBottom() {
!this.useChatRecordMode && this._onLoadingMore('toBottom');
!this.useChatRecordMode && this.toBottomLoadingMoreEnabled && this._onLoadingMore('toBottom');
},
// 手动触发上拉加载更多(非必须,可依据具体需求使用)
doLoadMore(type) {
@ -275,15 +279,15 @@ export default {
// 如果是本地分页,则在组件内部对数据进行分页处理,不触发@query事件
this._localPagingQueryList(this.pageNo, this.defaultPageSize, this.localPagingLoadingTime, res => {
this.completeByTotal(res, this.totalLocalPagingList.length);
this.queryFrom = Enum.QueryFrom.LoadingMore;
this.queryFrom = Enum.QueryFrom.LoadMore;
})
} else {
// emit @query相关加载更多事件
this._emitQuery(this.pageNo, this.defaultPageSize, Enum.QueryFrom.LoadingMore);
this._emitQuery(this.pageNo, this.defaultPageSize, Enum.QueryFrom.LoadMore);
this._callMyParentQuery();
}
// 设置当前加载状态为底部加载更多状态
this.loadingType = Enum.LoadingType.LoadingMore;
this.loadingType = Enum.LoadingType.LoadMore;
}
},
// (预处理)判断当没有更多数据且分页内容未超出z-paging时是否显示没有更多数据的view

View File

@ -66,7 +66,7 @@ export default {
nLoadingMoreFixedHeight: false,
nShowRefresherRevealHeight: 0,
nOldShowRefresherRevealHeight: -1,
nRefresherWidth: uni.upx2px(750),
nRefresherWidth: u.rpx2px(750),
nF2Opacity: 0
}
},

View File

@ -349,7 +349,7 @@ export default {
return this.refresherTriggered;
},
showRefresher() {
const showRefresher = this.finalRefresherEnabled && this.useCustomRefresher;
const showRefresher = this.finalRefresherEnabled || this.useCustomRefresher && !this.useChatRecordMode;
// #ifndef APP-NVUE
this.active && this.customRefresherHeight === -1 && showRefresher && this.updateCustomRefresherHeight();
// #endif
@ -415,7 +415,7 @@ export default {
this.$emit('onRestore');
this.$emit('Restore');
},
// #ifndef APP-VUE || MP-WEIXIN || MP-QQ || H5
// #ifndef APP-PLUS || MP-WEIXIN || MP-QQ || H5
// touch开始
_refresherTouchstart(e) {
this._handleListTouchstart();
@ -439,8 +439,8 @@ export default {
this._cleanRefresherEndTimeout();
},
// 非appvue或微信小程序或QQ小程序或h5平台使用js控制下拉刷新
// #ifndef APP-VUE || MP-WEIXIN || MP-QQ || H5
// 非app-ios/android或微信小程序或QQ小程序或h5平台使用js控制下拉刷新
// #ifndef APP-IOS || APP-ANDROID || MP-WEIXIN || MP-QQ || H5
// touch中
_refresherTouchmove(e) {
const currentTimeStamp = u.getTime();
@ -515,7 +515,7 @@ export default {
// 下拉刷新距离未超过阈值,显示默认状态
this.refresherStatus = Enum.Refresher.Default;
}
// #ifndef APP-VUE || MP-WEIXIN || MP-QQ || H5
// #ifndef APP-PLUS || MP-WEIXIN || MP-QQ || H5
// this.scrollEnable = false;
// 通过transform控制下拉刷新view垂直偏移
this.refresherTransform = `translateY(${moveDis}px)`;
@ -523,7 +523,7 @@ export default {
// #endif
this.moveDis = moveDis;
},
// #ifndef APP-VUE || MP-WEIXIN || MP-QQ || H5
// #ifndef APP-PLUS || MP-WEIXIN || MP-QQ || H5
// touch结束
_refresherTouchend(e) {
// 下拉刷新用户手离开屏幕,允许列表滚动
@ -553,7 +553,7 @@ export default {
this._refresherEnd();
} else {
// 如果是松手立即刷新状态,则触发下拉刷新
// #ifndef APP-VUE || MP-WEIXIN || MP-QQ || H5
// #ifndef APP-PLUS || MP-WEIXIN || MP-QQ || H5
this.refresherTransform = `translateY(${refresherThreshold}px)`;
this.refresherTransition = 'transform .1s linear';
// #endif
@ -584,7 +584,7 @@ export default {
_handleScrollViewBounce({ bounce }) {
if (!this.usePageScroll && !this.scrollToTopBounceEnabled) {
if (this.wxsScrollTop <= 5) {
// #ifdef APP-VUE || MP-WEIXIN || MP-QQ || H5
// #ifdef APP-PLUS || MP-WEIXIN || MP-QQ || H5
this.refresherTransition = '';
// #endif
this.scrollEnable = bounce;
@ -615,7 +615,9 @@ export default {
// 下拉刷新结束
_refresherEnd(shouldEndLoadingDelay = true, fromAddData = false, isUserPullDown = false, setLoading = true) {
if (this.loadingType === Enum.LoadingType.Refresher) {
// 计算当前下拉刷新结束需要延迟的时间
const refresherCompleteDelay = (fromAddData && (isUserPullDown || this.showRefresherWhenReload)) ? this.refresherCompleteDelay : 0;
// 如果延迟时间大于0则展示刷新结束状态否则直接展示默认状态
const refresherStatus = refresherCompleteDelay > 0 ? Enum.Refresher.Complete : Enum.Refresher.Default;
if (this.finalShowRefresherWhenReload) {
const stackCount = this.refresherRevealStackCount;
@ -624,7 +626,12 @@ export default {
}
this._cleanRefresherEndTimeout();
this.refresherEndTimeout = u.delay(() => {
// 更新下拉刷新状态
this.refresherStatus = refresherStatus;
// 如果当前下拉刷新状态不是刷新结束,则认为其不在刷新结束状态
if (refresherStatus !== Enum.Refresher.Complete) {
this.isRefresherInComplete = false;
}
}, this.refresherStatus !== Enum.Refresher.Default && refresherStatus === Enum.Refresher.Default ? this.refresherCompleteDuration : 0);
// #ifndef APP-NVUE
@ -640,11 +647,11 @@ export default {
animateDuration = this.refresherEndBounceEnabled ? this.refresherCompleteDuration / 1000 : this.refresherCompleteDuration / 3000;
}
this.refresherTransition = `transform ${fromAddData ? animateDuration : this.refresherDefaultDuration / 1000}s ${animateType}`;
// #ifndef APP-VUE || MP-WEIXIN || MP-QQ || H5
// #ifndef APP-PLUS || MP-WEIXIN || MP-QQ || H5
this.refresherTransform = 'translateY(0px)';
this.currentDis = 0;
// #endif
// #ifdef APP-VUE || MP-WEIXIN || MP-QQ || H5
// #ifdef APP-PLUS || MP-WEIXIN || MP-QQ || H5
this.wxsPropType = this.refresherTransition + 'end' + u.getTime();
// #endif
// #ifdef APP-NVUE
@ -748,10 +755,10 @@ export default {
}
// #endif
this.refresherRevealStackCount ++;
// #ifndef APP-VUE || MP-WEIXIN || MP-QQ || H5
// #ifndef APP-PLUS || MP-WEIXIN || MP-QQ || H5
this.refresherTransform = `translateY(${this.finalRefresherThreshold}px)`;
// #endif
// #ifdef APP-VUE || MP-WEIXIN || MP-QQ || H5
// #ifdef APP-PLUS || MP-WEIXIN || MP-QQ || H5
this.wxsPropType = 'begin' + u.getTime();
// #endif
this.moveDis = this.finalRefresherThreshold;
@ -762,10 +769,10 @@ export default {
},
// 触发下拉刷新
_doRefresherLoad(isUserPullDown = true) {
this._onRefresh(false,isUserPullDown);
this._onRefresh(false, isUserPullDown);
this.loading = true;
},
// #ifndef APP-VUE || MP-WEIXIN || MP-QQ || H5
// #ifndef APP-PLUS || MP-WEIXIN || MP-QQ || H5
// 获取处理后的moveDis
_getFinalRefresherMoveDis(moveDis) {
let diffDis = moveDis - this.oldCurrentMoveDis;

View File

@ -240,7 +240,9 @@ export default {
},
// 当滚动到底部时
_onScrollToLower(e) {
(!e.detail || !e.detail.direction || e.detail.direction === 'bottom') && this._onLoadingMore(this.useChatRecordMode ? 'click' : 'toBottom')
(!e.detail || !e.detail.direction || e.detail.direction === 'bottom')
&& this.toBottomLoadingMoreEnabled
&& this._onLoadingMore(this.useChatRecordMode ? 'click' : 'toBottom')
},
// 滚动到顶部
_scrollToTop(animate = true, isPrivate = true) {

View File

@ -74,6 +74,11 @@ export default {
type: [Number, String],
default: u.gc('virtualScrollFps', 80)
},
// 虚拟列表cell id的前缀适用于一个页面有多个虚拟列表的情况用以区分不同虚拟列表cell的id注意请勿传数字或以数字开头的字符串。如设置为list1则cell的id应为list1-zp-id-${item.zp_index}
virtualCellIdPrefix: {
type: String,
default: u.gc('virtualCellIdPrefix', '')
},
},
data() {
return {
@ -110,6 +115,10 @@ export default {
virtualList(newVal){
this.$emit('update:virtualList', newVal);
this.$emit('virtualListChange', newVal);
},
// 监听虚拟列表顶部占位高度改变并emit
virtualPlaceholderTopHeight(newVal) {
this.$emit('virtualTopHeightChange', newVal);
}
},
computed: {
@ -139,17 +148,31 @@ export default {
finalFixedCellHeight() {
return u.convertToPx(this.fixedCellHeight);
},
fianlVirtualCellIdPrefix() {
const prefix = this.virtualCellIdPrefix ? this.virtualCellIdPrefix + '-' : '';
return prefix + 'zp-id';
},
finalPlaceholderTopHeightStyle() {
// #ifdef VUE2
return { transform: this.virtualPlaceholderTopHeight > 0 ? `translateY(${this.virtualPlaceholderTopHeight}px)` : 'none' };
// #endif
return {};
},
virtualRangePageHeight(){
return this.finalVirtualPageHeight * this.preloadPage;
},
virtualScrollDisTimeStamp() {
return 1000 / this.virtualScrollFps;
},
}
},
methods: {
// 在使用动态高度虚拟列表时若在列表数组中需要插入某个item需要调用此方法item:需要插入的itemindex:插入的cell位置若index为2则插入的item在原list的index=1之后index从0开始
doInsertVirtualListItem(item, index) {
if (this.cellHeightMode !== Enum.CellHeightMode.Dynamic) return;
this.realTotalData.splice(index, 0, item);
// #ifdef VUE3
this.realTotalData = [...this.realTotalData];
// #endif
this.virtualItemInsertedCount ++;
if (!item || Object.prototype.toString.call(item) !== '[object Object]') {
item = { item };
@ -162,7 +185,7 @@ export default {
while (retryCount <= 10) {
await u.wait(c.delayTime);
const cellNode = await this._getNodeClientRect(`#zp-id-${item[cellIndexKey]}`, this.finalUseInnerList);
const cellNode = await this._getVirtualCellNodeByIndex(item[cellIndexKey]);
// 如果获取当前cell的节点信息失败则重试不超过10次
if (!cellNode) {
retryCount ++;
@ -191,12 +214,12 @@ export default {
}
})
},
// 在使用动态高度虚拟列表时手动更新指定cell的缓存高度(当cell高度在初始化之后再次改变调用)index:需要更新的cell在列表中的位置从0开始
// 在使用动态高度虚拟列表时手动更新指定cell的缓存高度(当cell高度在初始化之后再次改变调用)index:需要更新的cell在列表中的位置从0开始
didUpdateVirtualListCell(index) {
if (this.cellHeightMode !== Enum.CellHeightMode.Dynamic) return;
const currentNode = this.virtualHeightCacheList[index];
this.$nextTick(() => {
this._getNodeClientRect(`#zp-id-${index}`, this.finalUseInnerList).then(cellNode => {
this._getVirtualCellNodeByIndex(index).then(cellNode => {
// 更新当前cell的高度
const cellNodeHeight = cellNode ? cellNode[0].height : 0;
const heightDis = cellNodeHeight - currentNode.height;
@ -261,7 +284,7 @@ export default {
if (!this.finalFixedCellHeight) {
this.$nextTick(() => {
u.delay(() => {
this._getNodeClientRect(`#zp-id-${0}`,this.finalUseInnerList).then(cellNode => {
this._getVirtualCellNodeByIndex(0).then(cellNode => {
if (!cellNode) {
if (this.getCellHeightRetryCount.fixed > 10) return;
this.getCellHeightRetryCount.fixed ++;
@ -287,7 +310,7 @@ export default {
this.$nextTick(() => {
u.delay(async () => {
for (let i = 0; i < list.length; i++) {
const cellNode = await this._getNodeClientRect(`#zp-id-${list[i][this.virtualCellIndexKey]}`, this.finalUseInnerList);
const cellNode = await this._getVirtualCellNodeByIndex(list[i][this.virtualCellIndexKey]);
const currentHeight = cellNode ? cellNode[0].height : 0;
if (!cellNode) {
if (this.getCellHeightRetryCount.dynamic <= 10) {
@ -328,8 +351,8 @@ export default {
_setCellIndex(list, dataFrom = 'bottom') {
let currentItemIndex = 0;
const cellIndexKey = this.virtualCellIndexKey;
([Enum.QueryFrom.Refresh, Enum.QueryFrom.Reload].indexOf(this.queryFrom) >= 0) && this._resetDynamicListState();
if (this.totalData.length) {
dataFrom === 'bottom' && ([Enum.QueryFrom.Refresh, Enum.QueryFrom.Reload].indexOf(this.queryFrom) >= 0) && this._resetDynamicListState();
if (this.totalData.length && this.queryFrom !== Enum.QueryFrom.Refresh) {
if (dataFrom === 'bottom') {
currentItemIndex = this.realTotalData.length;
const lastItem = this.realTotalData.length ? this.realTotalData.slice(-1)[0] : null;
@ -504,6 +527,20 @@ export default {
})
}
},
// 获取对应index的虚拟列表cell节点信息
_getVirtualCellNodeByIndex(index) {
let inParent = false;
// 在vue3+(微信小程序或QQ小程序)中使用非内置列表写法时若z-paging在swiper-item内存在无法获取slot插入的cell高度的问题
// 通过uni.createSelectorQuery().in(this.$parent)来解决此问题
// #ifdef VUE3
// #ifdef MP-WEIXIN || MP-QQ
if (this.forceCloseInnerList) {
inParent = true;
}
// #endif
// #endif
return this._getNodeClientRect(`#${this.fianlVirtualCellIdPrefix}-${index}`, this.finalUseInnerList, false, inParent);
},
// 处理使用内置列表时点击了cell事件
_innerCellClick(item, index) {
this.$emit('innerCellClick', item, index);

View File

@ -2,7 +2,7 @@
export default {
// 当前版本号
version: '2.7.11',
version: '2.8.3',
// 延迟操作的通用时间
delayTime: 100,
// 请求失败时候全局emit使用的key

View File

@ -1,32 +1,32 @@
// [z-paging]枚举
export default {
// 当前加载类型 0.下拉刷新 1.上拉加载更多
// 当前加载类型 refresher:下拉刷新 load-more:上拉加载更多
LoadingType: {
Refresher: 0,
LoadingMore: 1
Refresher: 'refresher',
LoadMore: 'load-more'
},
// 下拉刷新状态 0.默认状态 1.松手立即刷新 2.刷新中 3.刷新结束 4.松手进入二楼
// 下拉刷新状态 default:默认状态 release-to-refresh:松手立即刷新 loading:刷新中 complete:刷新结束 go-f2:松手进入二楼
Refresher: {
Default: 0,
ReleaseToRefresh: 1,
Loading: 2,
Complete: 3,
GoF2: 4
Default: 'default',
ReleaseToRefresh: 'release-to-refresh',
Loading: 'loading',
Complete: 'complete',
GoF2: 'go-f2'
},
// 底部加载更多状态 0.默认状态 1.加载中 2.没有更多数据 3.加载失败
// 底部加载更多状态 default:默认状态 loading:加载中 no-more:没有更多数据 fail:加载失败
More: {
Default: 0,
Loading: 1,
NoMore: 2,
Fail: 3
Default: 'default',
Loading: 'loading',
NoMore: 'no-more',
Fail: 'fail'
},
// @query触发来源 0.用户主动下拉刷新 1.通过reload触发 2.通过refresh触发 3.通过滚动到底部加载更多或点击底部加载更多触发
// @query触发来源 user-pull-down:用户主动下拉刷新 reload:通过reload触发 refresh:通过refresh触发 load-more:通过滚动到底部加载更多或点击底部加载更多触发
QueryFrom: {
UserPullDown: 0,
Reload: 1,
Refresh: 2,
LoadingMore: 3
UserPullDown: 'user-pull-down',
Reload: 'reload',
Refresh: 'refresh',
LoadMore: 'load-more'
},
// 虚拟列表cell高度模式
CellHeightMode: {

View File

@ -50,8 +50,6 @@ export default {
data() {
return {
// --------------静态资源---------------
base64Arrow: zStatic.base64Arrow,
base64Flower: zStatic.base64Flower,
base64BackToTop: zStatic.base64BackToTop,
// -------------全局数据相关--------------
@ -218,7 +216,10 @@ export default {
// 初始化systemInfo
this.systemInfo = uni.getSystemInfoSync();
// 初始化z-paging高度
!this.usePageScroll && this.autoHeight && this._setAutoHeight();
!this.usePageScroll && this.autoHeight && this._setAutoHeight();
// #ifdef MP-KUAISHOU
this._setFullScrollViewInHeight();
// #endif
this.loaded = true;
u.delay(() => {
// 更新fixed模式下z-paging的布局主要是更新windowTop、windowBottom
@ -408,10 +409,7 @@ export default {
},
// 设置z-paging高度
async _setAutoHeight(shouldFullHeight = true, scrollViewNode = null) {
let heightKey = 'min-height';
// #ifndef APP-NVUE
heightKey = 'min-height';
// #endif
const heightKey = 'min-height';
try {
if (shouldFullHeight) {
// 如果需要铺满全屏,则计算当前全屏可是区域的高度
@ -432,6 +430,16 @@ export default {
}
} catch (e) {}
},
// #ifdef MP-KUAISHOU
// 设置scroll-view内容器的最小高度等于scroll-view的高度(为了解决在快手小程序中内容较少时scroll-view内容器高度无法铺满scroll-view的问题)
_setFullScrollViewInHeight() {
try {
// 如果需要铺满全屏,则计算当前全屏可是区域的高度
const scrollViewNode = await this._getNodeClientRect('.zp-scroll-view');
scrollViewNode && this.$set(this.scrollViewInStyle, 'min-height', scrollViewNode[0].height + 'px');
} catch (e) {}
},
// #endif
// 组件销毁后续处理
_handleUnmounted() {
this.active = false;

View File

@ -8,6 +8,10 @@ let config = null;
let configLoaded = false;
const timeoutMap = {};
// #ifdef APP-HARMONY
let screenWidth = 0;
// #endif
// 获取默认配置信息
function gc(key, defaultValue) {
// 这里return一个函数以解决在vue3+appvue中props默认配置读取在main.js之前执行导致uni.$zp全局配置无效的问题。相当于props的default中传入一个带有返回值的函数
@ -119,12 +123,25 @@ function convertToPx(text) {
text = text.replace('px', '');
}
if (!isNaN(text)) {
if (isRpx) return Number(uni.upx2px(text));
if (isRpx) return Number(rpx2px(text));
return Number(text);
}
return 0;
}
// rpx => px兼容鸿蒙
function rpx2px(rpx) {
// #ifdef APP-HARMONY
if (!screenWidth) {
screenWidth = uni.getSystemInfoSync().screenWidth;
}
return (screenWidth * Number.parseFloat(rpx)) / 750;
// #endif
// #ifndef APP-HARMONY
return uni.upx2px(rpx);
// #endif
}
// 获取当前时间
function getTime() {
return (new Date()).getTime();
@ -266,5 +283,6 @@ export default {
wait,
isPromise,
addUnit,
deepCopy
deepCopy,
rpx2px
};

View File

@ -4,13 +4,13 @@
/ /_____| |_) | (_| | (_| | | | | | (_| |
/___| | .__/ \__,_|\__, |_|_| |_|\__, |
|_| |___/ |___/
v2.7.11 (2024-06-28)
by ZXLee
v2.8.3 (2024-11-27)
@author ZXLee <admin@zxlee.cn>
-->
<!-- 文档地址https://z-paging.zxlee.cn -->
<!-- github地址https://github.com/SmileZXLee/uni-z-paging -->
<!-- dcloud地址https://ext.dcloud.net.cn/plugin?id=3935 -->
<!-- 反馈QQ群790460711(已满)371624008 -->
<!-- 反馈QQ群343409055 -->
<template name="z-paging">
<!-- #ifndef APP-NVUE -->
@ -44,17 +44,17 @@ by ZXLee
@scrolltoupper="_onScrollToUpper" @refresherrestore="_onRestore" @refresherrefresh="_onRefresh(true)"
>
<view class="zp-paging-touch-view"
<!-- #ifndef APP-VUE || MP-WEIXIN || MP-QQ || H5 -->
<!-- #ifndef APP-PLUS || MP-WEIXIN || MP-QQ || H5 -->
@touchstart="_refresherTouchstart" @touchmove="_refresherTouchmove" @touchend="_refresherTouchend" @touchcancel="_refresherTouchend"
<!-- #endif -->
<!-- #ifdef APP-VUE || MP-WEIXIN || MP-QQ || H5 -->
<!-- #ifdef APP-PLUS || MP-WEIXIN || MP-QQ || H5 -->
@touchstart="pagingWxs.touchstart" @touchmove="pagingWxs.touchmove" @touchend="pagingWxs.touchend" @touchcancel="pagingWxs.touchend"
@mousedown="pagingWxs.mousedown" @mousemove="pagingWxs.mousemove" @mouseup="pagingWxs.mouseup" @mouseleave="pagingWxs.mouseleave"
<!-- #endif -->
>
<view v-if="finalRefresherFixedBacHeight>0" class="zp-fixed-bac-view" :style="[{'background': refresherFixedBackground,'height': `${finalRefresherFixedBacHeight}px`}]"></view>
<view class="zp-paging-main" :style="[scrollViewInStyle,{'transform': finalRefresherTransform,'transition': refresherTransition}]"
<!-- #ifdef APP-VUE || MP-WEIXIN || MP-QQ || H5 -->
<!-- #ifdef APP-PLUS || MP-WEIXIN || MP-QQ || H5 -->
:change:prop="pagingWxs.propObserver" :prop="wxsPropType"
:data-refresherThreshold="finalRefresherThreshold" :data-refresherF2Enabled="refresherF2Enabled" :data-refresherF2Threshold="finalRefresherF2Threshold" :data-isIos="isIos"
:data-loading="loading||isRefresherInComplete" :data-useChatRecordMode="useChatRecordMode"
@ -63,7 +63,7 @@ by ZXLee
:data-refresherAecc="refresherAngleEnableChangeContinued" :data-usePageScroll="usePageScroll" :data-watchTouchDirectionChange="watchTouchDirectionChange"
:data-oldIsTouchmoving="isTouchmoving" :data-refresherOutRate="finalRefresherOutRate" :data-refresherPullRate="finalRefresherPullRate" :data-hasTouchmove="hasTouchmove"
<!-- #endif -->
<!-- #ifdef APP-VUE || H5 -->
<!-- #ifdef APP-PLUS || H5 -->
:change:renderPropIsIosAndH5="pagingRenderjs.renderPropIsIosAndH5Change" :renderPropIsIosAndH5="isIosAndH5"
<!-- #endif -->
>
@ -88,15 +88,19 @@ by ZXLee
<!-- 全屏Loading -->
<slot v-if="showLoading&&zSlots.loading&&!loadingFullFixed" name="loading" />
<!-- 主体内容 -->
<view class="zp-paging-container-content" :style="[{transform:virtualPlaceholderTopHeight>0?`translateY(${virtualPlaceholderTopHeight}px)`:'none'},finalPagingContentStyle]">
<view class="zp-paging-container-content" :style="[finalPlaceholderTopHeightStyle,finalPagingContentStyle]">
<!-- #ifdef VUE3 -->
<!-- 虚拟列表顶部占位view -->
<view v-if="useVirtualList" class="zp-virtual-placeholder" :style="[{height:virtualPlaceholderTopHeight+'px'}]"/>
<!-- #endif -->
<slot />
<!-- 内置列表&虚拟列表 -->
<template v-if="finalUseInnerList">
<slot name="header"/>
<view class="zp-list-container" :style="[innerListStyle]">
<template v-if="finalUseVirtualList">
<view class="zp-list-cell" :style="[innerCellStyle]" :id="`zp-id-${item[virtualCellIndexKey]}`" v-for="(item,index) in virtualList" :key="item['zp_unique_index']" @click="_innerCellClick(item,virtualTopRangeIndex+index)">
<view v-if="useCompatibilityMode">使用兼容模式请在组件源码z-paging.vue第99行中注释这一行并打开下面一行注释</view>
<view class="zp-list-cell" :style="[innerCellStyle]" :id="`${fianlVirtualCellIdPrefix}-${item[virtualCellIndexKey]}`" v-for="(item,index) in virtualList" :key="item['zp_unique_index']" @click="_innerCellClick(item,virtualTopRangeIndex+index)">
<view v-if="useCompatibilityMode">使用兼容模式请在组件源码z-paging.vue第103行中注释这一行并打开下面一行注释</view>
<!-- <zp-public-virtual-cell v-if="useCompatibilityMode" :extraData="extraData" :item="item" :index="virtualTopRangeIndex+index" /> -->
<slot v-else name="cell" :item="item" :index="virtualTopRangeIndex+index"/>
</view>
@ -170,7 +174,7 @@ by ZXLee
<!-- 点击返回顶部view -->
<view v-if="showBackToTopClass" :class="finalBackToTopClass" :style="[finalBackToTopStyle]" @click.stop="_backToTopClick">
<slot v-if="zSlots.backToTop" name="backToTop" />
<image v-else class="zp-back-to-top-img" :src="backToTopImg.length?backToTopImg:base64BackToTop" />
<image v-else class="zp-back-to-top-img" :class="{'zp-back-to-top-img-inversion': useChatRecordMode&&!backToTopImg.length}" :src="backToTopImg.length?backToTopImg:base64BackToTop" />
</view>
<!-- 全屏Loading(铺满z-paging并固定) -->
<view v-if="showLoading&&zSlots.loading&&loadingFullFixed" class="zp-loading-fixed">
@ -261,7 +265,7 @@ by ZXLee
</view>
</template>
<view :style="nLoadingMoreFixedHeight?{height:loadingMoreCustomStyle&&loadingMoreCustomStyle.height?loadingMoreCustomStyle.height:'80rpx'}:{}">
<view :style="nLoadingMoreFixedHeight?{height:loadingMoreCustomStyle&&loadingMoreCustomStyle.height?loadingMoreCustomStyle.height:loadingMoreFixedHeight}:{}">
<slot v-if="showLoadingMoreDefault" name="loadingMoreDefault" />
<slot v-else-if="showLoadingMoreLoading" name="loadingMoreLoading" />
<slot v-else-if="showLoadingMoreNoMore" name="loadingMoreNoMore" />
@ -298,7 +302,7 @@ by ZXLee
<!-- 点击返回顶部view -->
<view v-if="showBackToTopClass" :class="finalBackToTopClass" :style="[finalBackToTopStyle]" @click.stop="_backToTopClick">
<slot v-if="zSlots.backToTop" name="backToTop" />
<image v-else class="zp-back-to-top-img" :src="backToTopImg.length?backToTopImg:base64BackToTop" />
<image v-else class="zp-back-to-top-img" :class="{'zp-back-to-top-img-inversion': useChatRecordMode&&!backToTopImg.length}" :src="backToTopImg.length?backToTopImg:base64BackToTop" />
</view>
<!-- 全屏Loading(铺满z-paging并固定) -->
<view v-if="showLoading&&zSlots.loading&&loadingFullFixed" class="zp-loading-fixed">
@ -307,9 +311,12 @@ by ZXLee
</component>
<!-- #endif -->
</template>
<!-- #ifdef APP-VUE || MP-WEIXIN || MP-QQ || H5 -->
<!-- #ifndef APP-NVUE -->
<!-- #ifdef APP-PLUS || MP-WEIXIN || MP-QQ || H5 -->
<script src="./wxs/z-paging-wxs.wxs" module="pagingWxs" lang="wxs"></script>
<!-- #endif -->
<!-- #endif -->
<script module="pagingRenderjs" lang="renderjs">
import pagingRenderjs from './wxs/z-paging-renderjs.js';
/**
@ -332,9 +339,11 @@ by ZXLee
*/
export default {
name:"z-paging",
// #ifdef APP-VUE || H5
// #ifndef APP-NVUE
// #ifdef APP-PLUS || H5
mixins: [pagingRenderjs],
// #endif
// #endif
}
</script>
<script src="./js/z-paging-main.js" />

View File

@ -1,88 +1,89 @@
{
"id": "z-paging",
"name": "z-paging",
"displayName": "【z-paging下拉刷新、上拉加载】高性能全平台兼容。支持虚拟列表分页全自动处理",
"version": "2.7.11",
"description": "超简单、低耦合使用wxs+renderjs实现。支持自定义下拉刷新、上拉加载更多、虚拟列表、下拉进入二楼、自动管理空数据图、无闪动聊天分页、本地分页、国际化等100+项配置",
"keywords": [
"下拉刷新",
"上拉加载",
"分页器",
"nvue",
"虚拟列表"
],
"repository": "https://github.com/SmileZXLee/uni-z-paging",
"types": "global.d.ts",
"engines": {
"HBuilderX": "^3.0.7"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": "393727164"
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/z-paging",
"type": "component-vue"
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y",
"alipay": "n"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y",
"钉钉": "y",
"快手": "y",
"飞书": "y",
"京东": "y"
},
"快应用": {
"华为": "y",
"联盟": "y"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
{
"id": "z-paging",
"name": "z-paging",
"displayName": "【z-paging下拉刷新、上拉加载】高性能全平台兼容。支持虚拟列表分页全自动处理",
"version": "2.8.4",
"description": "超简单、低耦合使用wxs+renderjs实现。支持自定义下拉刷新、上拉加载更多、虚拟列表、下拉进入二楼、自动管理空数据图、无闪动聊天分页、本地分页、国际化等数百项配置",
"keywords": [
"下拉刷新",
"上拉加载",
"分页器",
"nvue",
"虚拟列表"
],
"repository": "https://github.com/SmileZXLee/uni-z-paging",
"engines": {
"HBuilderX": "^3.0.7"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": "393727164"
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/z-paging",
"type": "component-vue"
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y",
"alipay": "n"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y",
"app-harmony": "u",
"app-uvue": "u"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y",
"钉钉": "y",
"快手": "y",
"飞书": "y",
"京东": "y"
},
"快应用": {
"华为": "y",
"联盟": "y"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}

View File

@ -4,7 +4,7 @@
<img alt="logo" src="https://z-paging.zxlee.cn/img/title-logo.png" height="100" style="margin-bottom: 50px;" />
</p>
[![version](https://img.shields.io/badge/version-2.7.11-blue)](https://github.com/SmileZXLee/uni-z-paging) [![license](https://img.shields.io/github/license/SmileZXLee/uni-z-paging)](https://en.wikipedia.org/wiki/MIT_License)
[![version](https://img.shields.io/badge/version-2.8.3-blue)](https://github.com/SmileZXLee/uni-z-paging) [![license](https://img.shields.io/github/license/SmileZXLee/uni-z-paging)](https://en.wikipedia.org/wiki/MIT_License)
<img height="0" width="0" src="https://api.z-notify.zxlee.cn/v1/public/statistics/8293556910106066944/addOnly?from=uni" />
`z-paging-x`现已支持uniapp x持续完善中插件地址👉🏻 [https://ext.dcloud.net.cn/plugin?name=z-paging-x](https://ext.dcloud.net.cn/plugin?name=z-paging-x)
@ -19,14 +19,15 @@
* 【低耦合低侵入】分页自动管理。在page中无需处理任何分页相关逻辑无需在data中定义任何分页相关变量全由z-paging内部处理。
* 【超灵活支持各种类型自定义】支持自定义下拉刷新自定义上拉加载更多等各种自定义效果支持使用内置自动分页同时也支持通过监听下拉刷新和滚动到底部事件自行处理支持使用自带全屏布局规范同时也支持将z-paging自由放在任意容器中。
* 【功能丰富】支持国际化支持自定义且自动管理空数据图支持主题模式切换支持本地分页支持无闪动聊天分页模式支持展示最后更新时间支持吸顶效果支持内部scroll-view滚动与页面滚动支持一键滚动到顶部支持下拉进入二楼等诸多功能。
* 【全平台兼容】支持vue、nvuevue2、vue3支持h5、app及各家小程序。
* 【高性能】在app-vue、h5、微信小程序、QQ小程序上使用wxs+renderjs视图层实现下拉刷新;支持虚拟列表,轻松渲染万级数据!
* 【【全平台兼容】支持vue&nvuevue2&vue3js&ts支持h5、app、鸿蒙Next及各家小程序。
* 【高性能】在app-vue、h5、微信小程序、QQ小程序上使用wxs+renderjs视图层实现下拉刷新;支持虚拟列表,轻松渲染万级列表数据!
***
### 反馈qq群
* 官方1群`已满`[790460711](https://jq.qq.com/?_wv=1027&k=vU2fKZZH)
* 官方2群[371624008](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=avPmibADf2TNi4LxkIwjCE5vbfXpa-r1&authKey=dQ%2FVDAR87ONxI4b32Py%2BvmXbhnopjHN7%2FJPtdsqJdsCPFZB6zDQ17L06Uh0kITUZ&noverify=0&group_code=371624008)
* 官方2群`已满`[371624008](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=avPmibADf2TNi4LxkIwjCE5vbfXpa-r1&authKey=dQ%2FVDAR87ONxI4b32Py%2BvmXbhnopjHN7%2FJPtdsqJdsCPFZB6zDQ17L06Uh0kITUZ&noverify=0&group_code=371624008)
* 官方3群[343409055](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=sIaNqiCMIjxGQVksjytCw6R8DSiibHR7&authKey=pp995q8ZzFtl5F2xUwvvceP24QTcguWW%2FRVoDnMa8JZF4L2DmS%2B%2FV%2F5sYrcgPsmW&noverify=0&group_code=343409055)
***

View File

@ -0,0 +1,11 @@
declare module 'vue' {
export interface GlobalComponents {
['z-paging']: typeof import('./comps/z-paging')['ZPaging']
['z-paging-swiper']: typeof import('./comps/z-paging-swiper')['ZPagingSwiper']
['z-paging-swiper-item']: typeof import('./comps/z-paging-swiper-item')['ZPagingSwiperItem']
['z-paging-empty-view']: typeof import('./comps/z-paging-empty-view')['ZPagingEmptyView']
['z-paging-cell']: typeof import('./comps/z-paging-cell')['ZPagingCell']
}
}
export {}

View File

@ -0,0 +1,9 @@
export interface AllowedComponentProps {
class?: unknown;
style?: unknown;
}
export interface VNodeProps {
key?: string | number | symbol;
ref?: unknown;
}

View File

@ -0,0 +1,29 @@
import { AllowedComponentProps, VNodeProps } from './_common'
// ****************************** Props ******************************
declare interface ZPagingCellProps {
/**
* z-paging-cell样式
*/
cellStyle?: Record<string, any>
}
// ****************************** Slots ******************************
declare interface ZPagingCellSlots {
// ******************** 主体布局Slot ********************
/**
* view
*/
['default']?: () => any
}
declare interface _ZPagingCell {
new (): {
$props: AllowedComponentProps &
VNodeProps &
ZPagingCellProps
$slots: ZPagingCellSlots
}
}
export declare const ZPagingCell: _ZPagingCell

View File

@ -0,0 +1,95 @@
import { AllowedComponentProps, VNodeProps } from './_common'
// ****************************** Props ******************************
declare interface ZPagingEmptyViewProps {
/**
* z-pagingz-paging的剩余部分
* @default false
* @since 2.0.3
*/
emptyViewFixed?: boolean;
/**
*
* @default "没有数据哦~"
*/
emptyViewText?: string;
/**
* 使z-paging内置的图片
* - 使"@""/"
*/
emptyViewImg?: string;
/**
*
* @default "重新加载"
* @since 1.6.7
*/
emptyViewReloadText?: string;
/**
* view的top等
* - fixed布局`margin-top`
*/
emptyViewStyle?: Record<string, any>;
/**
* img样式
*/
emptyViewImgStyle?: Record<string, any>;
/**
*
*/
emptyViewTitleStyle?: Record<string, any>;
/**
*
* @since 1.6.7
*/
emptyViewReloadStyle?: Record<string, any>;
/**
* ()
* @default false
* @since 1.6.7
*/
showEmptyViewReload?: boolean;
/**
*
* @default false
*/
isLoadFailed?: boolean;
/**
*
* @default 'rpx'
* @since 2.6.7
*/
unit?: 'rpx' | 'px';
// ****************************** Events ******************************
/**
*
*/
onReload?: () => void
/**
* view
* @since 2.3.3
*/
onViewClick?: () => void
}
declare interface _ZPagingEmptyView {
new (): {
$props: AllowedComponentProps &
VNodeProps &
ZPagingEmptyViewProps
}
}
export declare const ZPagingEmptyView: _ZPagingEmptyView

View File

@ -0,0 +1,95 @@
import { AllowedComponentProps, VNodeProps } from './_common'
// ****************************** Props ******************************
declare interface ZPagingSwiperItemProps {
/**
* indexswiper中的第几个
* @default 0
*/
tabIndex?: number
/**
* swiper切换到第几个index
* @default 0
*/
currentIndex?: number
/**
* 使使nvue时nvue中z-paging内置了list组件
* @default false
*/
useVirtualList?: boolean
/**
* cell高度模式`fixed`cell高度完全相同cell高度为准进行计算
* @default 'fixed'
*/
cellHeightMode?: 'fixed' | 'dynamic'
/**
* ()dom越多()
* @default 12
*/
preloadPage?: number | string
/**
* 122
* @default 1
* @since 2.2.8
*/
virtualListCol?: number | string
/**
* scroll取样帧率80
* @default 80
*/
virtualScrollFps?: number | string
/**
* z-paging内部循环渲染列表(使)
* @default false
*/
useInnerList?: boolean
/**
* cell的key名称(nvue有效nvue中开启use-inner-list时必须填此项)
* @since 2.2.7
*/
cellKeyName?: string
/**
* innerList样式
*/
innerListStyle?: Record<string, any>
}
// ****************************** Methods ******************************
declare interface _ZPagingSwiperItemRef {
/**
* pageNo恢复为默认值
*
* @param [animate=false]
*/
reload: (animate?: boolean) => void;
/**
*
* - complete传进去的数组长度小于pageSize时
*
* @param [data]
* @param [success=true]
*/
complete: (data?: any[] | false, success?: boolean) => void;
}
declare interface _ZPagingSwiperItem {
new (): {
$props: AllowedComponentProps &
VNodeProps &
ZPagingSwiperItemProps
}
}
export declare const ZPagingSwiperItem: _ZPagingSwiperItem
export declare const ZPagingSwiperItemRef: _ZPagingSwiperItemRef

View File

@ -0,0 +1,89 @@
import { AllowedComponentProps, VNodeProps } from './_common'
// ****************************** Props ******************************
declare interface ZPagingSwiperProps {
/**
* 使fixed布局使fixed布局z-paging-swiper的父view无需固定高度z-paging高度默认铺满屏幕view请放z-paging-swiper标签内view使用slot="top"view使用slot="bottom"
* @default true
*/
fixed?: boolean
/**
*
* @default false
*/
safeAreaInsetBottom?: boolean
/**
* z-paging-swiper样式
*/
swiperStyle?: Record<string, any>
}
// ****************************** Slots ******************************
declare interface ZPagingSwiperSlots {
// ******************** 主体布局Slot ********************
/**
* view
*/
['default']?: () => any
/**
* tab-view等需要固定的()slot="top"view中
* view时view包住它们view上设置slot="top"需要固定在顶部的view请勿设置position: fixed;
* @since 1.5.5
*/
['top']?: () => any
/**
* ()slot="bottom"view中
* view时view包住它们view上设置slot="bottom"需要固定在底部的view请勿设置position: fixed;
* @since 1.6.2
*/
['bottom']?: () => any
/**
* ()slot="left"view中
* view时view包住它们view上设置slot="left"需要固定在左侧的view请勿设置position: fixed;
* @since 2.2.3
*/
['left']?: () => any
/**
* ()slot="right"view中
* view时view包住它们view上设置slot="right"需要固定在右侧的view请勿设置position: fixed;
* @since 2.2.3
*/
['right']?: () => any
}
// ****************************** Methods ******************************
declare interface _ZPagingSwiperRef {
/**
* slot="left"slot="right"slot="left"slot="right"
*
* @since 2.3.5
*/
updateLeftAndRightWidth: () => void;
/**
* fixed模式下z-paging-swiper的布局onShow时候调用iOS+h5+tabbar+fixed+tabbar页面跳转到无tabbar页面后返回
*
* @since 2.6.5
*/
updateFixedLayout: () => void;
}
declare interface _ZPagingSwiper {
new (): {
$props: AllowedComponentProps &
VNodeProps &
ZPagingSwiperProps
$slots: ZPagingSwiperSlots
}
}
export declare const ZPagingSwiper: _ZPagingSwiper
export declare const ZPagingSwiperRef: _ZPagingSwiperRef

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,24 @@
/// <reference path="./comps.d.ts" />
declare module 'z-paging' {
export function install() : void
/**
* z-paging全局配置
* - uni.$zp
*
* @since 2.6.5
*/
interface $zp {
/**
*
*/
config : Record<string, any>;
}
global {
interface Uni {
$zp : $zp
}
}
}
declare type ZPagingSwiperRef = typeof import('./comps/z-paging-swiper')['ZPagingSwiperRef']
declare type ZPagingSwiperItemRef = typeof import('./comps/z-paging-swiper-item')['ZPagingSwiperItemRef']