收货地址,轮播广告

This commit is contained in:
xiaoshan
2023-10-23 18:11:59 +08:00
parent 317a8bc93e
commit 17793e7227
41 changed files with 11550 additions and 195 deletions

View File

@@ -1,12 +1,6 @@
## 2.5.82023-05-03
1.`新增` props`refresher-no-transform`支持控制下拉刷新时是否禁止下拉刷新view跟随用户触摸竖直移动
2.`新增` props`refresher-refreshing-animated`,支持控制下拉刷新刷新中状态下是否展示旋转动画
3.`新增` vue3中页面滚动hooks
4.`新增` 全局拦截器-`@query`拦截器中回调函数添加当前列表最后一个item数据
5.`修复` 在vue3+内置浏览器中,报错`SyntaxError: Unexpected token . at xxx`的问题。
6.`修复` 滑动切换选项卡简化写法queryList触发多次的问题。
7.`优化` 底部加载更多展示逻辑,在各个平台中过渡更加自然。
8.`优化` `@touchDirectionChange`触发逻辑,仅在值改变时触发,优化性能。
## 2.5.72023-03-14
1.`修复` 在nvue+安卓中,设置`empty-view-center`为false后空数据图被切割未能完整显示的问题。
2.`修复``2.5.4`引出的在nvue中使用`slot="top"`后下拉刷新失效的问题。
## 2.6.02023-10-17
1.`修复` 在安卓中突然滚动到顶部可能出现的无法下拉刷新问题
2.`修复` 在安卓中可能出现的列表卡住和无法下拉的问题
3.`修复` 在安卓6.0以下系统中列表为空的问题
4.`优化` 列表滚动-下拉刷新状态过渡细节

View File

@@ -71,10 +71,10 @@
return {};
}
},
//预加载的列表可视范围(列表高度)页数,默认为7,即预加载当前页及上下各7页的cell。此数值越大则虚拟列表中加载的dom越多内存消耗越大(会维持在一个稳定值),但增加预加载页面数量可缓解快速滚动短暂白屏问题
//预加载的列表可视范围(列表高度)页数,默认为12,即预加载当前页及上下各12页的cell。此数值越大则虚拟列表中加载的dom越多内存消耗越大(会维持在一个稳定值),但增加预加载页面数量可缓解快速滚动短暂白屏问题
preloadPage: {
type: [Number, String],
default: 7
default: 12
},
//虚拟列表cell高度模式默认为fixed也就是每个cell高度完全相同将以第一个cell高度为准进行计算。可选值【dynamic】即代表高度是动态非固定的【dynamic】性能低于【fixed】。
cellHeightMode: {
@@ -104,7 +104,7 @@
delay = 100;
// #endif
setTimeout(() => {
this.$refs.paging.reload();
this.$refs.paging.reload().catch(() => {});
}, delay);
})
}
@@ -115,11 +115,11 @@
},
methods: {
reload(data) {
this.$refs.paging.reload(data);
return this.$refs.paging.reload(data);
},
complete(data) {
this.firstLoaded = true;
this.$refs.paging.complete(data);
return this.$refs.paging.complete(data);
},
_queryList(pageNo, pageSize, from) {
this.$emit('query', pageNo, pageSize, from);

View File

@@ -130,6 +130,7 @@
.zp-swiper-super {
flex: 1;
overflow: hidden;
position: relative;
/* #ifndef APP-NVUE */
display: flex;

View File

@@ -45,7 +45,7 @@
return this.c.defaultThemeStyle;
},
c() {
return this.zConfig;
return this.zConfig || {};
},
ownLoadingMoreText() {
const statusTextArr = [this.c.defaultText,this.c.loadingText,this.c.noMoreText,this.c.failText];

View File

@@ -41,6 +41,7 @@
.zp-scroll-view-super {
flex: 1;
overflow: hidden;
position: relative;
}

View File

@@ -7,7 +7,7 @@ function useZPaging(paging) {
onPullDownRefresh(() => {
if (!cPaging) return;
cPaging.value.reload();
cPaging.value.reload().catch(() => {});
})
onPageScroll(e => {

View File

@@ -6,7 +6,7 @@ function useZPagingComp(paging) {
const reload = () => {
if (!cPaging) return;
cPaging.value.reload();
cPaging.value.reload().catch(() => {});
}
const updatePageScrollTop = scrollTop => {
if (!cPaging) return;

View File

@@ -36,7 +36,7 @@ export default {
isOldWebView() {
// #ifndef APP-NVUE || MP-KUAISHOU
try {
const systemInfos = systemInfo.system.split(' ');
const systemInfos = uni.getSystemInfoSync().system.split(' ');
const deviceType = systemInfos[0];
const version = parseInt(systemInfos[1]);
if ((deviceType === 'iOS' && version <= 10) || (deviceType === 'Android' && version <= 6)) {

View File

@@ -152,6 +152,7 @@ export default {
fromEmptyViewReload: false,
queryFrom: '',
listRendering: false,
isHandlingRefreshToPage: false
}
},
computed: {
@@ -277,12 +278,13 @@ export default {
},
//从顶部添加数据不会影响分页的pageNo和pageSize
addDataFromTop(data, toTop = true, toTopWithAnimate = true) {
data = Object.prototype.toString.call(data) !== '[object Array]' ? [data] : data;
data = Object.prototype.toString.call(data) !== '[object Array]' ? [data] : data.reverse();
// #ifndef APP-NVUE
this.finalUseVirtualList && this._setCellIndex(data, 'top')
// #endif
this.totalData = [...data, ...this.totalData];
if (toTop) {
u.delay(() => {
this._scrollToTop(toTopWithAnimate);
})
u.delay(() => this._scrollToTop(toTopWithAnimate));
}
},
//重新设置列表数据调用此方法不会影响pageNo和pageSize也不会触发请求。适用场景当需要删除列表中某一项时将删除对应项后的数组通过此方法传递给z-paging。(当出现类似的需要修改列表数组的场景时请使用此方法请勿直接修改page中:list.sync绑定的数组)
@@ -341,19 +343,12 @@ export default {
},
//刷新列表数据pageNo和pageSize不会重置列表数据会重新从服务端获取。必须保证@query绑定的方法中的pageNo和pageSize和传给服务端的一致
refresh() {
if (!this.realTotalData.length) return this.reload();
const disPageNo = this.pageNo - this.defaultPageNo + 1;
if (disPageNo >= 1) {
this.loading = true;
this.privateConcat = false;
const totalPageSize = disPageNo * this.pageSize;
this.currentRefreshPageSize = totalPageSize;
this._emitQuery(this.defaultPageNo, totalPageSize, Enum.QueryFrom.Refresh);
this._callMyParentQuery(this.defaultPageNo, totalPageSize);
}
return new Promise((resolve, reject) => {
this.dataPromiseResultMap.reload = { resolve, reject };
});
return this._handleRefreshWithDisPageNo(this.pageNo - this.defaultPageNo + 1);
},
//刷新列表数据至指定页例如pageNo=5时则代表刷新列表至第5页此时pageNo会变为5列表会展示前5页的数据。必须保证@query绑定的方法中的pageNo和pageSize和传给服务端的一致
refreshToPage(pageNo) {
this.isHandlingRefreshToPage = true;
return this._handleRefreshWithDisPageNo(pageNo + this.defaultPageNo - 1);
},
//手动更新列表缓存数据将自动截取v-model绑定的list中的前pageSize条覆盖缓存请确保在list数据更新到预期结果后再调用此方法
updateCache() {
@@ -376,6 +371,13 @@ export default {
},
//reload之前的一些处理
_preReload(animate = this.showRefresherWhenReload, isFromMounted = true) {
const showRefresher = this.finalRefresherEnabled && this.useCustomRefresher;
// #ifndef APP-NVUE
if (this.customRefresherHeight === -1 && showRefresher) {
u.delay(() => this._preReload(animate, isFromMounted), c.delayTime / 2);
return;
}
// #endif
this.isUserReload = true;
this.loadingType = Enum.LoadingType.Refresher;
if (animate) {
@@ -466,9 +468,7 @@ export default {
if (!this.isFirstPage) {
this.listRendering = true;
this.$nextTick(() => {
u.delay(() => {
this.listRendering = false;
})
u.delay(() => this.listRendering = false);
})
} else {
this.listRendering = false;
@@ -518,10 +518,18 @@ export default {
this._callDataPromise(true, this.totalData);
}, dataChangeDelayTime)
}
if (this.isHandlingRefreshToPage) {
this.isHandlingRefreshToPage = false;
this.pageNo = this.defaultPageNo + Math.ceil(data.length / this.pageSize) - 1;
if (data.length % this.pageSize !== 0) {
this.customNoMore = 1;
}
}
} else {
this._currentDataChange(data, this.currentData);
this._callDataPromise(false);
this.loadingStatus = Enum.More.Fail;
this.isHandlingRefreshToPage = false;
if (this.loadingType === Enum.LoadingType.LoadingMore) {
this.pageNo --;
}
@@ -569,7 +577,7 @@ export default {
_currentDataChange(newVal, oldVal) {
newVal = [...newVal];
// #ifndef APP-NVUE
this.finalUseVirtualList && this._setCellIndex(newVal, this.totalData.length === 0)
this.finalUseVirtualList && this._setCellIndex(newVal, 'bottom');
this.useChatRecordMode && newVal.reverse();
// #endif
if (this.isFirstPage && this.finalConcat) {
@@ -643,6 +651,21 @@ export default {
}
this.privateConcat = true;
},
//根据pageNo处理refresh操作
_handleRefreshWithDisPageNo(pageNo) {
if (!this.realTotalData.length) return this.reload();
if (pageNo >= 1) {
this.loading = true;
this.privateConcat = false;
const totalPageSize = pageNo * this.pageSize;
this.currentRefreshPageSize = totalPageSize;
this._emitQuery(this.defaultPageNo, totalPageSize, Enum.QueryFrom.Refresh);
this._callMyParentQuery(this.defaultPageNo, totalPageSize);
}
return new Promise((resolve, reject) => {
this.dataPromiseResultMap.reload = { resolve, reject };
});
},
//本地分页请求
_localPagingQueryList(pageNo, pageSize, localPagingLoadingTime, callback) {
pageNo = Math.max(1, pageNo);
@@ -696,7 +719,8 @@ export default {
_callDataPromise(success, totalList) {
for (const key in this.dataPromiseResultMap) {
const obj = this.dataPromiseResultMap[key];
success ? (!!obj && obj.resolve({ totalList, noMore: this.loadingStatus === Enum.More.NoMore })) : (!!obj && obj.reject());
if (!obj) break;
success ? obj.resolve({ totalList, noMore: this.loadingStatus === Enum.More.NoMore }) : obj.reject(`z-paging-${key}-error`);
}
},
//检查complete data的类型

View File

@@ -128,14 +128,14 @@ export default {
this.$emit('emptyViewReload', reload => {
if (reload === undefined || reload === true) {
this.fromEmptyViewReload = true;
this.reload();
this.reload().catch(() => {});
}
callbacked = true;
});
this.$nextTick(() => {
if (!callbacked) {
this.fromEmptyViewReload = true;
this.reload();
this.reload().catch(() => {});
}
})
},

View File

@@ -7,10 +7,11 @@ import u from '.././z-paging-utils'
import c from '.././z-paging-constant'
import interceptor from '../z-paging-interceptor'
const language = uni.getSystemInfoSync().language;
export default {
data() {
return {
language: uni.getSystemInfoSync().language
language
}
},
computed: {

View File

@@ -205,9 +205,9 @@ export default {
}
}
},
//触发加载更多时调用,from:0-滑动到底部触发1-点击加载更多触发
//触发加载更多时调用,from:toBottom-滑动到底部触发1、click-点击加载更多触发
_onLoadingMore(from = 'click') {
if (from === 'toBottom' && !this.scrollToBottomBounceEnabled && this.scrollEnable) {
if (this.isIos && from === 'toBottom' && !this.scrollToBottomBounceEnabled && this.scrollEnable) {
this.scrollEnable = false;
this.$nextTick(() => {
this.scrollEnable = true;

View File

@@ -231,7 +231,8 @@ export default {
oldRefresherTouchmoveY: 0,
oldTouchDirection: '',
oldEmitedTouchDirection: '',
oldPullingDistance: -1
oldPullingDistance: -1,
refresherThresholdUpdateTag: 0
}
},
watch: {
@@ -305,13 +306,7 @@ export default {
showRefresher() {
const showRefresher = this.finalRefresherEnabled && this.useCustomRefresher;
// #ifndef APP-NVUE
if (this.customRefresherHeight === -1 && showRefresher) {
u.delay(() => {
this.$nextTick(()=>{
this._updateCustomRefresherHeight();
})
})
}
this.customRefresherHeight === -1 && showRefresher && u.delay(() => this.$nextTick(this._updateCustomRefresherHeight));
// #endif
return showRefresher;
},
@@ -330,11 +325,14 @@ export default {
},
methods: {
//终止下拉刷新状态
endRefresh(){
endRefresh() {
this.totalData = this.realTotalData;
this._refresherEnd();
this._endSystemLoadingAndRefresh();
this._handleScrollViewDisableBounce({ bounce: true });
this.$nextTick(() => {
this.refresherTriggered = false;
})
},
handleRefresherStatusChanged(func) {
this.refresherStatusChangedFunc = func;
@@ -506,7 +504,7 @@ export default {
},
//处理scroll-view bounce是否生效
_handleScrollViewDisableBounce({ bounce }) {
if (!this.usePageScroll && !this.scrollToTopBounceEnabled) {
if (!this.usePageScroll && !this.scrollToTopBounceEnabled && this.wxsScrollTop <= 5) {
// #ifdef APP-VUE || MP-WEIXIN || MP-QQ || H5
this.refresherTransition = '';
// #endif
@@ -589,9 +587,7 @@ export default {
}, refresherCompleteDelay);
}
if (setLoading) {
u.delay(() => {
this.loading = false;
}, shouldEndLoadingDelay ? c.delayTime : 0);
u.delay(() => this.loading = false, shouldEndLoadingDelay ? c.delayTime : 0);
isUserPullDown && this._onRestore();
}
},

View File

@@ -217,8 +217,7 @@ export default {
this.$nextTick(() => {
this.oldScrollTop = 0;
})
if (!this.useChatRecordMode || this.loadingStatus === Enum.More.NoMore) return;
this._onLoadingMore('click');
this.useChatRecordMode && this.loadingStatus !== Enum.More.NoMore && this._onLoadingMore('click');
},
//当滚动到底部时
_onScrollToLower(e) {
@@ -418,11 +417,14 @@ export default {
this.$emit('scrollTopChange', newVal);
this.$emit('update:scrollTop', newVal);
this._checkShouldShowBackToTop(newVal);
const scrollTop = this.isIos ? (newVal > 5 ? 6 : 0) : newVal;
if (isPageScrollTop) {
const scrollTop = this.isIos ? (newVal > 5 ? 6 : 0) : (newVal > 105 ? 106 : (newVal > 5 ? 6 : 0));
if (isPageScrollTop && this.wxsPageScrollTop !== scrollTop) {
this.wxsPageScrollTop = scrollTop;
} else {
} else if (!isPageScrollTop && this.wxsScrollTop !== scrollTop) {
this.wxsScrollTop = scrollTop;
if (scrollTop > 6) {
this.scrollEnable = true;
}
}
},
//更新使用页面滚动时slot="top"或"bottom"插入view的高度

View File

@@ -51,10 +51,10 @@ export default {
return u.gc('innerCellStyle', {});
}
},
//预加载的列表可视范围(列表高度)页数,默认为7,即预加载当前页及上下各7页的cell。此数值越大则虚拟列表中加载的dom越多内存消耗越大(会维持在一个稳定值),但增加预加载页面数量可缓解快速滚动短暂白屏问题
//预加载的列表可视范围(列表高度)页数,默认为12,即预加载当前页及上下各12页的cell。此数值越大则虚拟列表中加载的dom越多内存消耗越大(会维持在一个稳定值),但增加预加载页面数量可缓解快速滚动短暂白屏问题
preloadPage: {
type: [Number, String],
default: u.gc('preloadPage', 7),
default: u.gc('preloadPage', 12),
validator: (value) => {
if (value <= 0) u.consoleErr('preload-page必须大于0');
return value > 0;
@@ -90,6 +90,7 @@ export default {
virtualBottomRangeIndex: 0,
lastVirtualTopRangeIndex: 0,
lastVirtualBottomRangeIndex: 0,
virtualItemInsertedCount: 0,
virtualHeightCacheList: [],
@@ -121,6 +122,9 @@ export default {
}
},
computed: {
virtualCellIndexKey() {
return c.listCellIndexKey;
},
finalUseVirtualList() {
if (this.useVirtualList && this.usePageScroll){
u.consoleErr('使用页面滚动时,开启虚拟列表无效!');
@@ -149,36 +153,75 @@ export default {
},
},
methods: {
//在使用动态高度虚拟列表时,手动更新指定cell的缓存高度(当cell高度在初始化之后再次改变时调用)index代表需要更新的cell在列表中的位置从0开始
//在使用动态高度虚拟列表时,若在列表数组中需要插入某个item需要调用此方法item:需要插入的itemindex:插入的cell位置若index为2则插入的item在原list的index=1之后index从0开始
doInsertVirtualListItem(item, index) {
if (this.cellHeightMode !== Enum.CellHeightMode.Dynamic) return;
this.virtualItemInsertedCount ++;
if (!item || Object.prototype.toString.call(item) !== '[object Object]') {
item = { item };
}
const cellIndexKey = this.virtualCellIndexKey;
item[cellIndexKey] = `custom-${this.virtualItemInsertedCount}`;
item[c.listCellIndexUniqueKey] = `${this.virtualListKey}-${item[cellIndexKey]}`;
this.totalData.splice(index, 0, item);
this.$nextTick(async () => {
let retryCount = 0;
while (retryCount <= 10) {
await u.wait(c.delayTime);
const cellNode = await this._getNodeClientRect(`#zp-id-${item[cellIndexKey]}`, this.finalUseInnerList);
if (!cellNode) {
retryCount ++;
continue;
}
const currentHeight = cellNode ? cellNode[0].height : 0;
const lastHeightCache = this.virtualHeightCacheList[index - 1];
const lastTotalHeight = lastHeightCache ? lastHeightCache.totalHeight : 0;
this.virtualHeightCacheList.splice(index, 0, {
height: currentHeight,
lastTotalHeight,
totalHeight: lastTotalHeight + currentHeight
});
for (let i = index + 1; i < this.virtualHeightCacheList.length; i++) {
const thisNode = this.virtualHeightCacheList[i];
thisNode.lastTotalHeight += currentHeight;
thisNode.totalHeight += currentHeight;
}
this._updateVirtualScroll(this.oldScrollTop);
break;
}
})
},
//在使用动态高度虚拟列表时手动更新指定cell的缓存高度(当cell高度在初始化之后再次改变时调用)index:需要更新的cell在列表中的位置从0开始
didUpdateVirtualListCell(index) {
if (this.cellHeightMode !== Enum.CellHeightMode.Dynamic) return;
const currentNode = this.virtualHeightCacheList[index];
this._getNodeClientRect(`#zp-id-${index}`, this.finalUseInnerList).then(cellNode => {
const cellNodeHeight = cellNode ? cellNode[0].height : 0;
const heightDis = cellNodeHeight - currentNode.height;
currentNode.height = cellNodeHeight;
currentNode.totalHeight = currentNode.lastHeight + cellNodeHeight;
for (let i = index + 1; i < this.virtualHeightCacheList.length; i++) {
const thisNode = this.virtualHeightCacheList[i];
if (i === index + 1) {
thisNode.lastHeight = cellNodeHeight;
this.$nextTick(() => {
this._getNodeClientRect(`#zp-id-${index}`, this.finalUseInnerList).then(cellNode => {
const cellNodeHeight = cellNode ? cellNode[0].height : 0;
const heightDis = cellNodeHeight - currentNode.height;
currentNode.height = cellNodeHeight;
currentNode.totalHeight = currentNode.lastTotalHeight + cellNodeHeight;
for (let i = index + 1; i < this.virtualHeightCacheList.length; i++) {
const thisNode = this.virtualHeightCacheList[i];
thisNode.totalHeight += heightDis;
thisNode.lastTotalHeight += heightDis;
}
thisNode.totalHeight += heightDis;
}
});
});
})
},
//在使用动态高度虚拟列表时若删除了列表数组中的某个item需要调用此方法以更新高度缓存数组index代表需要更新的cell在列表中的位置从0开始
//在使用动态高度虚拟列表时若删除了列表数组中的某个item需要调用此方法以更新高度缓存数组index:删除的cell在列表中的位置从0开始
didDeleteVirtualListCell(index) {
if (this.cellHeightMode !== Enum.CellHeightMode.Dynamic) return;
const currentNode = this.virtualHeightCacheList[index];
for (let i = index + 1; i < this.virtualHeightCacheList.length; i++) {
const thisNode = this.virtualHeightCacheList[i];
if (i === index + 1) {
thisNode.lastHeight = currentNode.lastHeight;
}
thisNode.totalHeight -= currentNode.height;
thisNode.lastTotalHeight -= currentNode.height;
}
this.virtualHeightCacheList.splice(index, 1);
},
@@ -213,40 +256,63 @@ export default {
})
},
//cellHeightMode为dynamic时获取每个cell高度
_updateDynamicCellHeight(list) {
_updateDynamicCellHeight(list, dataFrom = 'bottom') {
const dataFromTop = dataFrom === 'top';
const heightCacheList = this.virtualHeightCacheList;
const currentCacheList = dataFromTop ? [] : heightCacheList;
let listTotalHeight = 0;
this.$nextTick(() => {
u.delay(async () => {
for (let i = 0; i < list.length; i++) {
let item = list[i];
const cellNode = await this._getNodeClientRect(`#zp-id-${item[c.listCellIndexKey]}`, this.finalUseInnerList);
const cellNode = await this._getNodeClientRect(`#zp-id-${list[i][this.virtualCellIndexKey]}`, this.finalUseInnerList);
const currentHeight = cellNode ? cellNode[0].height : 0;
if (!cellNode) {
this.virtualHeightCacheList = this.virtualHeightCacheList.slice(-i);
if (this.getCellHeightRetryCount.dynamic > 10) return;
this.getCellHeightRetryCount.dynamic ++;
this._updateDynamicCellHeight(list);
break;
}
const lastHeightCache = this.virtualHeightCacheList.length ? this.virtualHeightCacheList.slice(-1)[0] : null;
const lastHeight = lastHeightCache ? lastHeightCache.totalHeight : 0;
this.virtualHeightCacheList.push({
if (this.getCellHeightRetryCount.dynamic <= 10) {
heightCacheList.splice(heightCacheList.length - i, i);
this.getCellHeightRetryCount.dynamic ++;
this._updateDynamicCellHeight(list, dataFrom);
}
return;
}
const lastHeightCache = currentCacheList.length ? currentCacheList.slice(-1)[0] : null;
const lastTotalHeight = lastHeightCache ? lastHeightCache.totalHeight : 0;
currentCacheList.push({
height: currentHeight,
lastHeight,
totalHeight: lastHeight + currentHeight
lastTotalHeight,
totalHeight: lastTotalHeight + currentHeight
});
if (dataFromTop) {
listTotalHeight += currentHeight;
}
}
if (dataFromTop && list.length) {
for (let i = 0; i < heightCacheList.length; i++) {
const heightCacheItem = heightCacheList[i];
heightCacheItem.lastTotalHeight += listTotalHeight;
heightCacheItem.totalHeight += listTotalHeight;
}
this.virtualHeightCacheList = currentCacheList.concat(heightCacheList);
}
this._updateVirtualScroll(this.oldScrollTop);
}, c.delayTime, 'updateDynamicCellHeightDelay')
})
},
//设置cellItem的index
_setCellIndex(list, isFirstPage) {
let lastItemIndex = 0;
if (!isFirstPage) {
lastItemIndex = this.realTotalData.length;
const lastItem = this.realTotalData.length ? this.realTotalData.slice(-1)[0] : null;
if (lastItem && lastItem[c.listCellIndexKey] !== undefined) {
lastItemIndex = lastItem[c.listCellIndexKey] + 1;
_setCellIndex(list, dataFrom = 'bottom') {
let currentItemIndex = 0;
const cellIndexKey = this.virtualCellIndexKey;
if (this.totalData.length) {
if (dataFrom === 'bottom') {
currentItemIndex = this.realTotalData.length;
const lastItem = this.realTotalData.length ? this.realTotalData.slice(-1)[0] : null;
if (lastItem && lastItem[cellIndexKey] !== undefined) {
currentItemIndex = lastItem[cellIndexKey] + 1;
}
} else if (dataFrom === 'top') {
const firstItem = this.realTotalData.length ? this.realTotalData[0] : null;
if (firstItem && firstItem[cellIndexKey] !== undefined) {
currentItemIndex = firstItem[cellIndexKey] - list.length;
}
}
} else {
this._resetDynamicListState();
@@ -256,12 +322,12 @@ export default {
if (!item || Object.prototype.toString.call(item) !== '[object Object]') {
item = { item };
}
item[c.listCellIndexKey] = lastItemIndex + i;
item[c.listCellIndexUniqueKey] = `${this.virtualListKey}-${item[c.listCellIndexKey]}`;
item[cellIndexKey] = currentItemIndex + i;
item[c.listCellIndexUniqueKey] = `${this.virtualListKey}-${item[cellIndexKey]}`;
list[i] = item;
}
this.getCellHeightRetryCount.dynamic = 0;
this.cellHeightMode === Enum.CellHeightMode.Dynamic && this._updateDynamicCellHeight(list);
this.cellHeightMode === Enum.CellHeightMode.Dynamic && this._updateDynamicCellHeight(list, dataFrom);
},
//更新scroll滚动
_updateVirtualScroll(scrollTop, scrollDiff = 0) {
@@ -296,7 +362,7 @@ export default {
const heightCacheItem = heightCacheList[i];
if (heightCacheItem && heightCacheItem.totalHeight > topRangePageOffset) {
this.virtualTopRangeIndex = i;
this.virtualPlaceholderTopHeight = heightCacheItem.lastHeight;
this.virtualPlaceholderTopHeight = heightCacheItem.lastTotalHeight;
break;
}
}
@@ -306,7 +372,7 @@ export default {
const heightCacheItem = heightCacheList[i];
if (heightCacheItem && heightCacheItem.totalHeight < topRangePageOffset) {
this.virtualTopRangeIndex = i;
this.virtualPlaceholderTopHeight = heightCacheItem.lastHeight;
this.virtualPlaceholderTopHeight = heightCacheItem.lastTotalHeight;
topRangeMatched = true;
break;
}
@@ -334,7 +400,7 @@ export default {
},
//更新fixedCell模式下topRangeIndex&placeholderTopHeight
_updateFixedTopRangeIndex(scrollIndex) {
let virtualTopRangeIndex = this.virtualCellHeight === 0 ? 0 : scrollIndex - parseInt(this.finalVirtualPageHeight / this.virtualCellHeight) * this.preloadPage;
let virtualTopRangeIndex = this.virtualCellHeight === 0 ? 0 : scrollIndex - (parseInt(this.finalVirtualPageHeight / this.virtualCellHeight) || 1) * this.preloadPage;
virtualTopRangeIndex *= this.virtualListCol;
virtualTopRangeIndex = Math.max(0, virtualTopRangeIndex);
this.virtualTopRangeIndex = virtualTopRangeIndex;
@@ -342,7 +408,7 @@ export default {
},
//更新fixedCell模式下bottomRangeIndex&placeholderBottomHeight
_updateFixedBottomRangeIndex(scrollIndex) {
let virtualBottomRangeIndex = this.virtualCellHeight === 0 ? this.pageSize : scrollIndex + parseInt(this.finalVirtualPageHeight / this.virtualCellHeight) * (this.preloadPage + 1);
let virtualBottomRangeIndex = this.virtualCellHeight === 0 ? this.pageSize : scrollIndex + (parseInt(this.finalVirtualPageHeight / this.virtualCellHeight) || 1) * (this.preloadPage + 1);
virtualBottomRangeIndex *= this.virtualListCol;
virtualBottomRangeIndex = Math.min(this.realTotalData.length, virtualBottomRangeIndex);
this.virtualBottomRangeIndex = virtualBottomRangeIndex;

View File

@@ -1,7 +1,7 @@
// [z-paging]常量
export default {
version: '2.5.7',
version: '2.5.9',
delayTime: 100,
errorUpdateKey: 'z-paging-error-emit',
completeUpdateKey: 'z-paging-complete-emit',

View File

@@ -69,6 +69,7 @@ export default {
disabledBounce: false,
fromCompleteEmit: false,
disabledCompleteEmit: false,
pageLaunched: false,
//---------------wxs相关---------------
wxsIsScrollTopInTopRange: true,
@@ -176,7 +177,7 @@ export default {
created(){
if (this.createdReload && !this.refresherOnly && this.auto) {
this._startLoading();
this._preReload();
this.$nextTick(this._preReload);
}
},
mounted() {
@@ -188,7 +189,7 @@ export default {
this.finalUseCache && this._setListByLocalCache();
let delay = 0;
// #ifdef H5 || MP
delay = 100;
delay = c.delayTime;
// #endif
this.$nextTick(() => {
this.systemInfo = uni.getSystemInfoSync();
@@ -323,8 +324,28 @@ export default {
}
!this.usePageScroll && this.$refs['zp-n-list'].setSpecialEffects(args);
},
// #ifdef APP-VUE
//当app长时间进入后台后进入前台因系统内存管理导致app重新加载时进行一些适配处理
_handlePageLaunch() {
// 首次触发不进行处理只有进入后台后打开app重新加载时才处理
if (this.pageLaunched) {
// 解决在vue3+ios中app ReLaunch时顶部下拉刷新展示位置向下偏移的问题
// #ifdef VUE3
this.refresherThresholdUpdateTag = 1;
this.$nextTick(() => {
this.refresherThresholdUpdateTag = 0;
})
// #endif
// 解决使用虚拟列表时app ReLaunch时白屏问题
this._checkVirtualListScroll();
}
this.pageLaunched = true;
},
// #endif
//使手机发生较短时间的振动15ms
_doVibrateShort() {
// #ifndef H5
// #ifdef APP-PLUS
if (this.isIos) {
const UISelectionFeedbackGenerator = plus.ios.importClass('UISelectionFeedbackGenerator');
@@ -340,6 +361,8 @@ export default {
// #ifndef APP-PLUS
uni.vibrateShort();
// #endif
// #endif
},
//设置z-paging高度
async _setAutoHeight(shouldFullHeight = true, scrollViewNode = null) {
@@ -381,7 +404,7 @@ export default {
//添加全局emit监听
_onEmit() {
uni.$on(c.errorUpdateKey, () => {
this.loading && this.complete(false);
this.loading && this.complete(false).catch(() => {});
})
uni.$on(c.completeUpdateKey, (data) => {
setTimeout(() => {

View File

@@ -3,7 +3,7 @@
export default {
onPullDownRefresh() {
if (this.isPagingRefNotFound()) return;
this.$refs.paging.reload();
this.$refs.paging.reload().catch(() => {});
},
onPageScroll(e) {
if (this.isPagingRefNotFound()) return;

View File

@@ -159,6 +159,13 @@ function getInstanceId() {
return s.join('') + getTime();
}
// 等待一段时间
function wait(ms) {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}
//------------------ 私有方法 ------------------------
//时间格式化
function _timeFormat(time, textMap) {
@@ -216,5 +223,6 @@ export default {
getTime,
getInstanceId,
consoleErr,
delay
delay,
wait
};

View File

@@ -6,15 +6,18 @@ const data = {
isTouchFromZPaging: false,
isUsePageScroll: false,
isReachedTop: true,
isIosAndH5: false
isIosAndH5: false,
appLaunched: false
}
export default {
mounted() {
this._handleTouch();
// #ifdef APP-VUE
this.$ownerInstance && this.$ownerInstance.callMethod('_checkVirtualListScroll');
// #endif
if (window) {
this._handleTouch();
// #ifdef APP-VUE
this.$ownerInstance.callMethod('_handlePageLaunch');
// #endif
}
},
methods: {
//接收逻辑层发送的数据
@@ -24,7 +27,7 @@ export default {
},
//拦截处理touch事件
_handleTouch() {
if (window && !window.$zPagingRenderJsInited) {
if (!window.$zPagingRenderJsInited) {
window.$zPagingRenderJsInited = true;
window.addEventListener('touchstart', this._handleTouchstart, { passive: true })
window.addEventListener('touchmove', this._handleTouchmove, { passive: false })

View File

@@ -84,9 +84,7 @@ function touchmove(e, ownerIns) {
return true;
}
if (prevent && !state.disabledBounce) {
if (isIos) {
ownerIns.callMethod('_handleScrollViewDisableBounce', {bounce: false});
}
ownerIns.callMethod('_handleScrollViewDisableBounce', {bounce: false});
state.disabledBounce = true;
_handlePullingDown(state, ownerIns, prevent);
return !prevent;
@@ -218,7 +216,7 @@ function _getMoveDis(e, ins) {
diffDis = diffDis * (1 - refresherOutRate);
}
}
diffDis = diffDis > 100 ? diffDis / 100 : diffDis;
diffDis = diffDis > 100 ? diffDis / 100 : (diffDis > 20 ? diffDis / 1.2 : diffDis);
currentDis += diffDis;
currentDis = Math.max(0, currentDis);
return {
@@ -270,7 +268,7 @@ function _touchDisabled(e, ins, processTag) {
var fixedIsTopHitCount = state.fixedIsTopHitCount || 0;
if (fixedIsTop) {
fixedIsTopHitCount ++;
if (fixedIsTopHitCount <= 3) {
if (fixedIsTopHitCount <= 2) {
fixedIsTop = false;
}
state.fixedIsTopHitCount = fixedIsTopHitCount;

View File

@@ -4,13 +4,13 @@
/ /_____| |_) | (_| | (_| | | | | | (_| |
/___| | .__/ \__,_|\__, |_|_| |_|\__, |
|_| |___/ |___/
v2.5.7 (2023-03-14)
v2.5.9 (2023-09-25)
by ZXLee
-->
<!-- 文档地址https://z-paging.zxlee.cn -->
<!-- github地址https://github.com/SmileZXLee/uni-z-paging -->
<!-- dcloud地址https://ext.dcloud.net.cn/plugin?id=3935 -->
<!-- 反馈QQ群790460711 -->
<!-- 反馈QQ群790460711(已满)、371624008 -->
<template name="z-paging">
<!-- #ifndef APP-NVUE -->
@@ -20,7 +20,7 @@ by ZXLee
<!-- #endif -->
<!-- 顶部固定的slot -->
<slot v-if="!usePageScroll&&zSlots.top" name="top" />
<view class="zp-page-top" v-else-if="usePageScroll&&zSlots.top" :style="[{'top':`${windowTop}px`,'z-index':topZIndex}]">
<view class="zp-page-top" @touchmove.stop.prevent v-else-if="usePageScroll&&zSlots.top" :style="[{'top':`${windowTop}px`,'z-index':topZIndex}]">
<slot name="top" />
</view>
<view :class="{'zp-view-super':true,'zp-scroll-view-super':!usePageScroll}" :style="[finalScrollViewStyle]">
@@ -63,7 +63,7 @@ by ZXLee
:change:renderPropIsIosAndH5="pagingRenderjs.renderPropIsIosAndH5Change" :renderPropIsIosAndH5="isIosAndH5"
<!-- #endif -->
>
<view v-if="showRefresher" class="zp-custom-refresher-view" :style="[{'margin-top': `-${finalRefresherThreshold}px`,'background': refresherBackground,'opacity': isTouchmoving ? 1 : 0}]">
<view v-if="showRefresher" class="zp-custom-refresher-view" :style="[{'margin-top': `-${finalRefresherThreshold+refresherThresholdUpdateTag}px`,'background': refresherBackground,'opacity': isTouchmoving ? 1 : 0}]">
<view class="zp-custom-refresher-container" :style="[{'height': `${finalRefresherThreshold}px`,'background': refresherBackground}]">
<!-- 下拉刷新view -->
<view class="zp-custom-refresher-slot-view">
@@ -95,7 +95,7 @@ by ZXLee
<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['zp_index']}`" v-for="(item,index) in virtualList" :key="item['zp_unique_index']" @click="_innerCellClick(item,virtualTopRangeIndex+index)">
<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>
<!-- <zp-public-virtual-cell v-if="useCompatibilityMode" :extraData="extraData" :item="item" :index="virtualTopRangeIndex+index" /> -->
<slot v-else name="cell" :item="item" :index="virtualTopRangeIndex+index"/>
@@ -128,7 +128,7 @@ by ZXLee
<view v-if="safeAreaInsetBottom&&useSafeAreaPlaceholder" class="zp-safe-area-placeholder" :style="[{height:safeAreaBottom+'px'}]" />
</view>
<!-- 空数据图 -->
<view v-if="showEmpty" :class="{'zp-empty-view':true,'zp-empty-view-center':emptyViewCenter}" :style="[{emptyViewSuperStyle}]">
<view v-if="showEmpty" :class="{'zp-empty-view':true,'zp-empty-view-center':emptyViewCenter}" :style="[emptyViewSuperStyle]">
<slot v-if="zSlots.empty" name="empty" :isLoadFailed="isLoadFailed"/>
<z-paging-empty-view v-else :emptyViewImg="finalEmptyViewImg" :emptyViewText="finalEmptyViewText" :showEmptyViewReload="finalShowEmptyViewReload"
:emptyViewReloadText="finalEmptyViewReloadText" :isLoadFailed="isLoadFailed" :emptyViewStyle="emptyViewStyle" :emptyViewTitleStyle="emptyViewTitleStyle"
@@ -146,7 +146,7 @@ by ZXLee
</view>
<!-- 底部固定的slot -->
<slot v-if="!usePageScroll&&zSlots.bottom" name="bottom" />
<view class="zp-page-bottom" v-else-if="usePageScroll&&zSlots.bottom" :style="[{'bottom': `${windowBottom}px`}]">
<view class="zp-page-bottom" @touchmove.stop.prevent v-else-if="usePageScroll&&zSlots.bottom" :style="[{'bottom': `${windowBottom}px`}]">
<slot name="bottom" />
</view>
<!-- 点击返回顶部view -->
@@ -216,19 +216,8 @@ by ZXLee
<component :is="nViewIs" v-if="showLoading&&zSlots.loading&&!loadingFullFixed" :class="{'z-paging-content-fixed':usePageScroll}" style="flex:1" :style="[nChatRecordRotateStyle]">
<slot name="loading" />
</component>
<!-- 空数据图 -->
<component :is="nViewIs" v-if="showEmpty" :class="{'z-paging-content-fixed':usePageScroll}" style="flex:1" :style="[emptyViewSuperStyle,nChatRecordRotateStyle]">
<view :class="{'zp-empty-view':true,'zp-empty-view-center':emptyViewCenter}">
<slot v-if="zSlots.empty" name="empty" :isLoadFailed="isLoadFailed" />
<z-paging-empty-view v-else :emptyViewImg="finalEmptyViewImg" :emptyViewText="finalEmptyViewText" :showEmptyViewReload="finalShowEmptyViewReload"
:emptyViewReloadText="finalEmptyViewReloadText" :isLoadFailed="isLoadFailed" :emptyViewStyle="emptyViewStyle" :emptyViewTitleStyle="emptyViewTitleStyle"
:emptyViewImgStyle="emptyViewImgStyle" :emptyViewReloadStyle="emptyViewReloadStyle" :emptyViewZIndex="emptyViewZIndex" :emptyViewFixed="emptyViewFixed"
@reload="_emptyViewReload" @viewClick="_emptyViewClick" />
</view>
</component>
<component is="header" v-if="!hideNvueBottomTag" ref="zp-n-list-bottom-tag" class="zp-n-list-bottom-tag"></component>
<!-- 上拉加载更多view -->
<component :is="nViewIs" v-if="!refresherOnly&&loadingMoreEnabled">
<component :is="nViewIs" v-if="!refresherOnly&&loadingMoreEnabled&&!showEmpty">
<view v-if="useChatRecordMode">
<view v-if="loadingStatus!==M.NoMore&&realTotalData.length">
<slot v-if="zSlots.chatLoading" name="chatLoading" />
@@ -250,6 +239,17 @@ by ZXLee
<view v-if="safeAreaInsetBottom&&useSafeAreaPlaceholder" class="zp-safe-area-placeholder" :style="[{height:safeAreaBottom+'px'}]" />
</view>
</component>
<!-- 空数据图 -->
<component :is="nViewIs" v-if="showEmpty" :class="{'z-paging-content-fixed':usePageScroll}" :style="[{flex:emptyViewCenter?1:0},emptyViewSuperStyle,nChatRecordRotateStyle]">
<view :class="{'zp-empty-view':true,'zp-empty-view-center':emptyViewCenter}">
<slot v-if="zSlots.empty" name="empty" :isLoadFailed="isLoadFailed" />
<z-paging-empty-view v-else :emptyViewImg="finalEmptyViewImg" :emptyViewText="finalEmptyViewText" :showEmptyViewReload="finalShowEmptyViewReload"
:emptyViewReloadText="finalEmptyViewReloadText" :isLoadFailed="isLoadFailed" :emptyViewStyle="emptyViewStyle" :emptyViewTitleStyle="emptyViewTitleStyle"
:emptyViewImgStyle="emptyViewImgStyle" :emptyViewReloadStyle="emptyViewReloadStyle" :emptyViewZIndex="emptyViewZIndex" :emptyViewFixed="emptyViewFixed"
@reload="_emptyViewReload" @viewClick="_emptyViewClick" />
</view>
</component>
<component is="header" v-if="!hideNvueBottomTag" ref="zp-n-list-bottom-tag" class="zp-n-list-bottom-tag"></component>
</component>
<view v-if="zSlots.right" class="zp-page-right">
<slot name="right" />

View File

@@ -2,7 +2,7 @@
"id": "z-paging",
"name": "z-paging",
"displayName": "【z-paging下拉刷新、上拉加载】高性能全平台兼容。支持虚拟列表支持nvue、vue3",
"version": "2.5.8",
"version": "2.6.0",
"description": "超简单、低耦合使用wxs+renderjs实现。支持长列表优化支持自定义下拉刷新、上拉加载更多支持自动管理空数据图、点击返回顶部支持聊天分页、本地分页支持国际化等100+项配置",
"keywords": [
"下拉刷新",

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.5.7-blue)](https://github.com/SmileZXLee/uni-z-paging)
[![version](https://img.shields.io/badge/version-2.5.9-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)
### 文档地址:[https://z-paging.zxlee.cn](https://z-paging.zxlee.cn)
@@ -15,13 +15,16 @@
### 功能&特点
* 【配置简单】仅需两步(绑定网络请求方法、绑定分页结果数组)轻松完成完整下拉刷新,上拉加载更多功能。
* 【低耦合低侵入】分页自动管理。在page中无需处理任何分页相关逻辑无需在data中定义任何分页相关变量全由z-paging内部处理。
* 【超灵活,支持各种类型自定义】支持自定义下拉刷新,自定义上拉加载更多,自带自定义下拉刷新效果,及其他数十种自定义属性
* 【超灵活,支持各种类型自定义】支持自定义下拉刷新,自定义上拉加载更多等各种自定义效果支持使用内置自动分页同时也支持通过监听下拉刷新和滚动到底部事件自行处理支持使用自带全屏布局规范同时也支持将z-paging自由放在任意容器中
* 【功能丰富】支持国际化支持自定义且自动管理空数据图支持主题模式切换支持本地分页支持聊天分页模式支持展示最后更新时间支持吸顶效果支持内部scroll-view滚动与页面滚动支持一键滚动到顶部等诸多功能。
* 【全平台兼容】支持nvuevue3支持h5、app及各家小程序。
* 【全平台兼容】支持vue、nvuevue2、vue3支持h5、app及各家小程序。
* 【高性能】在app-vue、h5、微信小程序、QQ小程序上使用wxs+renderjs从视图层实现下拉刷新支持虚拟列表轻松渲染万级数据
***
### 反馈qq群(点击加群)[790460711](https://jq.qq.com/?_wv=1027&k=vU2fKZZH)
### 反馈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)
***
@@ -44,3 +47,7 @@
| 扫码体验 |
| ------------------------------------------------------------ |
| ![](https://z-paging.zxlee.cn/public/img/code.png) |
### demo下载
* 支持vue2&vue3的`选项式api`写法demo下载请点击页面右上角的【使用HBuilderX导入示例项目】或【下载示例项目ZIP】。
* 支持vue3的`组合式api`写法demo下载请访问[github](https://github.com/SmileZXLee/uni-z-paging)。