Răsfoiți Sursa

增加z-paging组件 解决包月无法下拉刷新问题

CarlYang 3 ani în urmă
părinte
comite
a249a98811
26 a modificat fișierele cu 5309 adăugiri și 280 ștergeri
  1. 13 4
      pages.json
  2. 4 1
      pages/center/monthly/monthly.scss
  3. 80 132
      pages/center/monthly/monthly.vue
  4. 116 85
      pages/center/monthly/monthly1.vue
  5. 10 5
      pages/favourableActivity/favourableActivity.vue
  6. 1 1
      pages/index/index.vue
  7. 83 52
      pages/myCars/myCars.vue
  8. 38 0
      uni_modules/z-paging/changelog.md
  9. 170 0
      uni_modules/z-paging/components/z-paging-empty-view/z-paging-empty-view.vue
  10. 86 0
      uni_modules/z-paging/components/z-paging-swiper-item/z-paging-swiper-item.vue
  11. 123 0
      uni_modules/z-paging/components/z-paging-swiper/z-paging-swiper.vue
  12. 158 0
      uni_modules/z-paging/components/z-paging/components/z-paging-load-more.vue
  13. 259 0
      uni_modules/z-paging/components/z-paging/components/z-paging-refresh.vue
  14. 157 0
      uni_modules/z-paging/components/z-paging/css/z-paging-main.css
  15. 38 0
      uni_modules/z-paging/components/z-paging/css/z-paging-static.css
  16. 32 0
      uni_modules/z-paging/components/z-paging/js/z-paging-config.js
  17. 150 0
      uni_modules/z-paging/components/z-paging/js/z-paging-i18n.js
  18. 2617 0
      uni_modules/z-paging/components/z-paging/js/z-paging-main.js
  19. 36 0
      uni_modules/z-paging/components/z-paging/js/z-paging-mixin.js
  20. 12 0
      uni_modules/z-paging/components/z-paging/js/z-paging-static.js
  21. 179 0
      uni_modules/z-paging/components/z-paging/js/z-paging-utils.js
  22. 60 0
      uni_modules/z-paging/components/z-paging/wxs/z-paging-renderjs.js
  23. 335 0
      uni_modules/z-paging/components/z-paging/wxs/z-paging-wxs.wxs
  24. 239 0
      uni_modules/z-paging/components/z-paging/z-paging.vue
  25. 80 0
      uni_modules/z-paging/package.json
  26. 233 0
      uni_modules/z-paging/readme.md

+ 13 - 4
pages.json

@@ -134,16 +134,25 @@
             
         }
         ,{
-            "path" : "pages/center/monthly/monthly",
+            "path" : "pages/center/monthly/monthly1",
             "style" :                                                                                    
             {
-				// "navigationStyle":"custom",
                 "navigationBarTitleText": "我的包月",
                 "navigationBarBackgroundColor": "#008CFF",
-                "navigationBarTextStyle": "white"
+                "navigationBarTextStyle": "white",
+				"enablePullDownRefresh": false
             }
-            
         },
+		{
+		    "path" : "pages/center/monthly/monthly",
+		    "style" :                                                                                    
+		    {
+		        "navigationBarTitleText": "我的包月",
+		        "navigationBarBackgroundColor": "#008CFF",
+		        "navigationBarTextStyle": "white",
+				"enablePullDownRefresh": false
+		    }
+		},
 		{
 		    "path" : "pages/payLists/pay",
 		    "style" :                                                                                    

+ 4 - 1
pages/center/monthly/monthly.scss

@@ -1,10 +1,13 @@
-page{
+page {
 	background-color: #F6F6FF
 }
 .monthly {
 	padding: 37rpx 40rpx;
 	height: calc(100vh - 88rpx);
 	overflow-y: scroll;
+	.paging {
+		padding: 37rpx 40rpx;
+	}
 	.monthly-list {
 		.monthly-list-item {
 			overflow: hidden;

+ 80 - 132
pages/center/monthly/monthly.vue

@@ -1,31 +1,27 @@
 <template>
 	<!-- 包月 -->
 	<view class="monthly">
-		<!-- <u-navbar
-		 title-color="#fff" 
-		 :custom-back="customBack" 
-		 :border-bottom="false" 
-		 back-icon-color="#CCE8FF" 
-		 :background="{background: '#008CFF' }" title="我的包月"></u-navbar> -->
-		<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback">
+		<z-paging class="paging" ref="paging" v-model="dataList" @query="queryList">
 			<view class="monthly-list">
-				<view class="monthly-list-item" :index="index" v-for="(monthlyItem, index) in  monthlyList" :key="index">
+				<view class="monthly-list-item" v-for="(monthlyItem, index) in  dataList" :key="monthlyItem.id">
 					<view class="monthly-list-item-top">
 						<view class="mlit-left">
 							<view>{{monthlyItem.vehicleNo}}</view>
 							<view>{{monthlyItem.roadName}}</view>
 						</view>
 						<view class="mlit-right u-flex">
-						<view class="mlit-right-item fee-status" v-if="monthlyItem.feeStatus === 0">未缴费</view>
-						<view class="mlit-right-item fee-status" v-if="monthlyItem.feeStatus === 1">已缴费</view>
-						<view class="mlit-right-item" v-if="monthlyItem.energyType === 1">汽油车</view>
-						<view class="mlit-right-item" v-if="monthlyItem.energyType === 2">新能源</view>
+							<view class="mlit-right-item fee-status" v-if="monthlyItem.feeStatus === 0">未缴费</view>
+							<view class="mlit-right-item fee-status" v-if="monthlyItem.feeStatus === 1">已缴费</view>
+							<view class="mlit-right-item" v-if="monthlyItem.energyType === 1">汽油车</view>
+							<view class="mlit-right-item" v-if="monthlyItem.energyType === 2">新能源</view>
 						</view>
 					</view>
-					<view class="monthly-list-item-bottom" >
+					<view class="monthly-list-item-bottom">
 						<view class="mlib-item">
 							<view>有效期限</view>:
-							<view>{{(monthlyItem.beginTime.split('-')).join('.')}}-{{(monthlyItem.endTime.split('-')).join('.')}}</view>
+							<view>
+								{{(monthlyItem.beginTime.split('-')).join('.')}}-{{(monthlyItem.endTime.split('-')).join('.')}}
+							</view>
 						</view>
 						<view class="mlib-item">
 							<view>剩余天数</view>:
@@ -33,147 +29,99 @@
 						</view>
 					</view>
 					<view v-if="monthlyItem.feeStatus=='0'" class="button-wrap u-flex u-row-right">
-						<view class="tool-btn" 
-						:class="{'tool-btn-cancel':monthlyItem.feeStatus=='0'}" 
-						v-if="monthlyItem.feeStatus=='0'" 
-						@click="cancelMonth(monthlyItem.monthId)">取消订单</view>
+						<view class="tool-btn" :class="{'tool-btn-cancel': monthlyItem.feeStatus=='0'}"
+							v-if="monthlyItem.feeStatus=='0'" @click="cancelMonth(monthlyItem.monthId)">取消订单</view>
 					</view>
-					<view v-else-if="monthlyItem.feeStatus == 1 && monthlyItem.surplusDays > 2" class="button-wrap u-flex u-row-right">
+					<view v-else-if="monthlyItem.feeStatus == 1 && monthlyItem.surplusDays > 2"
+						class="button-wrap u-flex u-row-right">
 						<view class="tool-btn">已缴费</view>
 					</view>
-					<view v-else-if="monthlyItem.feeStatus == 1 && monthlyItem.surplusDays < 3" class="button-wrap u-flex u-row-right">
+					<view v-else-if="monthlyItem.feeStatus == 1 && monthlyItem.surplusDays < 3"
+						class="button-wrap u-flex u-row-right">
 						<view class="tool-btn" @click="goRenewal(monthlyItem)">去续费</view>
 					</view>
 				</view>
 			</view>
-		</mescroll-body>
-		<u-modal v-model="canclShow" content="确认取消该订单?" @confirm="confirm" :show-cancel-button="true"></u-modal>
+		</z-paging>
+		<u-modal v-model="cancelShow" content="确认取消该订单?" @confirm="confirm" :show-cancel-button="true"></u-modal>
 		<u-toast ref="uToast" />
 	</view>
 </template>
 
 <script>
-	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
 	export default {
-		mixins: [MescrollMixin], // 使用mixin
 		data() {
 			return {
-				id:'',
-				canclShow: false,
-				monthlyList: [],
-				monthList:'',
-				beginTime:'',
-				endTime:'',
-				time:[],
-			}
-		},
-		onShow() {
-			// onShow 刷新数据
-			if(this.mescroll){
-				this.mescroll.triggerDownScroll();
+				id: '', // 当前选中的条目id
+				cancelShow: false,
+				dataList: [],
+				pageSize: 10,
+				pageNo: 1
 			}
 		},
 		methods: {
-			customBack(){
+			customBack() {
 				this.$u.route({
-					type:'switchTab',
+					type: 'switchTab',
 					url: 'pages/center/index'
 				});
 			},
-			/*下拉刷新的回调*/
-			downCallback(){
-				// 第2种: 下拉刷新和上拉加载调同样的接口, 则不用第1种, 直接mescroll.resetUpScroll()即可
-				this.mescroll.resetUpScroll(); // 重置列表为第一页 (自动执行 page.num=1, 再触发upCallback方法 )
-			},
-			/*上拉加载的回调*/
-			upCallback(page) {
-				let pageNum = page.num; // 页码, 默认从1开始
-				let pageSize = page.size; // 页长, 默认每页10条
-				// this.getMessageList()
-				this.$u.api.getMonthList({pageSize:pageSize ,pageNum: pageNum})
-				.then(res=>{
-					if(res.code == 200){
-					console.log('res',res)
-					// 接口返回的当前页数据列表 (数组)
-					let curPageData = res.data.rows;
-					// 接口返回的当前页数据长度 (如列表有26个数据,当前页返回8个,则curPageLen=8)
-					let curPageLen = curPageData.length; 
-					// 接口返回的总页数 (如列表有26个数据,每页10条,共3页; 则totalPage=3)
-					let totalPage = res.data.pages; 
-					// 接口返回的总数据量(如列表有26个数据,每页10条,共3页; 则totalSize=26)
-					let totalSize = res.data.total; 
-					// 接口返回的是否有下一页 (true/false)
-					// let hasNext = Number(res.data.page) < Number(res.data.pages); 
-					
-					//设置列表数据
-					if(page.num == 1) this.monthlyList = []; //如果是第一页需手动置空列表
-					this.monthlyList = this.monthlyList.concat(curPageData); //追加新数据
-					
-					// 请求成功,隐藏加载状态
-					//方法一(推荐): 后台接口有返回列表的总页数 totalPage
-					this.mescroll.endByPage(curPageLen, totalPage); 
-					setTimeout(()=>{
-						this.mescroll.endSuccess(curPageLen)
-					},20)
-					this.monthList=[],
-					res.data.rows.forEach(item => {
-						const obj = {
-							beginTime: item.beginTime,
-							endTime: item.endTime,
+			// 下拉刷新操作
+			queryList(pageNo, pageSize) {
+				console.log(pageNo)
+				console.log(pageSize)
+				this.$u.api.getMonthList({
+						pageSize: pageSize,
+						pageNum: pageNo,
+					})
+					.then(res => {
+						if (res.code === 200) {
+							this.pageNo = pageNo
+							this.pageSize = pageSize
+							this.$refs.paging.complete(res.data.rows);
+						} else {
+							this.$refs.uToast.show({
+								title: res.msg,
+								type: 'error',
+							});
 						}
-						this.monthList.push(obj)
-						// console.log(obj)
-					});
-					this.time = this.monthList[0]
-					let Date1 = this.time.beginTime;
-					let Date2 = this.time.endTime;
-					// Date1 = Date1.valueOf() + 24 * 60 * 60 * 1000
-					Date1 = new Date(Date1)
-					const year = Date1.getFullYear()
-					const month = Date1.getMonth()+1
-					const day = Date1.getDate()
-					Date2 = new Date(Date2)
-					const year2 = Date2.getFullYear()
-					const month2 = Date2.getMonth()+1
-					const day2 = Date2.getDate()
-					this.beginTime = year + '.' + month + '.' + day
-					console.log(this.beginTime)
-					this.endTime = year2 + '.' + month2 + '.' + day2
-					}else{
-						this.mescroll.endErr()
-					}
-				}).catch(err=>{
-					// console.log('err',err);
-					// this.$refs.uToast.show({
-					// 	title: err.msg,
-					// 	type: 'error',
-					// });
-				});
-				
+					})
+					.catch(err => {
+						this.$refs.uToast.show({
+							title: '操作失败',
+							type: 'error',
+						});
+					})
 			},
-			cancelMonth(monthId){
-				this.id=monthId;
-				this.canclShow = true;
-				console.log('monthId',monthId)
+			// 取消订单
+			cancelMonth(monthId) {
+				this.id = monthId;
+				this.cancelShow = true;
 			},
-			confirm(){
-				this.$u.api.cancelMonth({monthId: this.id})
-				.then(res=>{
-					if(res.code === 200){
-					this.$refs.uToast.show({ 
-						title: res.msg,
-						type: 'success',
-					});
-					this.downCallback()
-					}else{
-						
-					}
-				}).catch(err=>{
-					this.$refs.uToast.show({
-						title: err.msg,
-						type: 'error',
-					});
-				})
+			// 确认取消订单
+			confirm() {
+				this.$u.api.cancelMonth({
+						monthId: this.id,
+					})
+					.then(res => {
+						if (res.code === 200) {
+							this.$refs.uToast.show({
+								title: res.msg,
+								type: 'success',
+							});
+							this.queryList(this.pageNo, this.pageSize)
+						} else {
+							this.$refs.uToast.show({
+								title: res.msg,
+								type: 'error',
+							});
+						}
+					}).catch(err => {
+						this.$refs.uToast.show({
+							title: '操作失败',
+							type: 'error',
+						});
+					})
 			},
 			/**
 			 * 去续费
@@ -186,11 +134,11 @@
 						vehicleNo: item.vehicleNo
 					}
 				})
-			 }
+			}
 		}
 	}
 </script>
 
 <style lang="scss" scoped>
-@import './monthly.scss';
+	@import './monthly.scss';
 </style>

+ 116 - 85
pages/center/monthly/monthly1.vue

@@ -7,47 +7,47 @@
 		 :border-bottom="false" 
 		 back-icon-color="#CCE8FF" 
 		 :background="{background: '#008CFF' }" title="我的包月"></u-navbar> -->
-		 <mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback">
-			 <view class="monthly-list">
-			 	<view class="monthly-list-item"  v-for="(monthlyItem, index) in  dataList" :key="monthlyItem.id">
-			 		<view class="monthly-list-item-top">
-			 			<view class="mlit-left">
-			 				<view>{{monthlyItem.vehicleNo}}</view>
-			 				<view>{{monthlyItem.roadName}}</view>
-			 			</view>
-			 			<view class="mlit-right u-flex">
-			 			<view class="mlit-right-item fee-status" v-if="monthlyItem.feeStatus === 0">未缴费</view>
-			 			<view class="mlit-right-item fee-status" v-if="monthlyItem.feeStatus === 1">已缴费</view>
-			 			<view class="mlit-right-item" v-if="monthlyItem.energyType === 1">汽油车</view>
-			 			<view class="mlit-right-item" v-if="monthlyItem.energyType === 2">新能源</view>
-			 			</view>
-			 		</view>
-			 		<view class="monthly-list-item-bottom" >
-			 			<view class="mlib-item">
-			 				<view>有效期限</view>:
-			 				<view>{{(monthlyItem.beginTime.split('-')).join('.')}}-{{(monthlyItem.endTime.split('-')).join('.')}}</view>
-			 			</view>
-			 			<view class="mlib-item">
-			 				<view>剩余天数</view>:
-			 				<view>{{monthlyItem.surplusDays}}天</view>
-			 			</view>
-			 		</view>
-			 		<view v-if="monthlyItem.feeStatus=='0'" class="button-wrap u-flex u-row-right">
-			 			<view class="tool-btn" 
-			 			:class="{'tool-btn-cancel':monthlyItem.feeStatus=='0'}" 
-			 			v-if="monthlyItem.feeStatus=='0'" 
-			 			@click="cancelMonth(monthlyItem.monthId)">取消订单</view>
-			 		</view>
-			 		<view v-else-if="monthlyItem.feeStatus == 1 && monthlyItem.surplusDays > 2" class="button-wrap u-flex u-row-right">
-			 			<view class="tool-btn">已缴费</view>
-			 		</view>
-			 		<view v-else-if="monthlyItem.feeStatus == 1 && monthlyItem.surplusDays < 3" class="button-wrap u-flex u-row-right">
-			 			<view class="tool-btn" @click="goRenewal(monthlyItem)">去续费</view>
-			 		</view>
-			 	</view>
-			 </view>
-		 </mescroll-body>
-		<u-modal v-model="cancelShow" content="确认取消该订单?" @confirm="confirm" :show-cancel-button="true"></u-modal>
+		<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback">
+			<view class="monthly-list">
+				<view class="monthly-list-item" :index="index" v-for="(monthlyItem, index) in  monthlyList" :key="index">
+					<view class="monthly-list-item-top">
+						<view class="mlit-left">
+							<view>{{monthlyItem.vehicleNo}}</view>
+							<view>{{monthlyItem.roadName}}</view>
+						</view>
+						<view class="mlit-right u-flex">
+						<view class="mlit-right-item fee-status" v-if="monthlyItem.feeStatus === 0">未缴费</view>
+						<view class="mlit-right-item fee-status" v-if="monthlyItem.feeStatus === 1">已缴费</view>
+						<view class="mlit-right-item" v-if="monthlyItem.energyType === 1">汽油车</view>
+						<view class="mlit-right-item" v-if="monthlyItem.energyType === 2">新能源</view>
+						</view>
+					</view>
+					<view class="monthly-list-item-bottom" >
+						<view class="mlib-item">
+							<view>有效期限</view>:
+							<view>{{(monthlyItem.beginTime.split('-')).join('.')}}-{{(monthlyItem.endTime.split('-')).join('.')}}</view>
+						</view>
+						<view class="mlib-item">
+							<view>剩余天数</view>:
+							<view>{{monthlyItem.surplusDays}}天</view>
+						</view>
+					</view>
+					<view v-if="monthlyItem.feeStatus=='0'" class="button-wrap u-flex u-row-right">
+						<view class="tool-btn" 
+						:class="{'tool-btn-cancel':monthlyItem.feeStatus=='0'}" 
+						v-if="monthlyItem.feeStatus=='0'" 
+						@click="cancelMonth(monthlyItem.monthId)">取消订单</view>
+					</view>
+					<view v-else-if="monthlyItem.feeStatus == 1 && monthlyItem.surplusDays > 2" class="button-wrap u-flex u-row-right">
+						<view class="tool-btn">已缴费</view>
+					</view>
+					<view v-else-if="monthlyItem.feeStatus == 1 && monthlyItem.surplusDays < 3" class="button-wrap u-flex u-row-right">
+						<view class="tool-btn" @click="goRenewal(monthlyItem)">去续费</view>
+					</view>
+				</view>
+			</view>
+		</mescroll-body>
+		<u-modal v-model="canclShow" content="确认取消该订单?" @confirm="confirm" :show-cancel-button="true"></u-modal>
 		<u-toast ref="uToast" />
 	</view>
 </template>
@@ -58,9 +58,13 @@
 		mixins: [MescrollMixin], // 使用mixin
 		data() {
 			return {
-				cancelShow: false,
-				mescroll: null,
-				dataList: []
+				id:'',
+				canclShow: false,
+				monthlyList: [],
+				monthList:'',
+				beginTime:'',
+				endTime:'',
+				time:[],
 			}
 		},
 		onShow() {
@@ -76,54 +80,81 @@
 					url: 'pages/center/index'
 				});
 			},
-			// mescroll组件初始化的回调,可获取到mescroll对象
-			mescrollInit(mescroll) {
-				this.mescroll = mescroll;
-			},
-			// 下拉刷新的回调
+			/*下拉刷新的回调*/
 			downCallback(){
-				// 下拉刷新和上拉加载调同样的接口
+				// 第2种: 下拉刷新和上拉加载调同样的接口, 则不用第1种, 直接mescroll.resetUpScroll()即可
 				this.mescroll.resetUpScroll(); // 重置列表为第一页 (自动执行 page.num=1, 再触发upCallback方法 )
 			},
-			// 上拉加载的回调
+			/*上拉加载的回调*/
 			upCallback(page) {
 				let pageNum = page.num; // 页码, 默认从1开始
 				let pageSize = page.size; // 页长, 默认每页10条
-				this.$u.api.getMonthList({
-					pageSize: pageSize,
-					pageNum: pageNum,
-				})
-				.then(res =>{
-					console.log(res)
-					if (res.code === 200) {
-						// 接口返回的当前页数据列表 (数组)
-						let curPageData = res.data.rows; 
-						// 接口返回的当前页数据长度 
-						let curPageLen = curPageData.length; 
-						// 接口返回的总页数 (如列表有26个数据,每页10条,共3页; 则totalPage=3)
-						let totalPage = res.data.pages; 
-						// 接口返回的总数据量(如列表有26个数据,每页10条,共3页; 则totalSize=26)
-						let totalSize = res.data.total; 
-						// 接口返回的是否有下一页 (true/false)
-						let hasNext = res.data.page < res.data.pages; 
-						
-						//设置列表数据
-						if(page.num == 1) this.dataList = []; //如果是第一页需手动置空列表
-						this.dataList = this.dataList.concat(curPageData); //追加新数据
-						
-						// 请求成功,隐藏加载状态
-						this.mescroll.endByPage(curPageLen, totalPage);
-						setTimeout(()=>{
-							this.mescroll.endSuccess(curPageLen)
-						}, 20)
+				// this.getMessageList()
+				this.$u.api.getMonthList({pageSize:pageSize ,pageNum: pageNum})
+				.then(res=>{
+					if(res.code == 200){
+					console.log('res',res)
+					// 接口返回的当前页数据列表 (数组)
+					let curPageData = res.data.rows;
+					// 接口返回的当前页数据长度 (如列表有26个数据,当前页返回8个,则curPageLen=8)
+					let curPageLen = curPageData.length; 
+					// 接口返回的总页数 (如列表有26个数据,每页10条,共3页; 则totalPage=3)
+					let totalPage = res.data.pages; 
+					// 接口返回的总数据量(如列表有26个数据,每页10条,共3页; 则totalSize=26)
+					let totalSize = res.data.total; 
+					// 接口返回的是否有下一页 (true/false)
+					// let hasNext = Number(res.data.page) < Number(res.data.pages); 
+					
+					//设置列表数据
+					if(page.num == 1) this.monthlyList = []; //如果是第一页需手动置空列表
+					this.monthlyList = this.monthlyList.concat(curPageData); //追加新数据
+					
+					// 请求成功,隐藏加载状态
+					//方法一(推荐): 后台接口有返回列表的总页数 totalPage
+					this.mescroll.endByPage(curPageLen, totalPage); 
+					setTimeout(()=>{
+						this.mescroll.endSuccess(curPageLen)
+					},20)
+					this.monthList=[],
+					res.data.rows.forEach(item => {
+						const obj = {
+							beginTime: item.beginTime,
+							endTime: item.endTime,
+						}
+						this.monthList.push(obj)
+						// console.log(obj)
+					});
+					this.time = this.monthList[0]
+					let Date1 = this.time.beginTime;
+					let Date2 = this.time.endTime;
+					// Date1 = Date1.valueOf() + 24 * 60 * 60 * 1000
+					Date1 = new Date(Date1)
+					const year = Date1.getFullYear()
+					const month = Date1.getMonth()+1
+					const day = Date1.getDate()
+					Date2 = new Date(Date2)
+					const year2 = Date2.getFullYear()
+					const month2 = Date2.getMonth()+1
+					const day2 = Date2.getDate()
+					this.beginTime = year + '.' + month + '.' + day
+					console.log(this.beginTime)
+					this.endTime = year2 + '.' + month2 + '.' + day2
+					}else{
+						this.mescroll.endErr()
 					}
-				})
-				.catch(err => {
-					this.$refs.uToast.show({
-						title: '操作失败!',
-						type: 'error'
-					})
-				})
+				}).catch(err=>{
+					// console.log('err',err);
+					// this.$refs.uToast.show({
+					// 	title: err.msg,
+					// 	type: 'error',
+					// });
+				});
+				
+			},
+			cancelMonth(monthId){
+				this.id=monthId;
+				this.canclShow = true;
+				console.log('monthId',monthId)
 			},
 			confirm(){
 				this.$u.api.cancelMonth({monthId: this.id})

+ 10 - 5
pages/favourableActivity/favourableActivity.vue

@@ -9,7 +9,7 @@
 				</view>
 				<view>如果停车场、路边停车位有15分钟内等免费政策的,我行客户自然享受后再按“一分钱停车”、“八折停车”执行。</view>
 				<view>
-					<button type="default" class="btn1">银行卡开户</button>
+					<button type="default" class="btn1" @click="openAcount">银行卡开户</button>
 				</view>
 			</view>
 		</view>
@@ -21,10 +21,11 @@
 				</view>
 				<view>如果停车场、路边停车位有15分钟内等免费政策的,我行客户自然享受后再按“一分钱停车”、“八折停车”执行。</view>
 				<view>
-					<button type="default" class="btn2">银行卡开户</button>
+					<button type="default" class="btn2" @click="openAcount">银行卡开户</button>
 				</view>
 			</view>
 		</view>
+		<u-toast ref="uToast"/>
 	</view>
 </template>
 
@@ -48,10 +49,14 @@
 				this.id = 1
 			}
 		},
-		onShow() {
-			console.log(this.id == 1)
-		},
+		onShow() {},
 		methods: {
+			openAcount() {
+				this.$refs.uToast.show({
+					title: '该功能尚未开发',
+					type: 'warning'
+				})
+			}
 		}
 	}
 </script>

+ 1 - 1
pages/index/index.vue

@@ -214,7 +214,7 @@
 			this.handleGetIndexData();
 			this.getLocation();
 			let locationLocaturl = window.location.search;
-			this.code = getUrlParams(locationLocaturl,"code");
+			this.code = getUrlParams(locationLocaturl, "code");
 			if(this.code&&!this.$store.state.vuex_wxinfo.openId){this.handleGetWXInfo(this.code)};
 		},
 		methods: {

+ 83 - 52
pages/myCars/myCars.vue

@@ -31,7 +31,7 @@
 					<view class="mycars-item-tool">
 						<span class="default" v-if="item.isDefault == 1" :class="{'isDefault':item.isDefault == 1}" @click="handlesetDefault(item.id)">默认</span>
 						<span class="default" v-else @click="handlesetDefault(item.id)">设为默认</span>
-						<span @click="handleDelCar(item.id,item.vehicleNo)">删除</span>
+						<span @click="handleDelCar(item.id, item.vehicleNo)">删除</span>
 					</view>
 				</view>
 			</view>
@@ -69,9 +69,9 @@
 		onLoad(){
 			this.handlegetMycars();
 		},
-		onShow() {
-			this.handlegetMycars();
-		},
+		// onShow() {
+		// 	this.handlegetMycars();
+		// },
 		methods:{
 			customBack(){
 				this.$u.route({
@@ -79,16 +79,28 @@
 					url: 'pages/index/index'
 				});
 			},
+			// 获取车辆列表
 			handlegetMycars(){
 				this.$u.api.getMycars()
-				.then(res=>{
-					this.mycars = res.data.rows;
-					this.mycarsTotal = res.data.total;
-					console.log('this.mycars',this.mycars)
-				}).catch(err=>{
-					console.log('getMycars ',err)
-				});
+					.then(res=>{
+						if (res.code === 200) {
+							this.mycars = res.data.rows;
+							this.mycarsTotal = res.data.total;
+						} else {
+							this.$refs.uToast.show({
+								title: res.msg,
+								type: 'error'
+							})
+						}
+					})
+					.catch(err=>{
+						this.$refs.uToast.show({
+							title: '操作失败!',
+							type: 'error'
+						})
+					});
 			},
+			// 添加车辆
 			handleAddCar(){
 				if(!this.$u.test.carNo(this.newPlateNumber)){
 					this.$refs.uToast.show({
@@ -97,50 +109,64 @@
 					});
 					return
 				}
-				let param ={
+				let param = {
 					vehicleNo: this.newPlateNumber,
 					vehicleColor: this.vehicleColor
 				};
 				this.$u.api.addCar(param)
-				.then(res=>{
-					this.$refs.uToast.show({
-						title: res.msg,
-						type: 'success',
-					});
-					this.handlegetMycars();
-					console.log('getMycars',res)
-				}).catch(err=>{
-					this.$refs.uToast.show({
-						title: err.msg,
-						type: 'error',
+					.then(res=>{
+						if (res.code === 200) {
+							this.$refs.uToast.show({
+								title: res.msg,
+								type: 'success',
+							});
+							this.handlegetMycars();
+						} else {
+							this.$refs.uToast.show({
+								title: res.msg,
+								type: 'error',
+							});
+						}
+					})
+					.catch(err=>{
+						this.$refs.uToast.show({
+							title: '操作失败!',
+							type: 'error',
+						});
 					});
-					console.log('getMycars ',err)
-				});
 			},
-			handleDelCar(id,content){
+			// 删除车辆
+			handleDelCar(id, content){
 				this.delCarContent = `是否删除${content}`;
 				this.delCarId = id;
 				this.delCarshow = true;
 				
 			},
+			// 确认删除
 			confirmDelCar(){
-				console.log(this.delCarId);
 				this.$u.api.delCar(this.delCarId)
-				.then(res=>{
-					this.$refs.uToast.show({
-						title: res.msg,
-						type: 'success',
-					});
-					this.handlegetMycars();
-					console.log('getMycars',res)
-				}).catch(err=>{
-					this.$refs.uToast.show({
-						title: err.msg,
-						type: 'error',
-					});
-					console.log('getMycars ',err)
-				});				
+					.then(res=>{
+						if (res.code === 200) {
+							this.$refs.uToast.show({
+								title: res.msg,
+								type: 'success',
+							});
+							this.handlegetMycars();
+						} else {
+							this.$refs.uToast.show({
+								title: res.msg,
+								type: 'error',
+							});
+						}
+					})
+					.catch(err=>{
+						this.$refs.uToast.show({
+							title: '操作失败!',
+							type: 'error',
+						});
+					});				
 			},
+			// 点击输入框
 			messageInputClick(){
 				this.keyboardshow = true;
 			},
@@ -148,36 +174,41 @@
 			keyboardChange(val) {
 				// 将每次按键的值拼接到value变量中,注意+=写法
 				this.newPlateNumber += val;
-				console.log(this.newPlateNumber);
 			},
 			// 退格键被点击
 			backspace() {
 				// 删除value的最后一个字符
 				if(this.newPlateNumber.length) this.newPlateNumber = this.newPlateNumber.substr(0, this.newPlateNumber.length - 1);
-				console.log(this.newPlateNumber);
 			},
+			// 键盘输入完成后确认
 			keyboardConfirm(){
 				this.colorShow = true;
 			},
+			// 确认颜色
 			confirmColor(e){
 				this.vehicleColor = this.colorList[e].colorCode;
 			},
-			// 设置默认车辆
+			// 设置默认车辆操作
 			handlesetDefault(id){
 				this.$u.api.setDefaultCar({id:id})
 				.then(res=>{
-					this.$refs.uToast.show({
-						title: res.msg,
-						type: 'success',
-					});
-					this.handlegetMycars();
-					console.log('handlesetDefault',res)
+					if (res.code === 200) {
+						this.$refs.uToast.show({
+							title: res.msg,
+							type: 'success',
+						});
+						this.handlegetMycars();
+					} else {
+						this.$refs.uToast.show({
+							title: res.msg,
+							type: 'error',
+						});
+					}
 				}).catch(err=>{
 					this.$refs.uToast.show({
-						title: err.msg,
+						title: '操作失败!',
 						type: 'error',
 					});
-					console.log('handlesetDefault err',err)
 				});	
 			}
 			

+ 38 - 0
uni_modules/z-paging/changelog.md

@@ -0,0 +1,38 @@
+## 1.9.3(2021-07-12)
+1.延后首次加载自动请求的时机,使其在onLoad之后触发。  
+2.修复使用`safe-area-inset-bottom`时,距离顶部有段空白的BUG。  
+3.优化横向切换与下拉刷新手势的兼容,横向切换时禁止下拉刷新的细节调整。  
+## 1.9.2(2021-07-09)
+## 【注意】由V1.9.0起,fixed属性默认值为true,z-paging默认会铺满屏幕。老项目更新请注意,使用侧滑滚动切换选项卡或需要局部使用z-paging请设置:fixed="false"。如果您希望fixed属性默认为false,请参考文档:z-paging.com,将fixed默认值设置为false。 
+1.新增`completeByNoMore(data,nomore)`方法,支持在请求结束时自行控制是否有更多数据。  
+2.修复在微信小程序中,:fixed="false"时列表未展示的BUG。  
+3.进一步兼容和整合vue和nvue的写法。  
+4.其他细节调整与优化。
+## 1.9.1(2021-07-07)
+# 【注意】由V1.9.0起,fixed属性默认值为true,z-paging默认会铺满屏幕。老项目更新请注意,使用侧滑滚动切换选项卡或需要局部使用z-paging请设置:fixed="false"。如果您希望fixed属性默认为false,请参考文档:z-paging.com,将fixed默认值设置为false。
+1.修复在一些情况下空数据图无法展示或展示位置不正确的问题。  
+2.其他细节优化。
+## 1.9.0(2021-07-04)
+## 【注意1】由V1.9.0起,fixed属性默认值为true,z-paging默认会铺满屏幕。老项目更新请注意,使用侧滑滚动切换选项卡或需要局部使用z-paging请设置:fixed="false"。如果您希望fixed属性默认为false,请参考下方的【全局配置】,将fixed默认值设置为false。  
+1.修复使用slot="top"时可能出现的置顶view点击无效的问题。  
+2.修复设置`show-loading-more-when-reload`后,下拉刷新时底部加载更多view也处于loading状态的问题。  
+3.其他细节调整。
+
+## 1.8.9(2021-07-01)
+1.默认状态由`translateY(0px)`修改为`none`,修复因使用transform引发的子view fixed被降级为absoult的BUG。  
+2.修复在nvue安卓中,通过`loading-more-custom-style`修改加载更多view的高度时,加载更多view被裁剪的BUG。  
+3.去掉reload自动滚动到顶部的动画。  
+4.当`loading-more-enabled`设置为false,且`show-loading-more-when-reload`为true时,`show-loading-more-when-reload`优先。  
+5.修复在nvue 安卓中使用聊天记录模式,只有一页时底部有一段空白的BUG。  
+6.`concat`为false时,不再自动清空list。  
+## 1.8.8(2021-06-30)
+1.修复设置了`show-loading-more-when-reload`后,下拉刷新时展示加载更多loading且无数据时展示加载更多view的BUG。  
+2.修复在nvue中,在安卓设备上下拉刷新view底部有一根白色横线的BUG。  
+3.修复在nvue中,设置了`show-refresher-when-reload`后,部分平台reload时页面卡住闪退的BUG。  
+4.在nvue中支持`slot="top"`和`slot="bottom"`,使其写法与vue相同。  
+5.修改部分内部通用变量名,以避免在一些项目中引入mixins与其冲突的问题。  
+6.修复在nvue中,滚动到顶部会停顿一下,继续上拉才可以加载更多的BUG。  
+7.新增`concat`属性,支持控制是否自动拼接complete传过来的数组。
+## 1.8.7(2021-06-22)
+1.新增滑动切换选项卡简化写法及演示。  
+2.修复reload自动滚动到顶部无效的BUG。

+ 170 - 0
uni_modules/z-paging/components/z-paging-empty-view/z-paging-empty-view.vue

@@ -0,0 +1,170 @@
+<!-- z-paging -->
+<!-- github地址:https://github.com/SmileZXLee/uni-z-paging -->
+<!-- dcloud地址:https://ext.dcloud.net.cn/plugin?id=3935 -->
+<!-- 反馈QQ群:790460711 -->
+
+<!-- 空数据占位view,此组件支持easycom规范,可以在项目中直接引用 -->
+<template>
+	<view class="zp-container" :style="[finalEmptyViewStyle]">
+		<view class="zp-main">
+			<image v-if="!emptyViewImg.length" class="zp-main-image" :style="[emptyViewImgStyle]" :src="emptyImg"></image>
+			<image v-else class="zp-main-image" mode="aspectFit" :style="[emptyViewImgStyle]" :src="emptyViewImg"></image>
+			<text class="zp-main-title" :style="[emptyViewTitleStyle]">{{emptyViewText}}</text>
+			<text v-if="showEmptyViewReload" class="zp-main-error-btn" :style="[emptyViewReloadStyle]"
+				@click="reloadClick">{{emptyViewReloadText}}</text>
+		</view>
+	</view>
+</template>
+
+<script>
+	import zStatic from '../z-paging/js/z-paging-static'
+	export default {
+		data() {
+			return {
+				base64Empty: zStatic.base64Empty,
+				base64Error: zStatic.base64Error
+			};
+		},
+		props: {
+			//空数据描述文字
+			emptyViewText: {
+				type: String,
+				default: function() {
+					return '没有数据哦~'
+				}
+			},
+			//空数据图片
+			emptyViewImg: {
+				type: String,
+				default: function() {
+					return ''
+				}
+			},
+			//是否显示空数据图重新加载按钮
+			showEmptyViewReload: {
+				type: Boolean,
+				default: function() {
+					return false
+				}
+			},
+			//空数据点击重新加载文字
+			emptyViewReloadText: {
+				type: String,
+				default: function() {
+					return '重新加载'
+				}
+			},
+			//是否是加载失败
+			isLoadFailed: {
+				type: Boolean,
+				default: function() {
+					return false
+				}
+			},
+			//空数据图样式
+			emptyViewStyle: {
+				type: Object,
+				default: function() {
+					return {}
+				}
+			},
+			//空数据图img样式
+			emptyViewImgStyle: {
+				type: Object,
+				default: function() {
+					return {}
+				}
+			},
+			//空数据图描述文字样式
+			emptyViewTitleStyle: {
+				type: Object,
+				default: function() {
+					return {}
+				}
+			},
+			//空数据图重新加载按钮样式
+			emptyViewReloadStyle: {
+				type: Object,
+				default: function() {
+					return {}
+				}
+			},
+			//空数据图z-index
+			emptyViewZIndex: {
+				type: Number,
+				default: function() {
+					return 9
+				}
+			}
+		},
+		computed: {
+			emptyImg() {
+				if (this.isLoadFailed) {
+					return this.base64Error;
+				} else {
+					return this.base64Empty;
+				}
+			},
+			finalEmptyViewStyle(){
+				this.emptyViewStyle['z-index'] = this.emptyViewZIndex;
+				return this.emptyViewStyle;
+			}
+		},
+		methods: {
+			reloadClick() {
+				this.$emit('reload');
+			}
+		}
+	}
+</script>
+
+<style scoped>
+	.zp-container {
+		/* #ifndef APP-NVUE */
+		position: absolute;
+		top: 0;
+		left: 0;
+		width: 100%;
+		height: 100%;
+		display: flex;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		flex: 1;
+		/* #endif */
+		align-items: center;
+		justify-content: center;
+	}
+
+	.zp-main {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		margin-top: -150rpx;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		margin-top: -100rpx;
+		/* #endif */
+		flex-direction: column;
+		align-items: center;
+	}
+
+	.zp-main-image {
+		width: 200rpx;
+		height: 200rpx;
+	}
+
+	.zp-main-title {
+		font-size: 26rpx;
+		color: #aaaaaa;
+		text-align: center;
+		margin-top: 10rpx;
+	}
+
+	.zp-main-error-btn {
+		font-size: 26rpx;
+		padding: 8rpx 24rpx;
+		border: solid 1px #dddddd;
+		border-radius: 6rpx;
+		color: #aaaaaa;
+		margin-top: 50rpx;
+	}
+</style>

+ 86 - 0
uni_modules/z-paging/components/z-paging-swiper-item/z-paging-swiper-item.vue

@@ -0,0 +1,86 @@
+<!-- z-paging -->
+<!-- github地址:https://github.com/SmileZXLee/uni-z-paging -->
+<!-- dcloud地址:https://ext.dcloud.net.cn/plugin?id=3935 -->
+<!-- 反馈QQ群:790460711 -->
+
+<!-- 滑动切换选项卡swiper-item,此组件支持easycom规范,可以在项目中直接引用 -->
+<template>
+	<view class="zp-swiper-item-container">
+		<z-paging ref="paging" :fixed="false" @query="_queryList" @listChange="_updateList" :mounted-auto-call-reload="false"
+			style="height: 100%;">
+			<slot></slot>
+		</z-paging>
+	</view>
+</template>
+
+<script>
+	import zPaging from '../z-paging/z-paging'
+	export default {
+		name: "z-paging-swiper-item",
+		components: {
+			zPaging
+		},
+		data() {
+			return {
+				firstLoaded: false
+			}
+		},
+		props: {
+			//当前组件的index,也就是当前组件是swiper中的第几个
+			tabIndex: {
+				type: Number,
+				default: function() {
+					return 0
+				}
+			},
+			//当前swiper切换到第几个index
+			currentIndex: {
+				type: Number,
+				default: function() {
+					return 0
+				}
+			},
+		},
+		watch: {
+			currentIndex: {
+				handler(newVal, oldVal) {
+					if (newVal === this.tabIndex) {
+						//懒加载,当滑动到当前的item时,才去加载
+						if (!this.firstLoaded) {
+							setTimeout(() => {
+								this.$refs.paging.reload();
+							}, 5);
+						}
+					}
+				},
+				immediate: true
+			}
+		},
+		methods: {
+			reload(data) {
+				this.$refs.paging.reload(data);
+			},
+			complete(data) {
+				this.firstLoaded = true;
+				this.$refs.paging.complete(data);
+			},
+			_queryList(pageNo, pageSize) {
+				this.$emit('query', pageNo, pageSize);
+			},
+			_updateList(list) {
+				this.$emit('updateList', list);
+			}
+		}
+	}
+</script>
+
+<style scoped>
+	.zp-swiper-item-container {
+		/* #ifndef APP-NVUE */
+		height: 100%;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		flex: 1;
+		/* #endif */
+	}
+</style>

+ 123 - 0
uni_modules/z-paging/components/z-paging-swiper/z-paging-swiper.vue

@@ -0,0 +1,123 @@
+<!-- z-paging -->
+<!-- github地址:https://github.com/SmileZXLee/uni-z-paging -->
+<!-- dcloud地址:https://ext.dcloud.net.cn/plugin?id=3935 -->
+<!-- 反馈QQ群:790460711 -->
+
+<!-- 滑动切换选项卡swiper,此组件支持easycom规范,可以在项目中直接引用 -->
+<template>
+	<view :class="fixed?'zp-swiper-container zp-swiper-container-fixed':'zp-swiper-container'" :style="[swiperStyle]">
+		<slot v-if="$slots.top" name="top"></slot>
+		<view class="zp-swiper-super">
+			<view class="zp-swiper">
+				<slot/></slot>
+			</view>
+		</view>
+		<slot v-if="$slots.bottom" name="bottom"></slot>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: "z-paging-swiper",
+		data() {
+			return {
+				systemInfo: null
+			};
+		},
+		props: {
+			//是否使用fixed布局,默认为是
+			fixed: {
+				type: Boolean,
+				default: true
+			},
+			//是否开启底部安全区域适配
+			safeAreaInsetBottom: {
+				type: Boolean,
+				default: false
+			}
+		},
+		mounted() {
+			this.$nextTick(() => {
+				this.systemInfo = uni.getSystemInfoSync();
+			})
+		},
+		computed: {
+			swiperStyle() {
+				if (!this.systemInfo) {
+					return {};
+				}
+				let swiperStyle = {};
+				const windowTop = this.systemInfo.windowTop;
+				const windowBottom = this.systemInfo.windowBottom;
+				if (this.fixed) {
+					if (windowTop && windowTop !== undefined) {
+						swiperStyle.top = windowTop + 'px';
+					}
+					let bottom = 0;
+					if (windowBottom && windowBottom !== undefined) {
+						bottom = windowBottom;
+					}
+					if (this.safeAreaInsetBottom) {
+						bottom += this.safeAreaBottom;
+					}
+					swiperStyle.bottom = bottom + 'px';
+				}
+				return swiperStyle;
+			},
+			safeAreaBottom() {
+				if (!this.systemInfo) {
+					return 0;
+				}
+				let safeAreaBottom = 0;
+				// #ifdef APP-PLUS || H5 || MP-WEIXIN
+				safeAreaBottom = this.systemInfo.safeAreaInsets.bottom || 0;
+				// #endif
+				return safeAreaBottom;
+			}
+		}
+	}
+</script>
+
+<style scoped>
+	.zp-swiper-container {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		flex: 1;
+	}
+
+	.zp-swiper-container-fixed {
+		position: fixed;
+		/* #ifndef APP-NVUE */
+		height: auto;
+		width: auto;
+		/* #endif */
+		top: 0;
+		left: 0;
+		bottom: 0;
+		right: 0;
+	}
+
+	.zp-swiper-super {
+		flex: 1;
+		position: relative;
+	}
+
+	.zp-swiper {
+		/* #ifndef APP-NVUE */
+		height: 100%;
+		width: 100%;
+		position: absolute;
+		top: 0;
+		left: 0;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		flex: 1;
+		/* #endif */
+	}
+	
+	.zp-swiper-item {
+		height: 100%;
+	}
+</style>

+ 158 - 0
uni_modules/z-paging/components/z-paging/components/z-paging-load-more.vue

@@ -0,0 +1,158 @@
+<!-- z-paging -->
+<!-- github地址:https://github.com/SmileZXLee/uni-z-paging -->
+<!-- dcloud地址:https://ext.dcloud.net.cn/plugin?id=3935 -->
+<!-- 反馈QQ群:790460711 -->
+
+<!-- 上拉加载更多view -->
+<template>
+	<view class="zp-load-more-container" :style="[zConfig.loadingMoreCustomStyle]">
+		<text
+			:class="zConfig.defaultThemeStyle==='white'?'zp-loading-more-line zp-loading-more-line-white':'zp-loading-more-line zp-loading-more-line-black'"
+			:style="[zConfig.loadingMoreNoMoreLineCustomStyle]"
+			v-if="zConfig.showLoadingMoreNoMoreLine&&zConfig.loadingStatus===2"></text>
+		<!-- #ifndef APP-NVUE -->
+		<image v-if="zConfig.loadingStatus===1&&zConfig.loadingMoreLoadingIconCustomImage.length"
+			:src="zConfig.loadingMoreLoadingIconCustomImage" class="zp-loading-more-line-loading-custom-image">
+		</image>
+		<image
+			v-if="zConfig.loadingStatus===1&&zConfig.loadingMoreLoadingIconType==='flower'&&!zConfig.loadingMoreLoadingIconCustomImage.length"
+			class="zp-loading-more-line-loading-image" :style="[zConfig.loadingMoreLoadingIconCustomStyle]"
+			:src="zConfig.defaultThemeStyle==='white'?base64FlowerWhite:base64Flower">
+		</image>
+		<!-- #endif -->
+		<!-- #ifdef APP-NVUE -->
+		<view>
+			<loading-indicator v-if="zConfig.loadingStatus===1"
+				:style="[{color:zConfig.defaultThemeStyle==='white'?'white':'#777777'}]" :animating="true"
+				class="zp-loading-more-line-loading-image">
+			</loading-indicator>
+		</view>
+		<!-- #endif -->
+		<text
+			v-if="zConfig.loadingStatus===1&&zConfig.loadingMoreLoadingIconType==='circle'&&!zConfig.loadingMoreLoadingIconCustomImage.length"
+			:class="zConfig.defaultThemeStyle==='white'?'zp-loading-more-line-loading-view zp-loading-more-line-loading-view-white':'zp-loading-more-line-loading-view zp-loading-more-line-loading-view-black'"
+			:style="[zConfig.loadingMoreLoadingIconCustomStyle]"></text>
+		<text
+			:class="zConfig.defaultThemeStyle==='white'?'zp-loading-more-text zp-loading-more-text-white':'zp-loading-more-text zp-loading-more-text-black'">{{ownLoadingMoreText}}</text>
+		<text
+			:class="zConfig.defaultThemeStyle==='white'?'zp-loading-more-line zp-loading-more-line-white':'zp-loading-more-line zp-loading-more-line-black'"
+			:style="[zConfig.loadingMoreNoMoreLineCustomStyle]"
+			v-if="zConfig.showLoadingMoreNoMoreLine&&zConfig.loadingStatus===2"></text>
+	</view>
+</template>
+<script>
+	import zStatic from '../js/z-paging-static'
+	export default {
+		name: 'z-paging-load-more',
+		data() {
+			return {
+				base64Arrow: zStatic.base64Arrow,
+				base64Flower: zStatic.base64Flower,
+				base64FlowerWhite: zStatic.base64FlowerWhite,
+			};
+		},
+		props: ['zConfig'],
+		computed: {
+			ownLoadingMoreText() {
+				const loadingMoreText = this.loadingStatusTextMap[this.zConfig.loadingStatus];
+				return loadingMoreText;
+			},
+			loadingStatusTextMap() {
+				return {
+					0: this.zConfig.loadingMoreDefaultText,
+					1: this.zConfig.loadingMoreLoadingText,
+					2: this.zConfig.loadingMoreNoMoreText,
+					3: this.zConfig.loadingMoreFailText,
+				}
+			}
+		}
+	}
+</script>
+
+<style scoped>
+	@import "../css/z-paging-static.css";
+
+	.zp-load-more-container {
+		height: 80rpx;
+		font-size: 27rpx;
+		/* #ifndef APP-NVUE */
+		clear: both;
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		justify-content: center;
+	}
+
+	.zp-loading-more-line-loading-custom-image {
+		color: #a4a4a4;
+		margin-right: 8rpx;
+		width: 28rpx;
+		height: 28rpx;
+		/* #ifndef APP-NVUE */
+		animation: loading-circle 1s linear infinite;
+		/* #endif */
+	}
+
+	.zp-loading-more-line-loading-view {
+		margin-right: 8rpx;
+		width: 22rpx;
+		height: 23rpx;
+		border: 3rpx solid #dddddd;
+		border-radius: 50%;
+		/* #ifndef APP-NVUE */
+		animation: loading-circle 1s linear infinite;
+		/* #endif */
+	}
+
+	.zp-loading-more-line-loading-view-black {
+		border-color: #c8c8c8;
+		border-top-color: #444444;
+	}
+
+	.zp-loading-more-line-loading-view-white {
+		border-color: #aaaaaa;
+		border-top-color: #ffffff;
+	}
+
+	.zp-loading-more-text {
+		/* #ifdef APP-NVUE */
+		font-size: 30rpx;
+		margin: 0rpx 10rpx;
+		/* #endif */
+	}
+
+	.zp-loading-more-text-black {
+		color: #a4a4a4;
+	}
+
+	.zp-loading-more-text-white {
+		color: #efefef;
+	}
+
+	.zp-loading-more-line {
+		height: 1px;
+		width: 100rpx;
+		margin: 0rpx 10rpx;
+	}
+
+	.zp-loading-more-line-black {
+		background-color: #eeeeee;
+	}
+
+	.zp-loading-more-line-white {
+		background-color: #efefef;
+	}
+
+	@keyframes loading-circle {
+		0% {
+			-webkit-transform: rotate(0deg);
+			transform: rotate(0deg);
+		}
+
+		100% {
+			-webkit-transform: rotate(360deg);
+			transform: rotate(360deg);
+		}
+	}
+</style>

+ 259 - 0
uni_modules/z-paging/components/z-paging/components/z-paging-refresh.vue

@@ -0,0 +1,259 @@
+<!-- z-paging -->
+<!-- github地址:https://github.com/SmileZXLee/uni-z-paging -->
+<!-- dcloud地址:https://ext.dcloud.net.cn/plugin?id=3935 -->
+<!-- 反馈QQ群:790460711 -->
+
+<!-- 下拉刷新view -->
+<template>
+	<view style="height: 100%;">
+		<view
+			:class="['zp-custom-refresher-container',{'zp-custom-refresher-container-padding':showRefresherUpdateTime}]"
+			style="height: 100%;">
+			<view class="zp-custom-refresher-left">
+				<image v-if="refresherStatus!==2" :class="refresherLeftImageClass"
+					:style="[{width: showRefresherUpdateTime?'36rpx':'30rpx',height: showRefresherUpdateTime?'36rpx':'30rpx','margin-right': showRefresherUpdateTime?'20rpx':'8rpx'}]"
+					:src="defaultThemeStyle==='white'?base64ArrowWhite:base64Arrow">
+				</image>
+				<!-- #ifndef APP-NVUE -->
+				<image v-else class="zp-loading-more-line-loading-image zp-custom-refresher-left-image"
+					:style="[{width: showRefresherUpdateTime?'36rpx':'30rpx',height: showRefresherUpdateTime?'36rpx':'30rpx','margin-right': showRefresherUpdateTime?'20rpx':'8rpx'}]"
+					:src="defaultThemeStyle==='white'?base64FlowerWhite:base64Flower">
+				</image>
+				<!-- #endif -->
+				<!-- #ifdef APP-NVUE -->
+				<view v-else :style="[{'margin-right':showRefresherUpdateTime?'18rpx':'12rpx'}]">
+					<loading-indicator
+						:class="systemInfo.platform==='ios'?'zp-loading-image-ios':'zp-loading-image-android'"
+						:style="[{color:defaultThemeStyle==='white'?'white':'#777777'}]" :animating="true">
+					</loading-indicator>
+				</view>
+				<!-- #endif -->
+			</view>
+			<view class="zp-custom-refresher-right">
+				<text class="zp-custom-refresher-right-text"
+					:style="[refresherRightTextStyle]">{{refresherStatusTextMap[refresherStatus]||refresherDefaultText}}
+				</text>
+				<text class="zp-custom-refresher-right-text zp-custom-refresher-right-time-text"
+					:style="[refresherRightTextStyle]"
+					v-if="showRefresherUpdateTime&&refresherTimeText.length">{{refresherTimeText}}
+				</text>
+			</view>
+		</view>
+	</view>
+</template>
+<script>
+	const systemInfo = uni.getSystemInfoSync();
+	import zStatic from '../js/z-paging-static'
+	import {
+		getRefesrherFormatTimeByKey
+	} from '../js/z-paging-utils'
+	export default {
+		name: 'z-paging-refresh',
+		data() {
+			return {
+				systemInfo: systemInfo,
+				base64Arrow: zStatic.base64Arrow,
+				base64ArrowWhite: zStatic.base64ArrowWhite,
+				base64Flower: zStatic.base64Flower,
+				base64FlowerWhite: zStatic.base64FlowerWhite,
+				refresherTimeText: '',
+				isRefresherLeftImageClassLoaded: false
+			};
+		},
+		props: {
+			'refresherStatus': {
+				default: 0
+			},
+			'defaultThemeStyle': {},
+			'refresherDefaultText': {},
+			'refresherPullingText': {},
+			'refresherPullingText': {},
+			'refresherRefreshingText': {},
+			'showRefresherUpdateTime': {
+				default: false
+			},
+			'refresherUpdateTimeKey': {}
+		},
+		computed: {
+			refresherStatusTextMap() {
+				this.updateTime(this.refresherUpdateTimeKey);
+				return {
+					0: this.refresherDefaultText,
+					1: this.refresherPullingText,
+					2: this.refresherRefreshingText
+				};
+			},
+			refresherLeftImageClass() {
+				let refresherLeftImageClass = '';
+				if (this.refresherStatus === 0) {
+					if (this.isRefresherLeftImageClassLoaded) {
+						refresherLeftImageClass = 'zp-custom-refresher-left-image zp-custom-refresher-arrow-down';
+					} else {
+						this.isRefresherLeftImageClassLoaded = true;
+						refresherLeftImageClass =
+							'zp-custom-refresher-left-image zp-custom-refresher-arrow-down-no-duration';
+					}
+				} else {
+					refresherLeftImageClass = 'zp-custom-refresher-left-image zp-custom-refresher-arrow-top';
+				}
+				return refresherLeftImageClass;
+			},
+			refresherRightTextStyle() {
+				let refresherRightTextStyle = {};
+				let color = '#555555';
+				if (this.defaultThemeStyle === 'white') {
+					color = '#efefef';
+				}
+				// #ifdef APP-NVUE
+				if (this.showRefresherUpdateTime) {
+					refresherRightTextStyle = {
+						'height': '40rpx',
+						'line-height': '40rpx'
+					};
+				} else {
+					refresherRightTextStyle = {
+						'height': '80rpx',
+						'line-height': '80rpx'
+					};
+				}
+				// #endif
+				refresherRightTextStyle['color'] = color;
+				return refresherRightTextStyle;
+			}
+		},
+		methods: {
+			updateTime(refresherUpdateTimeKey) {
+				if (!refresherUpdateTimeKey) {
+					refresherUpdateTimeKey = this.refresherUpdateTimeKey;
+				}
+				if (this.showRefresherUpdateTime) {
+					this.refresherTimeText = getRefesrherFormatTimeByKey(refresherUpdateTimeKey);
+				}
+			}
+		}
+	}
+</script>
+
+<style scoped>
+	@import "../css/z-paging-static.css";
+
+	.zp-custom-refresher-container {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+	}
+
+	.zp-custom-refresher-container-padding {
+		/* #ifdef APP-NVUE */
+		padding: 15rpx 0rpx;
+		/* #endif */
+	}
+
+	.zp-custom-refresher-left {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		overflow: hidden;
+	}
+
+	.zp-custom-refresher-left-image {
+		/* #ifndef APP-NVUE */
+		transform: rotate(180deg);
+		margin-top: 2rpx;
+		/* #endif */
+		/* #ifdef MP-ALIPAY */
+		margin-top: 0rpx;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		transition-duration: .2s;
+		transition-property: transform;
+		color: #666666;
+		/* #endif */
+	}
+
+	.zp-custom-refresher-arrow-top {
+		/* #ifndef APP-NVUE */
+		animation: refresher-arrow-top .2s linear;
+		-webkit-animation: refresher-arrow-top .2s linear;
+		animation-fill-mode: forwards;
+		-webkit-animation-fill-mode: forwards;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		transform: rotate(0deg);
+		/* #endif */
+	}
+
+	.zp-custom-refresher-arrow-down {
+		/* #ifndef APP-NVUE */
+		animation: refresher-arrow-down .2s linear;
+		-webkit-animation: refresher-arrow-down .2s linear;
+		animation-fill-mode: forwards;
+		-webkit-animation-fill-mode: forwards;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		transform: rotate(180deg);
+		/* #endif */
+	}
+
+	.zp-custom-refresher-arrow-down-no-duration {
+		/* #ifndef APP-NVUE */
+		animation: refresher-arrow-down 0s linear;
+		-webkit-animation: refresher-arrow-down 0s linear;
+		animation-fill-mode: forwards;
+		-webkit-animation-fill-mode: forwards;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		transform: rotate(180deg);
+		/* #endif */
+	}
+
+	.zp-custom-refresher-right {
+		font-size: 27rpx;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		align-items: center;
+		justify-content: center;
+	}
+
+	.zp-custom-refresher-right-text {
+		/* #ifdef APP-NVUE */
+		font-size: 28rpx;
+		/* #endif */
+	}
+
+	.zp-custom-refresher-right-time-text {
+		margin-top: 10rpx;
+		font-size: 24rpx;
+	}
+
+	@keyframes refresher-arrow-top {
+		0% {
+			-webkit-transform: rotate(180deg);
+			transform: rotate(180deg);
+		}
+
+		100% {
+			-webkit-transform: rotate(0deg);
+			transform: rotate(0deg);
+		}
+	}
+
+	@keyframes refresher-arrow-down {
+		0% {
+			-webkit-transform: rotate(0deg);
+			transform: rotate(0deg);
+		}
+
+		100% {
+			-webkit-transform: rotate(180deg);
+			transform: rotate(180deg);
+		}
+	}
+</style>

+ 157 - 0
uni_modules/z-paging/components/z-paging/css/z-paging-main.css

@@ -0,0 +1,157 @@
+/* z-paging
+github地址:https://github.com/SmileZXLee/uni-z-paging
+dcloud地址:https://ext.dcloud.net.cn/plugin?id=3935
+反馈QQ群:790460711
+*/
+
+.z-paging-content {
+	position: relative;
+	/* #ifndef APP-NVUE */
+	display: flex;
+	width: 100%;
+	height: 100%;
+	/* #endif */
+	flex-direction: column;
+}
+
+.z-paging-content-fixed {
+	position: fixed;
+	/* #ifndef APP-NVUE */
+	height: auto;
+	width: auto;
+	/* #endif */
+	top: 0;
+	left: 0;
+	bottom: 0;
+	right: 0;
+}
+
+.zp-page-scroll-top,
+.zp-page-scroll-bottom {
+	/* #ifndef APP-NVUE */
+	width: auto;
+	/* #endif */
+	position: fixed;
+	left: 0;
+	right: 0;
+	z-index: 999;
+}
+
+.zp-scroll-view-super {
+	flex: 1;
+	position: relative;
+}
+
+.zp-scroll-view {
+	height: 100%;
+	width: 100%;
+}
+
+.zp-scroll-view-absolute {
+	position: absolute;
+	top: 0;
+	left: 0;
+}
+
+.zp-paging-touch-view {
+	width: 100%;
+	height: 100%;
+	position: relative;
+}
+
+.zp-fixed-bac-view {
+	position: absolute;
+	width: 100%;
+	top: 0;
+	left: 0;
+	height: 200px;
+}
+
+.zp-paging-main {
+	height: 100%;
+	/* #ifndef APP-NVUE */
+	display: flex;
+	/* #endif */
+	flex-direction: column;
+}
+
+.zp-paging-container {
+	flex: 1;
+	position: relative;
+}
+
+.zp-chat-record-loading-container {
+	/* #ifndef APP-NVUE */
+	display: flex;
+	width: 100%;
+	/* #endif */
+	/* #ifdef APP-NVUE */
+	width: 750rpx;
+	/* #endif */
+	align-items: center;
+	justify-content: center;
+	height: 60rpx;
+	font-size: 26rpx;
+}
+
+.zp-chat-record-loading-custom-image {
+	width: 35rpx;
+	height: 35rpx;
+	/* #ifndef APP-NVUE */
+	animation: loading-flower 1s linear infinite;
+	/* #endif */
+}
+
+.zp-custom-refresher-container {
+	/* #ifndef APP-NVUE */
+	display: flex;
+	/* #endif */
+	flex-direction: row;
+	justify-content: center;
+	align-items: center;
+}
+
+.zp-back-to-top {
+	width: 76rpx;
+	height: 76rpx;
+	z-index: 999;
+	position: absolute;
+	bottom: 0rpx;
+	right: 25rpx;
+	transition-duration: .3s;
+	transition-property: opacity;
+}
+
+.zp-back-to-top-show {
+	opacity: 1;
+}
+
+.zp-back-to-top-hide {
+	opacity: 0;
+}
+
+.zp-back-to-top-img {
+	/* #ifndef APP-NVUE */
+	width: 100%;
+	height: 100%;
+	/* #endif */
+	/* #ifdef APP-NVUE */
+	flex: 1;
+	/* #endif */
+	z-index: 999;
+}
+
+.zp-empty-view{
+	/* #ifdef APP-NVUE */
+	height: 100%;
+	/* #endif */
+	flex: 1;
+}
+
+.zp-n-refresh-container {
+	/* #ifndef APP-NVUE */
+	display: flex;
+	/* #endif */
+	justify-content: center;
+	width: 750rpx;
+}

+ 38 - 0
uni_modules/z-paging/components/z-paging/css/z-paging-static.css

@@ -0,0 +1,38 @@
+/* z-paging
+github地址:https://github.com/SmileZXLee/uni-z-paging
+dcloud地址:https://ext.dcloud.net.cn/plugin?id=3935
+反馈QQ群:790460711
+
+公用的静态css资源 */
+
+.zp-loading-more-line-loading-image {
+	margin-right: 8rpx;
+	width: 28rpx;
+	height: 28rpx;
+	/* #ifndef APP-NVUE */
+	animation: loading-flower 1s steps(12) infinite;
+	/* #endif */
+	color: #666666;
+}
+
+.zp-loading-image-ios{
+	width: 20px;
+	height: 20px;
+}
+
+.zp-loading-image-android{
+	width: 32rpx;
+	height: 32rpx;
+}
+
+@keyframes loading-flower {
+	0% {
+		-webkit-transform: rotate(0deg);
+		transform: rotate(0deg);
+	}
+
+	to {
+		-webkit-transform: rotate(1turn);
+		transform: rotate(1turn);
+	}
+}

+ 32 - 0
uni_modules/z-paging/components/z-paging/js/z-paging-config.js

@@ -0,0 +1,32 @@
+// z-paging
+// github地址:https://github.com/SmileZXLee/uni-z-paging
+// dcloud地址:https://ext.dcloud.net.cn/plugin?id=3935
+// 反馈QQ群:790460711
+// z-paging配置文件
+
+let config = null;
+let getedStorage = false;
+const storageKey = 'Z-PAGING-CONFIG-STORAGE-KEY'
+
+function setConfig(value) {
+	try {
+		uni.setStorageSync(storageKey, value);
+	} catch {}
+}
+
+function getConfig() {
+	try {
+		if (getedStorage) {
+			return config;
+		}
+		config = uni.getStorageSync(storageKey);
+		getedStorage = true;
+	} catch {
+		return null;
+	}
+}
+
+module.exports = {
+	setConfig,
+	getConfig
+};

+ 150 - 0
uni_modules/z-paging/components/z-paging/js/z-paging-i18n.js

@@ -0,0 +1,150 @@
+// z-paging
+// github地址:https://github.com/SmileZXLee/uni-z-paging
+// dcloud地址:https://ext.dcloud.net.cn/plugin?id=3935
+// 反馈QQ群:790460711
+// z-paging国际化(支持中文、中文繁体和英文)
+
+const i18nUpdateKey = 'z-paging-i18n-update';
+
+const refresherDefaultText = {
+	'en': 'Pull down to refresh',
+	'zh-cn': '继续下拉刷新',
+	'zh-hant-cn': '繼續下拉重繪',
+}
+const refresherPullingText = {
+	'en': 'Release to refresh',
+	'zh-cn': '松开立即刷新',
+	'zh-hant-cn': '鬆開立即重繪',
+}
+const refresherRefreshingText = {
+	'en': 'Refreshing...',
+	'zh-cn': '正在刷新...',
+	'zh-hant-cn': '正在重繪...',
+}
+
+const loadingMoreDefaultText = {
+	'en': 'Click to load more',
+	'zh-cn': '点击加载更多',
+	'zh-hant-cn': '點擊加載更多',
+}
+const loadingMoreLoadingText = {
+	'en': 'Loading...',
+	'zh-cn': '正在加载...',
+	'zh-hant-cn': '正在加載...',
+}
+const loadingMoreNoMoreText = {
+	'en': 'No more data',
+	'zh-cn': '没有更多了',
+	'zh-hant-cn': '沒有更多了',
+}
+const loadingMoreFailText = {
+	'en': 'Load failed,click to reload',
+	'zh-cn': '加载失败,点击重新加载',
+	'zh-hant-cn': '加載失敗,點擊重新加載',
+}
+
+const emptyViewText = {
+	'en': 'No data',
+	'zh-cn': '没有数据哦~',
+	'zh-hant-cn': '沒有數據哦~',
+}
+
+const emptyViewReloadText = {
+	'en': 'Reload',
+	'zh-cn': '重新加载',
+	'zh-hant-cn': '重新加載',
+}
+
+const emptyViewErrorText = {
+	'en': 'Sorry,load failed',
+	'zh-cn': '很抱歉,加载失败',
+	'zh-hant-cn': '很抱歉,加載失敗',
+}
+
+const refresherUpdateTimeText = {
+	'en': 'Last update: ',
+	'zh-cn': '最后更新:',
+	'zh-hant-cn': '最後更新:',
+}
+
+const refresherUpdateTimeNoneText = {
+	'en': 'None',
+	'zh-cn': '无',
+	'zh-hant-cn': '無',
+}
+
+const refresherUpdateTimeTodayText = {
+	'en': 'Today',
+	'zh-cn': '今天',
+	'zh-hant-cn': '今天',
+}
+
+const refresherUpdateTimeYesterdayText = {
+	'en': 'Yesterday',
+	'zh-cn': '昨天',
+	'zh-hant-cn': '昨天',
+}
+
+// 插件内部使用,请勿直接调用
+function getPrivateLanguage(myLanguage, followSystemLanguage = true) {
+	let systemLanguage = '';
+	if (followSystemLanguage) {
+		systemLanguage = uni.getSystemInfoSync().language;
+	}
+	let language = myLanguage || uni.getStorageSync(i18nUpdateKey) || systemLanguage;
+	language = language.toLowerCase();
+	var reg = new RegExp('_', '');
+	language = language.replace(reg, '-');
+	if (language.indexOf('zh') !== -1) {
+		if (language === 'zh' || language === 'zh-cn' || language.indexOf('zh-hans') !== -1) {
+			return 'zh-cn';
+		}
+		return 'zh-hant-cn';
+	}
+	if (language.indexOf('en') !== -1) {
+		return 'en';
+	}
+	return 'zh-cn';
+}
+
+// 获取当前语言,格式为:zh-cn、zh-hant-cn、en。followSystemLanguage:获取的结果是否是在不跟随系统语言下获取到的
+function getLanguage(followSystemLanguage = true) {
+	return getPrivateLanguage(false, followSystemLanguage);
+}
+
+// 获取当前语言,格式为:简体中文、繁體中文、English。followSystemLanguage:获取的结果是否是在不跟随系统语言下获取到的
+function getLanguageName(followSystemLanguage = true) {
+	const language = getLanguage(followSystemLanguage);
+	const languageNameMap = {
+		'zh-cn': '简体中文',
+		'zh-hant-cn': '繁體中文',
+		'en': 'English'
+	};
+	return languageNameMap[language];
+}
+
+function setLanguage(myLanguage) {
+	uni.setStorageSync(i18nUpdateKey, myLanguage);
+	uni.$emit(i18nUpdateKey, myLanguage);
+}
+
+module.exports = {
+	refresherDefaultText,
+	refresherPullingText,
+	refresherRefreshingText,
+	loadingMoreDefaultText,
+	loadingMoreLoadingText,
+	loadingMoreNoMoreText,
+	loadingMoreFailText,
+	emptyViewText,
+	emptyViewReloadText,
+	emptyViewErrorText,
+	getPrivateLanguage,
+	getLanguage,
+	getLanguageName,
+	setLanguage,
+	refresherUpdateTimeText,
+	refresherUpdateTimeNoneText,
+	refresherUpdateTimeTodayText,
+	refresherUpdateTimeYesterdayText
+}

+ 2617 - 0
uni_modules/z-paging/components/z-paging/js/z-paging-main.js

@@ -0,0 +1,2617 @@
+// z-paging
+// github地址:https://github.com/SmileZXLee/uni-z-paging
+// dcloud地址:https://ext.dcloud.net.cn/plugin?id=3935
+// 反馈QQ群:790460711
+
+import zStatic from './z-paging-static'
+import zConfig from './z-paging-config'
+import zUtils from './z-paging-utils'
+import zI18n from './z-paging-i18n'
+import zPagingRefresh from '../components/z-paging-refresh'
+import zPagingLoadMore from '../components/z-paging-load-more'
+import zPagingEmptyView from '../../z-paging-empty-view/z-paging-empty-view'
+
+const currentVersion = 'V1.9.3';
+const systemInfo = uni.getSystemInfoSync();
+const commonDelayTime = 100;
+const i18nUpdateKey = 'z-paging-i18n-update';
+const errorUpdateKey = 'z-paging-error-emit';
+let config = null;
+// #ifdef APP-NVUE
+const weexDom = weex.requireModule('dom');
+const weexAnimation = weex.requireModule('animation');
+// #endif
+try {
+	const contextKeys = require.context('@/uni_modules/z-paging', false, /\z-paging-config$/).keys();
+	if (contextKeys.length) {
+		const suffix = '.js';
+		config = require('@/uni_modules/z-paging/z-paging-config' + suffix);
+	}
+} catch {}
+
+//获取默认配置信息
+function _getConfig(key, defaultValue) {
+	if (!config) {
+		const temConfig = zConfig.getConfig();
+		if (zConfig && temConfig) {
+			config = temConfig;
+		}
+	}
+	if (!config) {
+		return defaultValue;
+	}
+	let value = config[toKebab(key)];
+	if (value === undefined) {
+		value = config[key];
+	}
+	if (value !== undefined) {
+		return value;
+	}
+	return defaultValue;
+}
+//驼峰转短横线
+function toKebab(value) {
+	return value.replace(/([A-Z])/g, "-$1").toLowerCase();
+}
+
+/**
+ * z-paging 分页组件
+ * @description 【uni-app自动分页器】超简单,低耦合!仅需两步轻松完成完整分页逻辑(下拉刷新、上拉加载更多),分页全自动处理。支持自定义加载更多的文字或整个view,自定义下拉刷新样式,自动管理空数据view等。
+ * @tutorial https://github.com/SmileZXLee/uni-z-paging
+ * @property {Number|String} default-page-no 自定义pageNo,默认为1
+ * @property {Number|String} default-page-size 自定义pageSize,默认为10
+ * @property {Number|Object} data-key 为保证数据一致,设置当前tab切换时的标识key,并在complete中传递相同key,若二者不一致,则complete将不会生效
+ * @property {String} language i18n国际化设置语言,支持简体中文(zh-cn)、繁体中文(zh-hant-cn)和英文(en)
+ * @property {Boolean} follow-system-language i18n国际化默认是否跟随系统语言,默认为是
+ * @property {Object} paging-style 设置z-paging的style,部分平台可能无法直接修改组件的style,可使用此属性代替
+ * @property {Object} paging-content-style 设置z-paging的容器(插槽的父view)的style
+ * @property {Boolean} auto-height z-paging是否自动高度,若自动高度则会自动铺满屏幕,默认为否
+ * @property {Number|String} auto-height-addition z-paging是否自动高度时,附加的高度,注意添加单位px或rpx,默认为px,若需要减少高度,请传负数
+ * @property {String} default-theme-style loading(下拉刷新、上拉加载更多)的主题样式,支持black,white,默认black
+ * @property {String} refresher-theme-style 下拉刷新的主题样式,支持black,white,默认black
+ * @property {String} loading-more-theme-style 底部加载更多的主题样式,支持black,white,默认black
+ * @property {Boolean} refresher-only 是否只使用下拉刷新,设置为true后将关闭mounted自动请求数据、关闭滚动到底部加载更多,强制隐藏空数据图。默认为否
+ * @property {Boolean} use-page-scroll 使用页面滚动,默认为否,当设置为是时则使用页面的滚动而非此组件内部的scroll-view的滚动,使用页面滚动时z-paging无需设置确定的高度且对于长列表展示性能更高,但配置会略微繁琐
+ * @property {Boolean} fixed z-paging是否使用fixed布局,若使用fixed布局,则z-paging的父view无需固定高度,z-paging高度默认为100%,默认为否(当使用内置scroll-view滚动时有效)
+ * @property {Boolean} mounted-auto-call-reload z-paging mounted后自动调用reload方法(mounted后自动调用接口),默认为是
+ * @property {Boolean} auto-scroll-to-top-when-reload reload时自动滚动到顶部,默认为是
+ * @property {Boolean} auto-clean-list-when-reload reload时立即自动清空原list,默认为是,若立即自动清空,则在reload之后、请求回调之前页面是空白的
+ * @property {Boolean} show-refresher-when-reload 调用reload方法时是否自动显示下拉刷新view,默认为否
+ * @property {Boolean} refresher-update-time-key 如果需要区别不同页面的最后更新时间,请为不同页面的z-paging的`refresher-update-time-key`设置不同的字符串
+ * @property {Boolean} use-custom-refresher 是否使用自定义的下拉刷新,默认为是,即使用z-paging的下拉刷新。设置为false即代表使用uni scroll-view自带的下拉刷新,h5、App、微信小程序以外的平台不支持uni scroll-view自带的下拉刷新
+ * @property {Number|String} refresher-fps 自定义下拉刷新下拉帧率,默认为40,过高可能会出现抖动问题(use-custom-refresher为true时生效)
+ * @property {Number|String} refresher-max-angle 自定义下拉刷新允许触发的最大下拉角度,默认为40度,当下拉角度小于设定值时,自定义下拉刷新动画不会被触发
+ * @property {Boolean} refresher-angle-enable-change-continued 自定义下拉刷新的角度由未达到最大角度变到达到最大角度时,是否继续下拉刷新手势,默认为否
+ * @property {String|Object} refresher-default-text 自定义下拉刷新默认状态下的文字(use-custom-refresher为true时生效)
+ * @property {String|Object} refresher-pulling-text 自定义下拉刷新松手立即刷新状态下的文字(use-custom-refresher为true时生效)
+ * @property {String|Object} refresher-refreshing-text 自定义下拉刷新刷新中状态下的文字(use-custom-refresher为true时生效)
+ * @property {Boolean} refresher-end-bounce-enabled 是否开启自定义下拉刷新刷新结束回弹效果,默认为是(use-custom-refresher为true时生效)
+ * @property {Object} loading-more-custom-style 自定义底部加载更多样式
+ * @property {Object} loading-more-loading-icon-custom-style 自定义底部加载更多加载中动画样式
+ * @property {String} loading-more-loading-icon-type 自定义底部加载更多加载中动画图标类型,可选circle或flower,默认为circle
+ * @property {String} loading-more-loading-icon-custom-image 自定义底部加载更多加载中动画图标图片
+ * @property {Boolean} loading-more-enabled 是否启用加载更多数据(含滑动到底部加载更多数据和点击加载更多数据),默认为是
+ * @property {Boolean} to-bottom-loading-more-enabled 是否启用滑动到底部加载更多数据
+ * @property {String|Object} loading-more-default-text 滑动到底部"默认"文字,默认为【点击加载更多】
+ * @property {String|Object} loading-more-loading-text 滑动到底部"加载中"文字,默认为【正在加载...】
+ * @property {String|Object} loading-more-no-more-text 滑动到底部"没有更多"文字,默认为【没有更多了】
+ * @property {String|Object} loading-more-fail-text 滑动到底部"加载失败"文字,默认为【加载失败,点击重新加载】
+ * @property {Boolean} hide-loading-more-when-no-more-and-inside-of-paging 当没有更多数据且分页内容未超出z-paging时是否隐藏没有更多数据的view,默认为是
+ * @property {Boolean} show-loading-more-no-more-view 是否显示没有更多数据的view,默认为是
+ * @property {Boolean} show-default-loading-more-text 是否显示默认的加载更多text,默认为是
+ * @property {Boolean} show-loading-more-no-more-line 是否显示没有更多数据的分割线,默认为是
+ * @property {Object} loading-more-no-more-line-custom-style 自定义底部没有更多数据的分割线样式
+ * @property {Boolean} hide-empty-view 是否强制隐藏空数据图,默认为否
+ * @property {String|Object} empty-view-text 空数据图描述文字,默认为“没有数据哦~”
+ * @property {String} empty-view-img 空数据图图片,默认使用z-paging内置的图片
+ * @property {Boolean} auto-hide-empty-view-when-loading 加载中时是否自动隐藏空数据图,默认为是
+ * @property {Boolean} auto-hide-loading-after-first-loaded 第一次加载后自动隐藏loading slot,默认为是
+ * @property {Boolean} auto-show-back-to-top 自动显示点击返回顶部按钮,默认为否
+ * @property {Number|String} back-to-top-threshold 点击返回顶部按钮显示/隐藏的阈值(滚动距离),单位为px,默认为400rpx
+ * @property {String} back-to-top-img 点击返回顶部按钮的自定义图片地址,默认使用z-paging内置的图片
+ * @property {Boolean} back-to-top-with-animate 点击返回顶部按钮返回到顶部时是否展示过渡动画,默认为是
+ * @property {Number|String} back-to-top-bottom 点击返回顶部按钮与底部的距离,注意添加单位px或rpx,默认为160rpx
+ * @property {Object} back-to-top-style 点击返回顶部按钮的自定义样式
+ * @property {Boolean} show-scrollbar 在设置滚动条位置时使用动画过渡,默认为否
+ * @property {Boolean} scroll-to-top-bounce-enabled iOS设备上滚动到顶部时是否允许回弹效果,默认为否。关闭回弹效果后可使滚动到顶部与下拉刷新更连贯,但是有吸顶view时滚动到顶部时可能出现抖动。
+ * @property {Boolean} scroll-with-animation 控制是否出现滚动条,默认为否
+ * @property {String} scroll-into-view 值应为某子元素id(id不能以数字开头)。设置哪个方向可滚动,则在哪个方向滚动到该元素
+ * @property {Number|String} lower-threshold 距底部/右边多远时(单位px),触发 scrolltolower 事件,默认为100rpx
+ * @property {Boolean} enable-back-to-top iOS点击顶部状态栏、安卓双击标题栏时,滚动条返回顶部,只支持竖向,默认为是
+ * @property {Boolean} refresher-enabled 是否开启自定义下拉刷新,默认为是
+ * @property {Number|String} refresher-threshold 设置自定义下拉刷新阈值,默认为80rpx
+ * @property {String} refresher-default-style 设置自定义下拉刷新默认样式,支持设置 black,white,none,none 表示不使用默认样式,默认为black
+ * @property {String} refresher-background 设置自定义下拉刷新区域背景颜色
+ * @property {Boolean} show-refresher-update-time 是否显示上次下拉刷新更新时间,默认为否
+ * @property {String} refresher-update-time-key 上次下拉刷新更新时间的key,用于区别不同的上次更新时间
+ * @property {Number|String} local-paging-loading-time 本地分页时上拉加载更多延迟时间,单位为毫秒,默认200毫秒
+ * @property {Boolean} use-chat-record-mode 使用聊天记录模式,默认为否
+ * @property {String} nvue-list-is nvue中修改列表类型,可选值有list、waterfall和scroller,默认为list
+ * @property {Object} nvue-waterfall-config nvue waterfall配置,仅在nvue中且nvueListIs=waterfall时有效,配置参数详情参见:https://uniapp.dcloud.io/component/waterfall
+ * @event {Function} addData 请求结束(成功或者失败)调用此方法,将请求的结果传递给z-paging处理,第一个参数为请求结果数组,第二个参数为是否成功(默认为是)
+ * @event {Function} setLocalPaging 设置本地分页,请求结束(成功或者失败)调用此方法,将请求的结果传递给z-paging作分页处理(若调用了此方法,则上拉加载更多时内部会自动分页,不会触发@query所绑定的事件)
+ * @event {Function} reload 重新加载分页数据,pageNo恢复为默认值,相当于下拉刷新的效果(animate为true时会展示下拉刷新动画,默认为false)
+ * @event {Function} endRefresh 手动停止下拉刷新加载
+ * @event {Function} loadingStatusChange 分页加载状态改变(0-默认状态 1.加载中 2.没有更多数据 3.加载失败)
+ * @event {Function} refresherStatusChange 自定义下拉刷新状态改变(use-custom-refresher为true时生效)(0-默认状态 1.松手立即刷新 2.刷新中)
+ * @event {Function} refresherTouchstart 自定义下拉刷新下拉开始(use-custom-refresher为true时生效)【注:当需要更细致定制自定义下拉刷新时使用,如果只需监听下拉刷新各个状态改变,使用`refresherStatusChange`即可】
+ * @event {Function} refresherTouchmove 自定义下拉刷新下拉中(use-custom-refresher为true时生效)【注:当需要更细致定制自定义下拉刷新时使用,如果只需监听下拉刷新各个状态改变,使用`refresherStatusChange`即可】
+ * @event {Function} refresherTouchend 自定义下拉刷新下拉结束(use-custom-refresher为true时生效)【注:当需要更细致定制自定义下拉刷新时使用,如果只需监听下拉刷新各个状态改变,使用`refresherStatusChange`即可】
+ * @event {Function} onRefresh 自定义下拉刷新被触发
+ * @event {Function} onRestore 自定义下拉刷新被复位
+ * @event {Function} scroll 滚动时触发,event.detail = {scrollLeft, scrollTop, scrollHeight, scrollWidth, deltaX, deltaY}
+ * @example <z-paging ref="paging" v-model="dataList" @query="queryList"></z-paging>
+ */
+export default {
+	name: "z-paging",
+	components: {
+		zPagingRefresh,
+		zPagingLoadMore,
+		zPagingEmptyView
+	},
+	data() {
+		return {
+			base64Arrow: zStatic.base64Arrow,
+			base64Flower: zStatic.base64Flower,
+			base64BackToTop: zStatic.base64BackToTop,
+			systemInfo: null,
+			currentData: [],
+			totalData: [],
+			pageNo: 1,
+			showLoadingMore: false,
+			refresherTriggered: false,
+			loading: false,
+			firstPageLoaded: false,
+			pagingLoaded: false,
+			loaded: false,
+			isUserReload: true,
+			scrollEnable: true,
+			scrollTop: 0,
+			oldScrollTop: 0,
+			refresherTouchstartY: 0,
+			lastRefresherTouchmove: null,
+			refresherReachMaxAngle: true,
+			refresherTransform: 'translateY(0px)',
+			refresherTransition: '0s',
+			finalRefresherDefaultStyle: 'black',
+			//当前加载类型 0-下拉刷新 1-上拉加载更多
+			loadingType: 0,
+			//底部加载更多状态 0-默认状态 1.加载中 2.没有更多数据 3.加载失败
+			loadingStatus: 0,
+			//下拉刷新状态 0-默认状态 1.松手立即刷新 2.刷新中
+			refresherStatus: 0,
+			scrollViewStyle: {},
+			pullDownTimeStamp: 0,
+			pageScrollTop: -1,
+			isTouchmoving: false,
+			isLocalPaging: false,
+			totalLocalPagingList: [],
+			realTotalData: [],
+			isAddedData: false,
+			isTotalChangeFromAddData: false,
+			isTouchEnded: false,
+			isUserPullDown: false,
+			privateRefresherEnabled: -1,
+			privateScrollWithAnimation: -1,
+			myParentQuery: -1,
+			chatRecordLoadingMoreText: '',
+			moveDistance: 0,
+			loadingMoreDefaultSlot: null,
+			backToTopClass: 'zp-back-to-top zp-back-to-top-hide',
+			showBackToTopClass: false,
+			tempLanguageUpdateKey: 0,
+			isLoadFailed: false,
+			isIos: systemInfo.platform === 'ios',
+			privateShowRefresherWhenReload: false,
+			nRefresherLoading: true,
+			nListIsDragging: false,
+			nShowBottom: true,
+			nFixFreezing: false,
+			nShowRefresherReveal: false,
+			nShowRefresherRevealHeight: 0,
+			nIsFirstPageAndNoMore: false,
+			nFirstPageAndNoMoreChecked: false,
+			nLoadingMoreFixedHeight: false,
+			wxsPropType: '',
+			refresherRevealStackCount: 0,
+			renderPropScrollTop: 0,
+			renderUsePageScroll: false,
+			wxsIsScrollTopInTopRange: true,
+			wxsScrollTop: 0,
+			wxsPageScrollTop: 0,
+			wxsOnPullingDown: false,
+			disabledBounce: false,
+			cacheScrollNodeHeight: -1,
+			customNoMore: -1
+		};
+	},
+	props: {
+		//自定义pageNo,默认为1
+		defaultPageNo: {
+			type: [Number, String],
+			default: _getConfig('defaultPageNo', 1),
+			observer: function(newVal, oldVal) {
+				this.pageNo = newVal;
+			},
+		},
+		//自定义pageSize,默认为10
+		defaultPageSize: {
+			type: [Number, String],
+			default: _getConfig('defaultPageSize', 10),
+		},
+		//为保证数据一致,设置当前tab切换时的标识key,并在complete中传递相同key,若二者不一致,则complete将不会生效
+		dataKey: {
+			type: [Number, Object],
+			default: function() {
+				return _getConfig('dataKey', null);
+			},
+		},
+		//自动注入的list名,可自动修改父view(包含ref="paging")中对应name的list值
+		autowireListName: {
+			type: String,
+			default: function() {
+				return _getConfig('autowireListName', '');
+			},
+		},
+		//自动注入的query名,可自动调用父view(包含ref="paging")中的query方法
+		autowireQueryName: {
+			type: String,
+			default: function() {
+				return _getConfig('autowireQueryName', '');
+			},
+		},
+		//i18n国际化设置语言,支持简体中文(zh-cn)、繁体中文(zh-hant-cn)和英文(en)
+		language: {
+			type: String,
+			default: _getConfig('language', '')
+		},
+		//i18n国际化默认是否跟随系统语言,默认为是
+		followSystemLanguage: {
+			type: Boolean,
+			default: _getConfig('followSystemLanguage', true)
+		},
+		//设置z-paging的style,部分平台可能无法直接修改组件的style,可使用此属性代替
+		pagingStyle: {
+			type: Object,
+			default: function() {
+				return _getConfig('pagingStyle', {});
+			},
+		},
+		//设置z-paging的容器(插槽的父view)的style
+		pagingContentStyle: {
+			type: Object,
+			default: function() {
+				return _getConfig('pagingContentStyle', {});
+			},
+		},
+		//z-paging是否自动高度,若自动高度则会自动铺满屏幕
+		autoHeight: {
+			type: Boolean,
+			default: _getConfig('autoHeight', false)
+		},
+		//z-paging是否自动高度时,附加的高度,注意添加单位px或rpx,若需要减少高度,则传负数
+		autoHeightAddition: {
+			type: [Number, String],
+			default: _getConfig('autoHeightAddition', '0px')
+		},
+		//loading(下拉刷新、上拉加载更多)的主题样式,支持black,white,默认black
+		defaultThemeStyle: {
+			type: String,
+			default: function() {
+				return _getConfig('defaultThemeStyle', 'black');
+			}
+		},
+		//下拉刷新的主题样式,支持black,white,默认black
+		refresherThemeStyle: {
+			type: String,
+			default: function() {
+				return _getConfig('refresherThemeStyle', '');
+			}
+		},
+		//底部加载更多的主题样式,支持black,white,默认black
+		loadingMoreThemeStyle: {
+			type: String,
+			default: function() {
+				return _getConfig('loadingMoreThemeStyle', '');
+			}
+		},
+		//是否只使用下拉刷新,设置为true后将关闭mounted自动请求数据、关闭滚动到底部加载更多,强制隐藏空数据图。默认为否
+		refresherOnly: {
+			type: Boolean,
+			default: _getConfig('refresherOnly', false)
+		},
+		//使用页面滚动,默认为否,当设置为是时则使用页面的滚动而非此组件内部的scroll-view的滚动,使用页面滚动时z-paging无需设置确定的高度且对于长列表展示性能更高,但配置会略微繁琐
+		usePageScroll: {
+			type: Boolean,
+			default: _getConfig('usePageScroll', false)
+		},
+		//z-paging是否使用fixed布局,若使用fixed布局,则z-paging的父view无需固定高度,z-paging高度默认为100%,默认为否(当使用内置scroll-view滚动时有效)
+		fixed: {
+			type: Boolean,
+			default: _getConfig('fixed', true)
+		},
+		//是否开启底部安全区域适配
+		safeAreaInsetBottom: {
+			type: Boolean,
+			default: _getConfig('safeAreaInsetBottom', false)
+		},
+		//是否可以滚动,使用内置scroll-view和nvue时有效,默认为是
+		scrollable: {
+			type: Boolean,
+			default: _getConfig('scrollable', true)
+		},
+		//z-paging mounted后自动调用reload方法(mounted后自动调用接口),默认为是。请使用简便写法:auto
+		mountedAutoCallReload: {
+			type: Boolean,
+			default: _getConfig('mountedAutoCallReload', true)
+		},
+		//z-paging mounted后自动调用reload方法(mounted后自动调用接口),默认为是
+		auto: {
+			type: Boolean,
+			default: _getConfig('auto', true)
+		},
+		//reload时自动滚动到顶部,默认为是
+		autoScrollToTopWhenReload: {
+			type: Boolean,
+			default: _getConfig('autoScrollToTopWhenReload', true)
+		},
+		//reload时立即自动清空原list,默认为是,若立即自动清空,则在reload之后、请求回调之前页面是空白的
+		autoCleanListWhenReload: {
+			type: Boolean,
+			default: _getConfig('autoCleanListWhenReload', true)
+		},
+		//调用reload方法时自动显示下拉刷新view,默认为否
+		showRefresherWhenReload: {
+			type: Boolean,
+			default: _getConfig('showRefresherWhenReload', false)
+		},
+		//调用reload方法时自动显示加载更多view,且为加载中状态,默认为否
+		showLoadingMoreWhenReload: {
+			type: Boolean,
+			default: _getConfig('showLoadingMoreWhenReload', false)
+		},
+		//是否使用自定义的下拉刷新,默认为是,即使用z-paging的下拉刷新。设置为false即代表使用uni scroll-view自带的下拉刷新,h5、App、微信小程序以外的平台不支持uni scroll-view自带的下拉刷新
+		useCustomRefresher: {
+			type: Boolean,
+			default: _getConfig('useCustomRefresher', true)
+		},
+		//自定义下拉刷新下拉帧率,默认为40,过高可能会出现抖动问题(use-custom-refresher为true时生效)
+		refresherFps: {
+			type: [Number, String],
+			default: _getConfig('refresherFps', 40)
+		},
+		//自定义下拉刷新允许触发的最大下拉角度,默认为40度,当下拉角度小于设定值时,自定义下拉刷新动画不会被触发
+		refresherMaxAngle: {
+			type: [Number, String],
+			default: _getConfig('refresherMaxAngle', 40)
+		},
+		//自定义下拉刷新的角度由未达到最大角度变到达到最大角度时,是否继续下拉刷新手势,默认为否
+		refresherAngleEnableChangeContinued: {
+			type: Boolean,
+			default: _getConfig('refresherAngleEnableChangeContinued', false)
+		},
+		//自定义下拉刷新默认状态下的文字(use-custom-refresher为true时生效)
+		refresherDefaultText: {
+			type: [String, Object],
+			default: _getConfig('refresherDefaultText', null)
+		},
+		//自定义下拉刷新松手立即刷新状态下的文字(use-custom-refresher为true时生效)
+		refresherPullingText: {
+			type: [String, Object],
+			default: _getConfig('refresherPullingText', null)
+		},
+		//自定义下拉刷新刷新中状态下的文字(use-custom-refresher为true时生效)
+		refresherRefreshingText: {
+			type: [String, Object],
+			default: _getConfig('refresherRefreshingText', null)
+		},
+		//是否开启自定义下拉刷新刷新结束回弹效果,默认为是(use-custom-refresher为true时生效)
+		refresherEndBounceEnabled: {
+			type: Boolean,
+			default: _getConfig('refresherEndBounceEnabled', true)
+		},
+		//自定义底部加载更多样式
+		loadingMoreCustomStyle: {
+			type: Object,
+			default: function() {
+				return _getConfig('loadingMoreCustomStyle', {});
+			}
+		},
+		//自定义底部加载更多加载中动画样式
+		loadingMoreLoadingIconCustomStyle: {
+			type: Object,
+			default: function() {
+				return _getConfig('loadingMoreLoadingIconCustomStyle', {});
+			}
+		},
+		//自定义底部加载更多加载中动画图标类型,可选flower或circle,默认为flower
+		loadingMoreLoadingIconType: {
+			type: String,
+			default: _getConfig('loadingMoreLoadingIconType', 'flower')
+		},
+		//自定义底部加载更多加载中动画图标图片
+		loadingMoreLoadingIconCustomImage: {
+			type: String,
+			default: _getConfig('loadingMoreLoadingIconCustomImage', '')
+		},
+		//是否启用加载更多数据(含滑动到底部加载更多数据和点击加载更多数据),默认为是
+		loadingMoreEnabled: {
+			type: Boolean,
+			default: _getConfig('loadingMoreEnabled', true)
+		},
+		//是否启用滑动到底部加载更多数据,默认为是
+		toBottomLoadingMoreEnabled: {
+			type: Boolean,
+			default: _getConfig('toBottomLoadingMoreEnabled', true)
+		},
+		//滑动到底部"默认"文字,默认为【点击加载更多】
+		loadingMoreDefaultText: {
+			type: [String, Object],
+			default: _getConfig('loadingMoreDefaultText', null)
+		},
+		//滑动到底部"加载中"文字,默认为【正在加载...】
+		loadingMoreLoadingText: {
+			type: [String, Object],
+			default: _getConfig('loadingMoreLoadingText', null)
+		},
+		//滑动到底部"没有更多"文字,默认为【没有更多了】
+		loadingMoreNoMoreText: {
+			type: [String, Object],
+			default: _getConfig('loadingMoreNoMoreText', null)
+		},
+		//滑动到底部"加载失败"文字,默认为【加载失败,点击重新加载】
+		loadingMoreFailText: {
+			type: [String, Object],
+			default: _getConfig('loadingMoreFailText', null)
+		},
+		//当没有更多数据且分页内容未超出z-paging时是否隐藏没有更多数据的view,默认为否
+		hideLoadingMoreWhenNoMoreAndInsideOfPaging: {
+			type: Boolean,
+			default: _getConfig('hideLoadingMoreWhenNoMoreAndInsideOfPaging', false)
+		},
+		//当没有更多数据且分页数组长度少于这个值时,隐藏没有更多数据的view,默认为0,代表不限制。
+		hideLoadingMoreWhenNoMoreByLimit: {
+			type: Number,
+			default: _getConfig('hideLoadingMoreWhenNoMoreByLimit', 0)
+		},
+		//是否显示默认的加载更多text,默认为是
+		showDefaultLoadingMoreText: {
+			type: Boolean,
+			default: _getConfig('showDefaultLoadingMoreText', true)
+		},
+		//是否显示没有更多数据的view
+		showLoadingMoreNoMoreView: {
+			type: Boolean,
+			default: _getConfig('showLoadingMoreNoMoreView', true)
+		},
+		//是否显示没有更多数据的分割线,默认为是
+		showLoadingMoreNoMoreLine: {
+			type: Boolean,
+			default: _getConfig('showLoadingMoreNoMoreLine', true)
+		},
+		//自定义底部没有更多数据的分割线样式
+		loadingMoreNoMoreLineCustomStyle: {
+			type: Object,
+			default: function() {
+				return _getConfig('loadingMoreNoMoreLineCustomStyle', {});
+			},
+		},
+		//是否强制隐藏空数据图,默认为否
+		hideEmptyView: {
+			type: Boolean,
+			default: _getConfig('hideEmptyView', false)
+		},
+		//空数据图描述文字,默认为“没有数据哦~”
+		emptyViewText: {
+			type: [String, Object],
+			default: _getConfig('emptyViewText', null)
+		},
+		//是否显示空数据图重新加载按钮(无数据时),默认为否
+		showEmptyViewReload: {
+			type: Boolean,
+			default: _getConfig('showEmptyViewReload', false)
+		},
+		//加载失败时是否显示空数据图重新加载按钮,默认为是
+		showEmptyViewReloadWhenError: {
+			type: Boolean,
+			default: _getConfig('showEmptyViewReloadWhenError', true)
+		},
+		//空数据图点击重新加载文字,默认为“重新加载”
+		emptyViewReloadText: {
+			type: [String, Object],
+			default: _getConfig('emptyViewReloadText', null)
+		},
+		//空数据图图片,默认使用z-paging内置的图片
+		emptyViewImg: {
+			type: String,
+			default: _getConfig('emptyViewImg', '')
+		},
+		//空数据图“加载失败”描述文字,默认为“很抱歉,加载失败”
+		emptyViewErrorText: {
+			type: [String, Object],
+			default: _getConfig('emptyViewErrorText', null)
+		},
+		//空数据图“加载失败”图片,默认使用z-paging内置的图片
+		emptyViewErrorImg: {
+			type: String,
+			default: _getConfig('emptyViewErrorImg', '')
+		},
+		//空数据图样式
+		emptyViewStyle: {
+			type: Object,
+			default: function() {
+				return _getConfig('emptyViewStyle', {});
+			}
+		},
+		//空数据图img样式
+		emptyViewImgStyle: {
+			type: Object,
+			default: function() {
+				return _getConfig('emptyViewImgStyle', {});
+			}
+		},
+		//空数据图描述文字样式
+		emptyViewTitleStyle: {
+			type: Object,
+			default: function() {
+				return _getConfig('emptyViewTitleStyle', {});
+			}
+		},
+		//空数据图重新加载按钮样式
+		emptyViewReloadStyle: {
+			type: Object,
+			default: function() {
+				return _getConfig('emptyViewReloadStyle', {});
+			}
+		},
+		//加载中时是否自动隐藏空数据图,默认为是
+		autoHideEmptyViewWhenLoading: {
+			type: Boolean,
+			default: _getConfig('autoHideEmptyViewWhenLoading', true)
+		},
+		//第一次加载后自动隐藏loading slot,默认为是
+		autoHideLoadingAfterFirstLoaded: {
+			type: Boolean,
+			default: _getConfig('autoHideLoadingAfterFirstLoaded', true)
+		},
+		//自动显示点击返回顶部按钮,默认为否
+		autoShowBackToTop: {
+			type: Boolean,
+			default: _getConfig('autoShowBackToTop', false)
+		},
+		//点击返回顶部按钮显示/隐藏的阈值(滚动距离),单位为px,默认为400rpx
+		backToTopThreshold: {
+			type: [Number, String],
+			default: _getConfig('backToTopThreshold', '400rpx')
+		},
+		//点击返回顶部按钮的自定义图片地址,默认使用z-paging内置的图片
+		backToTopImg: {
+			type: String,
+			default: _getConfig('backToTopImg', '')
+		},
+		//点击返回顶部按钮返回到顶部时是否展示过渡动画,默认为是
+		backToTopWithAnimate: {
+			type: Boolean,
+			default: _getConfig('backToTopWithAnimate', true)
+		},
+		//点击返回顶部按钮与底部的距离,注意添加单位px或rpx,默认为160rpx
+		backToTopBottom: {
+			type: [Number, String],
+			default: _getConfig('backToTopBottom', '160rpx')
+		},
+		//点击返回顶部按钮的自定义样式
+		backToTopStyle: {
+			type: Object,
+			default: function() {
+				return _getConfig('backToTopStyle', {});
+			},
+		},
+		//控制是否出现滚动条,默认为否
+		showScrollbar: {
+			type: Boolean,
+			default: _getConfig('showScrollbar', false)
+		},
+		//iOS设备上滚动到顶部时是否允许回弹效果,默认为否。关闭回弹效果后可使滚动到顶部与下拉刷新更连贯,但是有吸顶view时滚动到顶部时可能出现抖动。
+		scrollToTopBounceEnabled: {
+			type: Boolean,
+			default: _getConfig('scrollToTopBounceEnabled', false)
+		},
+		//iOS设备上滚动到底部时是否允许回弹效果,默认为是。
+		scrollToBottomBounceEnabled: {
+			type: Boolean,
+			default: _getConfig('scrollToBottomBounceEnabled', true)
+		},
+		//在设置滚动条位置时使用动画过渡,默认为否
+		scrollWithAnimation: {
+			type: Boolean,
+			default: _getConfig('scrollWithAnimation', false)
+		},
+		//值应为某子元素id(id不能以数字开头)。设置哪个方向可滚动,则在哪个方向滚动到该元素
+		scrollIntoView: {
+			type: String,
+			default: _getConfig('scrollIntoView', '')
+		},
+		//距底部/右边多远时(单位px),触发 scrolltolower 事件,默认为100rpx
+		lowerThreshold: {
+			type: [Number, String],
+			default: _getConfig('lowerThreshold', '100rpx')
+		},
+		//iOS点击顶部状态栏、安卓双击标题栏时,滚动条返回顶部,只支持竖向,默认为是
+		enableBackToTop: {
+			type: Boolean,
+			default: _getConfig('enableBackToTop', true)
+		},
+		//是否开启自定义下拉刷新,默认为是
+		refresherEnabled: {
+			type: Boolean,
+			default: _getConfig('refresherEnabled', true)
+		},
+		//设置自定义下拉刷新阈值,默认为80rpx
+		refresherThreshold: {
+			type: [Number, String],
+			default: _getConfig('refresherThreshold', '80rpx')
+		},
+		//设置系统下拉刷新默认样式,支持设置 black,white,none,none 表示不使用默认样式,默认为black
+		refresherDefaultStyle: {
+			type: String,
+			default: _getConfig('refresherDefaultStyle', 'black')
+		},
+		//设置自定义下拉刷新区域背景颜色
+		refresherBackground: {
+			type: String,
+			default: _getConfig('refresherBackground', '#ffffff00')
+		},
+		//设置固定的自定义下拉刷新区域背景颜色
+		refresherFixedBackground: {
+			type: String,
+			default: _getConfig('refresherFixedBackground', '#ffffff00')
+		},
+		//设置固定的自定义下拉刷新区域高度,默认为0
+		refresherFixedBacHeight: {
+			type: [Number, String],
+			default: _getConfig('refresherFixedBacHeight', 0)
+		},
+		//设置自定义下拉刷新下拉超出阈值后继续下拉位移衰减的比例,范围0-1,值越大代表衰减越多。默认为0.7(nvue无效)
+		refresherOutRate: {
+			type: Number,
+			default: _getConfig('refresherOutRate', 0.7)
+		},
+		//是否显示最后更新时间,默认为否
+		showRefresherUpdateTime: {
+			type: Boolean,
+			default: _getConfig('showRefresherUpdateTime', false)
+		},
+		//如果需要区别不同页面的最后更新时间,请为不同页面的z-paging的`refresher-update-time-key`设置不同的字符串
+		refresherUpdateTimeKey: {
+			type: String,
+			default: _getConfig('refresherUpdateTimeKey', 'default')
+		},
+		//本地分页时上拉加载更多延迟时间,单位为毫秒,默认200毫秒
+		localPagingLoadingTime: {
+			type: [Number, String],
+			default: _getConfig('localPagingLoadingTime', 200)
+		},
+		//使用聊天记录模式,默认为否
+		useChatRecordMode: {
+			type: Boolean,
+			default: _getConfig('useChatRecordMode', false)
+		},
+		//slot="top"的view的z-index,默认为99,仅使用页面滚动时有效
+		topZIndex: {
+			type: Number,
+			default: _getConfig('topZIndex', 99)
+		},
+		//z-paging内容容器父view的z-index,默认为1
+		superContentZIndex: {
+			type: Number,
+			default: _getConfig('superContentZIndex', 1)
+		},
+		//z-paging内容容器部分的z-index,默认为10
+		contentZIndex: {
+			type: Number,
+			default: _getConfig('contentZIndex', 10)
+		},
+		//空数据view的z-index,默认为9
+		emptyViewZIndex: {
+			type: Number,
+			default: _getConfig('emptyViewZIndex', 9)
+		},
+		//自动拼接complete中传过来的数组(使用聊天记录模式时无效)
+		concat: {
+			type: Boolean,
+			default: _getConfig('concat', true)
+		},
+		//nvue中修改列表类型,可选值有list、waterfall和scroller,默认为list
+		nvueListIs: {
+			type: String,
+			default: _getConfig('nvueListIs', 'list')
+		},
+		//nvue waterfall配置,仅在nvue中且nvueListIs=waterfall时有效,配置参数详情参见:https://uniapp.dcloud.io/component/waterfall
+		nvueWaterfallConfig: {
+			type: Object,
+			default: function() {
+				return _getConfig('nvueWaterfallConfig', {});
+			}
+		},
+		//nvue 控制是否回弹效果,iOS不支持动态修改
+		nvueBounce: {
+			type: Boolean,
+			default: function() {
+				return _getConfig('nvueBounce', true);
+			}
+		},
+		//是否将错误信息打印至控制台,默认为是
+		showConsoleError: {
+			type: Boolean,
+			default: function() {
+				return _getConfig('showConsoleError', true);
+			}
+		},
+		//父组件v-model所绑定的list的值
+		value: {
+			type: Array,
+			default: function() {
+				return [];
+			}
+		}
+	},
+	mounted() {
+		this.wxsPropType = (new Date()).getTime().toString();
+		this.renderJsIgnore;
+		if (!this.refresherOnly && (this.mountedAutoCallReload && this.auto)) {
+			this.$nextTick(() => {
+				this._preReload();
+			})
+		}
+		this.$nextTick(() => {
+			this.systemInfo = uni.getSystemInfoSync();
+			if (!this.usePageScroll && this.autoHeight) {
+				this._setAutoHeight();
+			}
+			this.loaded = true;
+		})
+		this.updatePageScrollTopHeight();
+		this.updatePageScrollBottomHeight();
+		uni.$on(i18nUpdateKey, () => {
+			this.tempLanguageUpdateKey = (new Date()).getTime();
+		})
+		uni.$on(errorUpdateKey, () => {
+			if (this.loading) {
+				this.complete(false);
+			}
+		})
+		// #ifdef APP-NVUE
+		if (!this.isIos && !this.useChatRecordMode) {
+			this.nLoadingMoreFixedHeight = true;
+		}
+		// #endif
+	},
+	destroyed() {
+		uni.$off(i18nUpdateKey);
+		uni.$off(errorUpdateKey);
+	},
+	watch: {
+		value(newVal, oldVal) {
+			let dataType = Object.prototype.toString.call(newVal);
+			if (dataType === '[object Undefined]') {
+				zUtils.consoleErr('v-model所绑定的值不存在!');
+				return;
+			}
+			if (dataType !== '[object Array]') {
+				zUtils.consoleErr('v-model所绑定的值必须为Array类型!');
+				return;
+			}
+			if (!zUtils.arrayIsEqual(newVal, this.totalData)) {
+				this.totalData = newVal;
+			}
+		},
+		totalData(newVal, oldVal) {
+			if ((!this.isUserReload || !this.autoCleanListWhenReload) && this.firstPageLoaded && !newVal.length &&
+				oldVal.length) {
+				return;
+			}
+			newVal = [...newVal];
+			if (this.loadingStatus === 2 && this.hideLoadingMoreWhenNoMoreByLimit > 0 &&
+				newVal.length) {
+				this.showLoadingMore = newVal.length > this.hideLoadingMoreWhenNoMoreByLimit;
+			} else if (this.loadingStatus === 2 && this.hideLoadingMoreWhenNoMoreAndInsideOfPaging &&
+				newVal.length) {
+				this.$nextTick(() => {
+					this._checkShowLoadingMoreWhenNoMoreAndInsideOfPaging(newVal);
+				})
+			} else {
+				this.showLoadingMore = newVal.length;
+			}
+			if (this.usePageScroll && this.isTotalChangeFromAddData) {
+				this.$nextTick(() => {
+					this._checkScrollViewShouldFullHeight();
+				})
+			}
+			if (!this.usePageScroll && (this.pageNo === this.defaultPageNo || this.defaultPageNo + 1)) {
+				setTimeout(() => {
+					this._checkScrollViewOutOfPage();
+				}, commonDelayTime)
+			}
+			this.realTotalData = newVal;
+			this.$emit('input', newVal);
+			this.$emit('update:list', newVal);
+			this.$emit('listChange', newVal);
+			this._callMyParentList(newVal);
+			this.firstPageLoaded = false;
+			this.isTotalChangeFromAddData = false;
+			this.$nextTick(() => {
+				this._getNodeClientRect('.zp-paging-container-content').then((res) => {
+					if (res) {
+						this.$emit('pagingContentHeightChanged', res[0].height);
+					}
+				});
+				// #ifdef APP-NVUE
+				if (this.useChatRecordMode && this.nIsFirstPageAndNoMore && this.pageNo === this
+					.defaultPageNo && !this.nFirstPageAndNoMoreChecked) {
+					this.nFirstPageAndNoMoreChecked = true;
+					this._scrollToBottom(false);
+				}
+				// #endif
+			})
+		},
+		currentData(newVal, oldVal) {
+			this._currentDataChange(newVal, oldVal);
+		},
+		loadingStatus(newVal, oldVal) {
+			this.$emit('loadingStatusChange', newVal);
+			// #ifdef APP-NVUE
+			if (this.useChatRecordMode) {
+				if (this.pageNo === this.defaultPageNo && newVal === 2) {
+					this.nIsFirstPageAndNoMore = true;
+					return;
+				}
+			}
+			this.nIsFirstPageAndNoMore = false;
+			//  #endif
+		},
+		oldScrollTop(newVal, oldVal) {
+			if (!this.usePageScroll) {
+				this.$emit('scrollTopChange', newVal);
+				this.$emit('update:scrollTop', newVal);
+				this._checkShouldShowBackToTop(newVal, oldVal);
+				if (this.isIos) {
+					if (newVal > 5) {
+						this.wxsScrollTop = 6;
+					} else {
+						this.wxsScrollTop = 0;
+					}
+				} else {
+					this.wxsScrollTop = newVal;
+				}
+			}
+		},
+		pageScrollTop(newVal, oldVal) {
+			if (this.usePageScroll) {
+				this.$emit('scrollTopChange', newVal);
+				this.$emit('update:scrollTop', newVal);
+				this._checkShouldShowBackToTop(newVal, oldVal);
+				if (this.isIos) {
+					if (newVal > 5) {
+						this.wxsPageScrollTop = 6;
+					} else {
+						this.wxsPageScrollTop = 0;
+					}
+				} else {
+					this.wxsPageScrollTop = newVal;
+				}
+			}
+		},
+		defaultThemeStyle: {
+			handler(newVal) {
+				if (newVal.length) {
+					this.finalRefresherDefaultStyle = newVal;
+				}
+			},
+			immediate: true
+		},
+		usePageScroll: {
+			handler(newVal) {
+				this.$nextTick(() => {
+					this.renderUsePageScroll = newVal;
+				})
+				if (this.loaded && this.autoHeight) {
+					this._setAutoHeight(!newVal);
+				}
+			},
+			immediate: true
+		},
+		autoHeight(newVal, oldVal) {
+			if (this.loaded && !this.usePageScroll) {
+				this._setAutoHeight(newVal);
+			}
+		},
+		autoHeightAddition(newVal, oldVal) {
+			if (this.loaded && !this.usePageScroll && this.autoHeight) {
+				this._setAutoHeight(newVal);
+			}
+		},
+		refresherDefaultStyle: {
+			handler(newVal) {
+				if (newVal.length) {
+					this.finalRefresherDefaultStyle = newVal;
+				}
+			},
+			immediate: true
+		},
+		refresherStatus(newVal, oldVal) {
+			if (newVal !== oldVal) {
+				this.$emit('refresherStatusChange', newVal);
+				this.$emit('update:refresherStatus', newVal);
+			}
+		},
+		useChatRecordMode(newVal, oldVal) {
+			if (newVal) {
+				this.nLoadingMoreFixedHeight = false;
+			}
+		},
+		finalScrollTop(newVal, oldVal) {
+			if (!this.useChatRecordMode) {
+				if (newVal < 6) {
+					this.renderPropScrollTop = 0;
+				} else {
+					this.renderPropScrollTop = 10;
+				}
+			}
+		},
+		nIsFirstPageAndNoMore: {
+			handler(newVal) {
+				const cellStyle = !this.useChatRecordMode || newVal ? {} : {
+					transform: 'rotate(180deg)'
+				};
+				this.$emit('update:cellStyle', cellStyle);
+			},
+			immediate: true
+		}
+	},
+	computed: {
+		pullDownDisTimeStamp() {
+			return 1000 / this.refresherFps;
+		},
+		finalRefresherEnabled() {
+			if (this.useChatRecordMode) {
+				return false;
+			}
+			if (this.privateRefresherEnabled === -1) {
+				return this.refresherEnabled;
+			}
+			return this.privateRefresherEnabled === 1;
+		},
+		finalScrollWithAnimation() {
+			if (this.privateScrollWithAnimation !== -1) {
+				const scrollWithAnimation = this.privateScrollWithAnimation === 1;
+				this.privateScrollWithAnimation = -1;
+				return scrollWithAnimation;
+			}
+			return this.scrollWithAnimation;
+		},
+		zPagingLoadMoreConfig() {
+			return {
+				loadingStatus: this.loadingStatus,
+				defaultThemeStyle: this.finalLoadingMoreThemeStyle,
+				loadingMoreCustomStyle: this.loadingMoreCustomStyle,
+				loadingMoreLoadingIconCustomStyle: this.loadingMoreLoadingIconCustomStyle,
+				loadingMoreLoadingIconType: this.loadingMoreLoadingIconType,
+				loadingMoreLoadingIconCustomImage: this.loadingMoreLoadingIconCustomImage,
+				showLoadingMoreNoMoreLine: this.showLoadingMoreNoMoreLine,
+				loadingMoreNoMoreLineCustomStyle: this.loadingMoreNoMoreLineCustomStyle,
+				loadingMoreDefaultText: this.finalLoadingMoreDefaultText,
+				loadingMoreLoadingText: this.finalLoadingMoreLoadingText,
+				loadingMoreNoMoreText: this.finalLoadingMoreNoMoreText,
+				loadingMoreFailText: this.finalLoadingMoreFailText
+			};
+		},
+		zScopedSlots() {
+			return this.$scopedSlots;
+		},
+		finalNvueListIs() {
+			if (this.usePageScroll) {
+				return 'view';
+			}
+			const nvueListIsLowerCase = this.nvueListIs.toLowerCase();
+			if (nvueListIsLowerCase === 'list' || nvueListIsLowerCase === 'waterfall' || nvueListIsLowerCase ===
+				'scroller') {
+				return nvueListIsLowerCase;
+			}
+			return 'list';
+		},
+		finalNvueSuperListIs() {
+			if (this.usePageScroll) {
+				return 'view';
+			}
+			return 'scroller';
+		},
+		finalPagingStyle() {
+			let pagingStyle = this.pagingStyle;
+			if (!this.systemInfo) {
+				return pagingStyle;
+			}
+			const windowTop = this.systemInfo.windowTop;
+			const windowBottom = this.systemInfo.windowBottom;
+			if (!this.usePageScroll && this.fixed) {
+				if (windowTop && windowTop !== undefined) {
+					pagingStyle.top = windowTop + 'px';
+				}
+				let bottom = 0;
+				if (windowBottom && windowBottom !== undefined) {
+					bottom = windowBottom;
+				}
+				if (this.safeAreaInsetBottom) {
+					bottom += this.safeAreaBottom;
+				}
+				pagingStyle.bottom = bottom + 'px';
+			}
+			return pagingStyle;
+		},
+		finalEnableBackToTop() {
+			if (this.usePageScroll) {
+				return false;
+			}
+			return this.enableBackToTop;
+		},
+		finalBackToTopThreshold() {
+			return this._convertTextToPx(this.backToTopThreshold);
+		},
+		finalLowerThreshold() {
+			return this._convertTextToPx(this.lowerThreshold);
+		},
+		finalRefresherThreshold() {
+			let refresherThreshold = this.refresherThreshold;
+			if (this.showRefresherUpdateTime) {
+				if (refresherThreshold === '80rpx') {
+					refresherThreshold = '120rpx';
+				}
+			}
+			return this._convertTextToPx(refresherThreshold);
+		},
+		finalRefresherFixedBacHeight() {
+			return this._convertTextToPx(this.refresherFixedBacHeight);
+		},
+		finalScrollTop() {
+			if (this.usePageScroll) {
+				return this.pageScrollTop;
+			}
+			return this.oldScrollTop;
+		},
+		finalBackToTopStyle() {
+			let tempBackToTopStyle = this.backToTopStyle;
+			if (!tempBackToTopStyle.bottom) {
+				tempBackToTopStyle.bottom = this.windowBottom + this._convertTextToPx(this.backToTopBottom) + 'px';
+			}
+			return tempBackToTopStyle;
+		},
+		finalTempLanguage() {
+			if (this.language.length) {
+				return this.language;
+			}
+			return this.tempLanguage;
+		},
+		finalLanguage() {
+			let language = this.finalTempLanguage.toLowerCase();
+			return zI18n.getPrivateLanguage(language, this.followSystemLanguage);
+		},
+		finalRefresherDefaultText() {
+			return this._getI18nText('refresherDefaultText', this.refresherDefaultText);
+		},
+		finalRefresherPullingText() {
+			return this._getI18nText('refresherPullingText', this.refresherPullingText);
+		},
+		finalRefresherRefreshingText() {
+			return this._getI18nText('refresherRefreshingText', this.refresherRefreshingText);
+		},
+		finalLoadingMoreDefaultText() {
+			return this._getI18nText('loadingMoreDefaultText', this.loadingMoreDefaultText);
+		},
+		finalLoadingMoreLoadingText() {
+			return this._getI18nText('loadingMoreLoadingText', this.loadingMoreLoadingText);
+		},
+		finalLoadingMoreNoMoreText() {
+			return this._getI18nText('loadingMoreNoMoreText', this.loadingMoreNoMoreText);
+		},
+		finalLoadingMoreFailText() {
+			return this._getI18nText('loadingMoreFailText', this.loadingMoreFailText);
+		},
+		finalEmptyViewText() {
+			if (this.isLoadFailed) {
+				return this.finalEmptyViewErrorText;
+			} else {
+				return this._getI18nText('emptyViewText', this.emptyViewText);
+			}
+		},
+		finalEmptyViewReloadText() {
+			return this._getI18nText('emptyViewReloadText', this.emptyViewReloadText);
+		},
+		finalEmptyViewErrorText() {
+			return this._getI18nText('emptyViewErrorText', this.emptyViewErrorText);
+		},
+		finalEmptyViewImg() {
+			if (this.isLoadFailed) {
+				return this.emptyViewErrorImg;
+			} else {
+				return this.emptyViewImg;
+			}
+		},
+		finalShowEmptyViewReload() {
+			if (this.isLoadFailed) {
+				return this.showEmptyViewReloadWhenError;
+			} else {
+				return this.showEmptyViewReload;
+			}
+		},
+		finalRefresherThemeStyle() {
+			if (this.refresherThemeStyle.length) {
+				return this.refresherThemeStyle;
+			}
+			return this.defaultThemeStyle;
+		},
+		finalLoadingMoreThemeStyle() {
+			if (this.loadingMoreThemeStyle.length) {
+				return this.loadingMoreThemeStyle;
+			}
+			return this.defaultThemeStyle;
+		},
+		finalPagingContentStyle() {
+			if (this.contentZIndex != 1) {
+				this.pagingContentStyle['z-index'] = this.contentZIndex;
+				this.pagingContentStyle['position'] = 'relative';
+			}
+			return this.pagingContentStyle;
+		},
+		finalScrollViewStyle() {
+			if (this.superContentZIndex != 1) {
+				this.scrollViewStyle['z-index'] = this.superContentZIndex;
+				this.scrollViewStyle['position'] = 'relative';
+			}
+			return this.scrollViewStyle;
+		},
+		finalRefresherOutRate() {
+			if (this.refresherOutRate < 0) {
+				return 0;
+			}
+			if (this.refresherOutRate > 1) {
+				return 1;
+			}
+			return this.refresherOutRate;
+		},
+		finalRefresherTransform() {
+			if (this.refresherTransform === 'translateY(0px)') {
+				return 'none';
+			}
+			return this.refresherTransform;
+		},
+		showEmpty() {
+			const showEmpty = !this.refresherOnly && !this.totalData.length && (this.autoHideEmptyViewWhenLoading ? this
+				.isAddedData : true) && !this.hideEmptyView && (this.autoHideEmptyViewWhenLoading ? (!this
+				.firstPageLoaded && !this.loading) : true);
+			return showEmpty;
+		},
+		tempLanguage() {
+			let systemLanguage = false;
+			const temp = this.tempLanguageUpdateKey;
+			if (this.followSystemLanguage) {
+				systemLanguage = systemInfo.language;
+			}
+			return uni.getStorageSync(i18nUpdateKey) || systemLanguage || 'zh-cn';
+		},
+		safeAreaBottom() {
+			if (!this.systemInfo) {
+				return 0;
+			}
+			let safeAreaBottom = 0;
+			// #ifdef APP-PLUS || H5 || MP-WEIXIN
+			safeAreaBottom = this.systemInfo.safeAreaInsets.bottom || 0;
+			// #endif
+			return safeAreaBottom;
+		},
+		renderJsIgnore() {
+			if ((this.usePageScroll && this.useChatRecordMode) || !this.refresherEnabled || !this.useCustomRefresher) {
+				this.$nextTick(() => {
+					this.renderPropScrollTop = 10;
+				})
+			}
+			return 0;
+		},
+		windowTop() {
+			if (!this.systemInfo) {
+				return 0;
+			}
+			const windowTop = this.systemInfo.windowTop;
+			return windowTop || 0;
+		},
+		windowBottom() {
+			if (!this.systemInfo) {
+				return 0;
+			}
+			let windowBottom = this.systemInfo.windowBottom || 0;
+			if (this.safeAreaInsetBottom) {
+				windowBottom += this.safeAreaBottom;
+			}
+			return windowBottom;
+		},
+		nWaterfallColumnCount() {
+			if (this.finalNvueListIs !== 'waterfall') {
+				return 0;
+			}
+			return this._getNvueWaterfallSingleConfig('column-count', 2);
+		},
+		nWaterfallColumnWidth() {
+			return this._getNvueWaterfallSingleConfig('column-width', 'auto');
+		},
+		nWaterfallColumnGap() {
+			return this._getNvueWaterfallSingleConfig('column-gap', 'normal');
+		},
+		nWaterfallLeftGap() {
+			return this._getNvueWaterfallSingleConfig('left-gap', 0);
+		},
+		nWaterfallRightGap() {
+			return this._getNvueWaterfallSingleConfig('right-gap', 0);
+		},
+		nViewIs() {
+			const finalNvueListIs = this.finalNvueListIs;
+			return finalNvueListIs === 'scroller' || finalNvueListIs === 'view' ? 'view' : finalNvueListIs ===
+				'waterfall' ? 'header' : 'cell';
+		},
+		nSafeAreaBottomHeight() {
+			return this.safeAreaInsetBottom ? this.safeAreaBottom : 0;
+		}
+	},
+	methods: {
+		//请求结束(成功或者失败)调用此方法,将请求的结果传递给z-paging处理,第一个参数为请求结果数组,第二个参数为是否成功(默认是是)
+		complete(data, success = true) {
+			this.customNoMore = -1;
+			this.addData(data, success);
+		},
+		//【保证数据一致】请求结束(成功或者失败)调用此方法,将请求的结果传递给z-paging处理,第一个参数为请求结果数组,第二个参数为dataKey,需与:data-key绑定的一致,第三个参数为是否成功(默认是是)
+		completeByKey(data, dataKey = null, success = true) {
+			if (dataKey !== null && this.dataKey !== null && dataKey !== this.dataKey) {
+				return;
+			}
+			this.customNoMore = -1;
+			this.addData(data, success);
+		},
+		//【自行判断是否有更多数据】请求结束(成功或者失败)调用此方法,将请求的结果传递给z-paging处理,第一个参数为请求结果数组,第二个参数为是否有更多数据,第三个参数为是否成功(默认是是)
+		completeByNoMore(data, nomore, success = true) {
+			if (nomore != 'undefined') {
+				this.customNoMore = nomore == true ? 1 : 0;
+			}
+			this.addData(data, success);
+		},
+		//与上方complete方法功能一致,新版本中设置服务端回调数组请使用complete方法
+		addData(data, success = true) {
+			this.$nextTick(() => {
+				this._addData(data, success, false);
+			})
+		},
+		//设置i18n国际化语言
+		setI18n(language) {
+			zI18n.setLanguage(language);
+		},
+		//获取当前z-paging的语言
+		getLanguage() {
+			return this.finalLanguage;
+		},
+		//当前版本号
+		getVersion() {
+			return `z-paging ${currentVersion}`;
+		},
+		//添加聊天记录
+		addChatRecordData(data, toBottom = true, toBottomWithAnimate = true) {
+			let dataType = Object.prototype.toString.call(data);
+			if (dataType !== '[object Array]') {
+				data = [data];
+			}
+			if (!this.useChatRecordMode) {
+				return;
+			}
+			this.isTotalChangeFromAddData = true;
+			//#ifndef APP-NVUE
+			this.totalData = [...this.totalData, ...data];
+			//#endif
+			//#ifdef APP-NVUE
+			if (this.nIsFirstPageAndNoMore) {
+				this.totalData = [...this.totalData, ...data];
+			} else {
+				this.totalData = [...data, ...this.totalData];
+			}
+			//#endif
+			if (toBottom) {
+				setTimeout(() => {
+					//#ifndef APP-NVUE
+					this._scrollToBottom(toBottomWithAnimate);
+					//#endif
+					//#ifdef APP-NVUE
+					if (this.nIsFirstPageAndNoMore) {
+						this._scrollToBottom(toBottomWithAnimate);
+					} else {
+						this._scrollToTop(toBottomWithAnimate);
+					}
+					//#endif
+				}, commonDelayTime)
+			}
+		},
+		//从顶部添加数据,不会影响分页的pageNo和pageSize
+		addDataFromTop(data, toTop = true, toTopWithAnimate = true) {
+			let dataType = Object.prototype.toString.call(data);
+			if (dataType !== '[object Array]') {
+				data = [data];
+			}
+			this.totalData = [...data, ...this.totalData];
+			if (toTop) {
+				setTimeout(() => {
+					this._scrollToTop(toTopWithAnimate);
+				}, commonDelayTime)
+			}
+		},
+		//重新设置列表数据,调用此方法不会影响pageNo和pageSize,也不会触发请求。适用场景:当需要删除列表中某一项时,将删除对应项后的数组通过此方法传递给z-paging。(当出现类似的需要修改列表数组的场景时,请使用此方法,请勿直接修改page中:list.sync绑定的数组)
+		resetTotalData(data) {
+			if (data == undefined) {
+				if (this.showConsoleError) {
+					zUtils.consoleErr('方法resetTotalData参数缺失!');
+				}
+				return;
+			}
+			this.isTotalChangeFromAddData = true;
+			let dataType = Object.prototype.toString.call(data);
+			if (dataType !== '[object Array]') {
+				data = [data];
+			}
+			this.totalData = data;
+		},
+		//设置本地分页数据,请求结束(成功或者失败)调用此方法,将请求的结果传递给z-paging作分页处理(若调用了此方法,则上拉加载更多时内部会自动分页,不会触发@query所绑定的事件)
+		setLocalPaging(data, success = true) {
+			this.isLocalPaging = true;
+			this.$nextTick(() => {
+				this._addData(data, success, true);
+			})
+		},
+		//重新加载分页数据,pageNo会恢复为默认值,相当于下拉刷新的效果(animate为true时会展示下拉刷新动画,默认为false)
+		reload(animate = this.showRefresherWhenReload) {
+			if (animate) {
+				this.privateShowRefresherWhenReload = animate;
+				this.isUserPullDown = true;
+			}
+			this._preReload(animate, false);
+		},
+		//清空分页数据
+		clean() {
+			this._reload(true);
+			this._addData([], true, false);
+		},
+		//手动触发滚动到顶部加载更多,聊天记录模式时有效
+		doChatRecordLoadMore() {
+			if (this.useChatRecordMode) {
+				this._onLoadingMore('click');
+			}
+		},
+		//手动触发上拉加载更多(非必须,可依据具体需求使用)
+		doLoadMore() {
+			this._onLoadingMore('toBottom');
+		},
+		//手动停止下拉刷新加载
+		endRefresh() {
+			this.refresherTriggered = false;
+		},
+		//滚动到顶部,animate为是否展示滚动动画,默认为是
+		scrollToTop(animate) {
+			this._scrollToTop(animate, false);
+		},
+		//滚动到底部,animate为是否展示滚动动画,默认为是
+		scrollToBottom(animate) {
+			this.$nextTick(() => {
+				this._scrollToBottom(animate);
+			})
+		},
+		//滚动到指定view(vue中有效)。sel为需要滚动的view的id值,不包含"#";offset为偏移量,单位为px;animate为是否展示滚动动画,默认为否
+		scrollIntoViewById(sel, offset, animate) {
+			this._scrollIntoView(sel, offset, animate);
+		},
+		//滚动到指定view(vue中有效)。nodeTop为需要滚动的view的top值(通过uni.createSelectorQuery()获取);offset为偏移量,单位为px;animate为是否展示滚动动画,默认为否
+		scrollIntoViewByNodeTop(nodeTop, offset, animate) {
+			this.scrollTop = this.oldScrollTop;
+			this.$nextTick(() => {
+				this._scrollIntoViewByNodeTop(nodeTop, offset, animate);
+			})
+		},
+		//滚动到指定view(nvue中有效)。index为需要滚动的view的index(第几个);offset为偏移量,单位为px;animate为是否展示滚动动画,默认为否
+		scrollIntoViewByIndex(index, offset, animate) {
+			this._scrollIntoView(index, offset, animate);
+		},
+		//滚动到指定view(nvue中有效)。view为需要滚动的view(通过`this.$refs.xxx`获取),不包含"#";offset为偏移量,单位为px;animate为是否展示滚动动画,默认为否
+		scrollIntoViewByView(view, offset, animate) {
+			this._scrollIntoView(view, offset, animate);
+		},
+		//当使用页面滚动并且自定义下拉刷新时,请在页面的onPageScroll中调用此方法,告知z-paging当前的pageScrollTop,否则会导致在任意位置都可以下拉刷新
+		updatePageScrollTop(value) {
+			if (value == undefined) {
+				//zUtils.consoleErr('updatePageScrollTop方法缺少参数,请将页面onPageScroll事件中的scrollTop传递给此方法');
+				return;
+			}
+			this.pageScrollTop = value;
+		},
+		//当使用页面滚动并且设置了slot="top"时,默认初次加载会自动获取其高度,并使内部容器下移,当slot="top"的view高度动态改变时,在其高度需要更新时调用此方法
+		updatePageScrollTopHeight() {
+			this._updatePageScrollTopOrBottomHeight('top');
+		},
+		//当使用页面滚动并且设置了slot="bottom"时,默认初次加载会自动获取其高度,并使内部容器下移,当slot="bottom"的view高度动态改变时,在其高度需要更新时调用此方法
+		updatePageScrollBottomHeight() {
+			this._updatePageScrollTopOrBottomHeight('bottom');
+		},
+		//更新z-paging内置scroll-view的scrollTop
+		updateScrollViewScrollTop(scrollTop, animate = true) {
+			this.privateScrollWithAnimation = animate ? 1 : 0;
+			this.scrollTop = this.oldScrollTop;
+			this.$nextTick(() => {
+				this.scrollTop = scrollTop;
+				this.oldScrollTop = this.scrollTop;
+			});
+		},
+		//设置nvue List的specialEffects
+		setListSpecialEffects(args) {
+			this.nFixFreezing = args !== {};
+			if (!this.usePageScroll) {
+				this.$refs['n-list'].setSpecialEffects(args);
+			}
+		},
+		handleRefresherStatusChanged(func) {
+			this.refresherStatusChangedFunc = func;
+		},
+		//------------------ 私有方法 ------------------------
+		//reload之前的一些处理
+		_preReload(animate = this.showRefresherWhenReload, isFromMounted = true) {
+			this.isUserReload = true;
+			if (animate) {
+				this.privateShowRefresherWhenReload = animate;
+				// #ifndef APP-NVUE
+				if (this.useCustomRefresher) {
+					this._doRefresherRefreshAnimate();
+				} else {
+					this.refresherTriggered = true;
+				}
+				// #endif
+				// #ifdef APP-NVUE
+				this.refresherStatus = 2;
+				this.refresherRevealStackCount++;
+				setTimeout(() => {
+					this._getNodeClientRect('zp-n-refresh-container', false).then((node) => {
+						if (node) {
+							let nodeHeight = node[0].height;
+							this.nShowRefresherReveal = true;
+							this.nShowRefresherRevealHeight = nodeHeight;
+							setTimeout(() => {
+								this._nDoRefresherEndAnimation(0, -nodeHeight, false, false);
+								setTimeout(() => {
+									this._nDoRefresherEndAnimation(nodeHeight, 0);
+								}, 10)
+							}, 10)
+							this._reload(false, isFromMounted);
+						} else {
+							this._reload(false, isFromMounted);
+						}
+					});
+				}, 10)
+				return;
+				// #endif
+			} else {
+				this._refresherEnd(false, false);
+			}
+			this._reload(false, isFromMounted);
+		},
+		//重新加载分页数据
+		_reload(isClean = false, isFromMounted = false) {
+			this.isAddedData = false;
+			this.cacheScrollNodeHeight = -1;
+			this.pageNo = this.defaultPageNo;
+			if (!isClean) {
+				this._startLoading(true);
+			}
+			this.firstPageLoaded = true;
+			this.isTotalChangeFromAddData = false;
+			this.totalData = [];
+			if (!isClean) {
+				this.$emit('query', this.pageNo, this.defaultPageSize);
+				let delay = 0;
+				// #ifdef MP-TOUTIAO
+				delay = 5;
+				// #endif
+				setTimeout(() => {
+					this._callMyParentQuery();
+				}, delay)
+				if (!isFromMounted && this.autoScrollToTopWhenReload) {
+					let checkedNRefresherLoading = true;
+					// #ifdef APP-NVUE
+					checkedNRefresherLoading = !this.nRefresherLoading;
+					// #endif
+					if (checkedNRefresherLoading) {
+						this._scrollToTop(false);
+					}
+				}
+				// #ifndef APP-NVUE
+				if (!this.usePageScroll && this.useChatRecordMode) {
+					if (this.showConsoleError) {
+						zUtils.consoleWarn('[z-paging]使用聊天记录模式时,建议使用页面滚动,可将usePageScroll设置为true以启用页面滚动!!');
+					}
+				}
+				// #endif
+			}
+			this.$nextTick(() => {
+				if (!this.realTotalData.length) {
+					// #ifdef APP-NVUE
+					this.nShowBottom = false;
+					// #endif
+				}
+			})
+		},
+		//处理服务端返回的数组
+		_addData(data, success, isLocal) {
+			this.isAddedData = true;
+			this.isTotalChangeFromAddData = true;
+			if (!this.useCustomRefresher) {
+				uni.stopPullDownRefresh();
+			}
+			// #ifdef APP-NVUE
+			if (this.usePageScroll) {
+				uni.stopPullDownRefresh();
+			}
+			// #endif
+			if (this.isUserPullDown && this.showRefresherUpdateTime && this.pageNo === this.defaultPageNo) {
+				zUtils.setRefesrherTime((new Date()).getTime(), this.refresherUpdateTimeKey);
+				this.tempLanguageUpdateKey = (new Date()).getTime();
+				if (this.$refs.refresh) {
+					this.$refs.refresh.updateTime();
+				}
+			}
+			if (this.isUserPullDown && this.pageNo === this.defaultPageNo) {
+				this.isUserPullDown = false;
+			}
+			const dataType = Object.prototype.toString.call(data);
+			if (dataType === '[object Boolean]') {
+				success = data;
+				data = [];
+			} else if (dataType !== '[object Array]') {
+				data = [];
+				let methodStr = isLocal ? 'setLocalPaging' : 'complete';
+				if (dataType !== '[object Undefined]') {
+					if (this.showConsoleError) {
+						zUtils.consoleErr(`${methodStr}参数类型不正确,第一个参数类型必须为Array!`);
+					}
+				}
+			}
+			if (this.refresherTriggered) {
+				this.refresherTriggered = false;
+			}
+			let delayTime = commonDelayTime;
+			// #ifdef APP-NVUE
+			if (this.useChatRecordMode) {
+				delayTime = 0
+			}
+			// #endif
+			setTimeout(() => {
+				this._refresherEnd(true, true);
+				this.pagingLoaded = true;
+			}, delayTime)
+			if (this.pageNo === this.defaultPageNo) {
+				this.isLoadFailed = !success;
+			}
+			if (success) {
+				this.loadingStatus = 0;
+				if (isLocal) {
+					this.totalLocalPagingList = data;
+					this._localPagingQueryList(this.defaultPageNo, this.defaultPageSize, 0, (res) => {
+						this.complete(res);
+					})
+				} else {
+					this._currentDataChange(data, this.currentData);
+				}
+			} else {
+				this._currentDataChange(data, this.currentData);
+				this.loadingStatus = 3;
+				if (this.loadingType === 1) {
+					this.pageNo--;
+				}
+			}
+		},
+		//当前数据改变时调用
+		_currentDataChange(newVal, oldVal) {
+			newVal = [...newVal];
+			// #ifndef APP-NVUE
+			if (this.useChatRecordMode) {
+				newVal.reverse();
+			}
+			// #endif
+			if (this.pageNo === this.defaultPageNo && this.concat) {
+				this.totalData = [];
+			}
+			if (this.customNoMore !== -1) {
+				if (this.customNoMore === 0 || !newVal.length) {
+					this.loadingStatus = 2;
+				}
+			} else {
+				if (!newVal.length ||
+					(newVal.length && newVal.length < this.defaultPageSize)) {
+					this.loadingStatus = 2;
+				}
+			}
+			if (!this.totalData.length) {
+				if (this.concat) {
+					this.totalData = newVal;
+				}
+				if (this.useChatRecordMode) {
+					// #ifndef APP-NVUE
+					this.$nextTick(() => {
+						this._scrollToBottom(false);
+					})
+					// #endif
+				}
+			} else {
+				if (this.useChatRecordMode) {
+					// #ifdef APP-NVUE
+					this.totalData = [...this.totalData, ...newVal];
+					// #endif
+					//#ifndef APP-NVUE
+					const idIndex = newVal.length;
+					let idIndexStr = `z-paging-${idIndex}`;
+					this.totalData = [...newVal, ...this.totalData];
+					if (this.pageNo !== this.defaultPageNo) {
+						this.privateScrollWithAnimation = 0;
+						let delayTime = 200;
+						//#ifdef H5
+						delayTime = 0;
+						//#endif
+						this.$emit('update:chatIndex', idIndex);
+						if (this.usePageScroll) {
+							this._scrollIntoView(idIndexStr, 30, false, () => {
+								this.$emit('update:chatIndex', 0);
+							});
+						} else {
+							setTimeout(() => {
+								this._scrollIntoView(idIndexStr, 30, false, () => {
+									this.$emit('update:chatIndex', 0);
+								});
+							}, delayTime)
+						}
+					} else {
+						this.$nextTick(() => {
+							this._scrollToBottom(false);
+						})
+					}
+					//#endif
+
+				} else {
+					if (this.concat) {
+						this.totalData = [...this.totalData, ...newVal];
+					}
+				}
+			}
+		},
+		//通过@scroll事件检测是否滚动到了底���
+		_checkScrolledToBottom(scrollDiff) {
+			if (this.cacheScrollNodeHeight === -1) {
+				this._getNodeClientRect('.zp-scroll-view').then((res) => {
+					if (res) {
+						let pageScrollNodeHeight = res[0].height;
+						this.cacheScrollNodeHeight = pageScrollNodeHeight;
+						if (scrollDiff - pageScrollNodeHeight <= this.finalLowerThreshold) {
+							this._onLoadingMore('toBottom');
+						}
+					}
+				});
+			} else {
+				if (scrollDiff - this.cacheScrollNodeHeight <= this.finalLowerThreshold) {
+					this._onLoadingMore('toBottom');
+				}
+			}
+		},
+		//触发加载更多时调用,from:0-滑动到底部触发;1-点击加载更多触发
+		_onLoadingMore(from = 'click') {
+			if (from === 'toBottom') {
+				if (!this.scrollToBottomBounceEnabled) {
+					if (this.scrollEnable) {
+						this.scrollEnable = false;
+						this.$nextTick(() => {
+							this.scrollEnable = true;
+						})
+					}
+				}
+			}
+			this.$emit('scrolltolower', from);
+			if (from === 'toBottom' && (!this.toBottomLoadingMoreEnabled || this.useChatRecordMode)) {
+				return;
+			}
+			if (this.refresherOnly || !this.loadingMoreEnabled || !(this.loadingStatus === 0 || 3) || this.loading)
+				return;
+			this._doLoadingMore();
+		},
+		//当滚动到顶部时
+		_scrollToUpper() {
+			this.$emit('scrolltoupper');
+			this.$emit('scrollTopChange', 0);
+			this.$nextTick(() => {
+				this.oldScrollTop = 0;
+			})
+			if (!this.useChatRecordMode) {
+				return;
+			}
+			if (this.loadingStatus === 2) {
+				return;
+			}
+
+			this._onLoadingMore('click');
+		},
+		//点击返回顶部
+		_backToTopClick() {
+			if (!this.backToTopWithAnimate) {
+				this._checkShouldShowBackToTop(1, 0);
+			}
+			this.scrollToTop(this.backToTopWithAnimate);
+		},
+		//滚动到顶部
+		_scrollToTop(animate, isPrivate = true) {
+			// #ifdef APP-NVUE
+			const el = this.$refs['zp-n-list-top-tag'];
+			if (this.usePageScroll) {
+				this._getNodeClientRect('zp-page-scroll-top', false).then((node) => {
+					if (node) {
+						let nodeHeight = node[0].height;
+						weexDom.scrollToElement(el, {
+							offset: -nodeHeight,
+							animated: animate
+						});
+					}
+				});
+			} else {
+				weexDom.scrollToElement(el, {
+					offset: 0,
+					animated: animate
+				});
+			}
+			return;
+			// #endif
+			if (this.usePageScroll) {
+				this.$nextTick(() => {
+					uni.pageScrollTo({
+						scrollTop: 0,
+						duration: animate ? 100 : 0,
+					});
+				});
+				return;
+			}
+			this.privateScrollWithAnimation = animate ? 1 : 0;
+			this.scrollTop = this.oldScrollTop;
+			this.$nextTick(() => {
+				this.scrollTop = 0;
+				this.oldScrollTop = this.scrollTop;
+			});
+		},
+		//滚动到底部
+		async _scrollToBottom(animate = true) {
+			// #ifdef APP-NVUE
+			const el = this.$refs['zp-n-list-bottom-tag'];
+			weexDom.scrollToElement(el, {
+				offset: 0,
+				animated: animate
+			});
+			return;
+			// #endif
+			if (this.usePageScroll) {
+				this.$nextTick(() => {
+					uni.pageScrollTo({
+						scrollTop: Number.MAX_VALUE,
+						duration: animate ? 100 : 0,
+					});
+				});
+				return;
+			}
+			try {
+				this.privateScrollWithAnimation = animate ? 1 : 0;
+				let pagingContainerH = 0;
+				let scrollViewH = 0;
+				const pagingContainerNode = await this._getNodeClientRect('.zp-paging-container');
+				const scrollViewNode = await this._getNodeClientRect('.zp-scroll-view');
+				if (pagingContainerNode) {
+					pagingContainerH = pagingContainerNode[0].height;
+				}
+				if (scrollViewNode) {
+					scrollViewH = scrollViewNode[0].height;
+				}
+				if (pagingContainerH > scrollViewH) {
+					this.scrollTop = this.oldScrollTop;
+					this.$nextTick(() => {
+						this.scrollTop = pagingContainerH - scrollViewH;
+						this.oldScrollTop = this.scrollTop;
+					});
+				}
+			} catch (e) {
+
+			}
+		},
+		//滚动到指定view
+		_scrollIntoView(sel, offset = 0, animate = false, finishCallback) {
+			try {
+				this.scrollTop = this.oldScrollTop;
+				this.$nextTick(() => {
+					// #ifdef APP-NVUE
+					const refs = this.$parent.$refs;
+					if (!refs) {
+						return;
+					}
+					const dataType = Object.prototype.toString.call(sel);
+					let el = null;
+					if (dataType === '[object Number]') {
+						const els = refs[`z-paging-${sel}`];
+						el = els ? els[0] : null;
+					} else {
+						el = sel;
+					}
+					if (el) {
+						weexDom.scrollToElement(el, {
+							offset: -offset,
+							animated: animate
+						});
+					} else {
+						zUtils.consoleErr('在nvue中滚动到指定位置,cell必须设置 :ref="`z-paging-${index}`"');
+					}
+					return;
+					// #endif
+					if (sel.indexOf('#') != -1) {
+						sel = sel.replace('#', '');
+					}
+					this._getNodeClientRect('#' + sel, false).then((node) => {
+						if (node) {
+							let nodeTop = node[0].top;
+							this._scrollIntoViewByNodeTop(nodeTop, offset, animate);
+							if (finishCallback) {
+								finishCallback();
+							}
+						}
+					});
+				});
+			} catch (e) {
+
+			}
+		},
+		//通过nodeTop滚动到指定view
+		_scrollIntoViewByNodeTop(nodeTop, offset = 0, animate = false) {
+			this.privateScrollWithAnimation = animate ? 1 : 0;
+			if (this.usePageScroll) {
+				uni.pageScrollTo({
+					scrollTop: nodeTop - offset,
+					duration: animate ? 100 : 0
+				});
+			} else {
+				nodeTop = nodeTop + this.oldScrollTop;
+				this.scrollTop = nodeTop - offset;
+				this.oldScrollTop = this.scrollTop;
+			}
+		},
+		//是否要展示上拉加载更多view
+		_shouldShowLoading(type) {
+			if (!(this.loadingStatus === 0 ? this.nShowBottom : true)) {
+				return false;
+			}
+			if (((!this.showLoadingMoreWhenReload || this.isUserPullDown || this.loadingStatus !== 1) && !this
+					.showLoadingMore) || (!this.loadingMoreEnabled && (!this.showLoadingMoreWhenReload || this
+					.isUserPullDown || this.loadingStatus !== 1)) || this
+				.refresherOnly) {
+				return false;
+			}
+			if (this.useChatRecordMode && type !== 'loadingMoreLoading') {
+				return false;
+			}
+			if (!this.$slots) {
+				return false;
+			}
+			if (type === 'loadingMoreDefault') {
+				const res = this.loadingStatus === 0 && this.$slots.loadingMoreDefault;
+				if (res) {
+					// #ifdef APP-NVUE
+					if (!this.isIos) {
+						this.nLoadingMoreFixedHeight = false;
+					}
+					//  #endif
+				}
+				return res;
+			} else if (type === 'loadingMoreLoading') {
+				const res = this.loadingStatus === 1 && this.$slots.loadingMoreLoading;
+				if (res) {
+					// #ifdef APP-NVUE
+					if (!this.isIos) {
+						this.nLoadingMoreFixedHeight = false;
+					}
+					//  #endif
+				}
+				return res;
+			} else if (type === 'loadingMoreNoMore') {
+				const res = this.loadingStatus === 2 && this.$slots.loadingMoreNoMore && this.showLoadingMoreNoMoreView;
+				if (res) {
+					// #ifdef APP-NVUE
+					if (!this.isIos) {
+						this.nLoadingMoreFixedHeight = false;
+					}
+					//  #endif
+				}
+				return res;
+			} else if (type === 'loadingMoreFail') {
+				const res = this.loadingStatus === 3 && this.$slots.loadingMoreFail;
+				if (res) {
+					// #ifdef APP-NVUE
+					if (!this.isIos) {
+						this.nLoadingMoreFixedHeight = false;
+					}
+					//  #endif
+				}
+				return res;
+			} else if (type === 'loadingMoreCustom') {
+				const res = this.showDefaultLoadingMoreText && !(this.loadingStatus === 2 && !this
+					.showLoadingMoreNoMoreView);
+				return res;
+			}
+			return false;
+		},
+		//处理开始加载更多状态
+		_startLoading(isReload = false) {
+			if ((this.showLoadingMoreWhenReload && !this.isUserPullDown) || !isReload) {
+				this.loadingStatus = 1;
+			}
+			this.loading = true;
+		},
+		//处理开始加载更多
+		_doLoadingMore() {
+			if (this.pageNo >= this.defaultPageNo && this.loadingStatus !== 2) {
+				this.pageNo++;
+				this._startLoading(false);
+				if (this.isLocalPaging) {
+					this._localPagingQueryList(this.pageNo, this.defaultPageSize, this.localPagingLoadingTime, (
+						res) => {
+						this.addData(res);
+					})
+				} else {
+					this.$emit('query', this.pageNo, this.defaultPageSize);
+					this._callMyParentQuery();
+				}
+				this.loadingType = 1;
+			}
+		},
+		_scroll(e) {
+			this.$emit('scroll', e);
+			this.oldScrollTop = e.detail.scrollTop;
+			const scrollDiff = e.detail.scrollHeight - this.oldScrollTop;
+			if (!this.isIos) {
+				this._checkScrolledToBottom(scrollDiff);
+			}
+		},
+		//自定义下拉刷新被触发
+		_onRefresh() {
+			if (this.loading || this.nShowRefresherReveal) {
+				return;
+			}
+			this.isUserPullDown = true;
+			this.isUserReload = false;
+			this._startLoading(true);
+			this.refresherTriggered = true;
+			if (this.useChatRecordMode) {
+				this._onLoadingMore('click')
+			} else {
+				this._reload();
+			}
+			this.$emit('onRefresh');
+			this.loadingType = 0;
+		},
+		//自定义下拉刷新被复位
+		_onRestore() {
+			this.refresherTriggered = 'restore';
+			this.$emit('onRestore');
+		},
+		//拖拽开始
+		_refresherTouchstart(e) {
+			if (this._getRefresherTouchDisabled()) {
+				return;
+			}
+			const touch = zUtils.getCommonTouch(e);
+			this._handleRefresherTouchstart(touch);
+		},
+		//进一步处理拖拽开始结果
+		_handleRefresherTouchstart(touch) {
+			if (!this.loading && this.isTouchEnded) {
+				this.isTouchmoving = false;
+			}
+			this.isTouchEnded = false;
+			this.refresherTransition = 'transform .1s linear';
+			this.refresherTouchstartY = touch.touchY;
+			this.$emit('refresherTouchstart', this.refresherTouchstartY);
+			this.lastRefresherTouchmove = touch;
+		},
+		//拖拽中
+		_refresherTouchmove(e) {
+			const currentTimeStamp = (new Date()).getTime();
+			if (this.pullDownTimeStamp && currentTimeStamp - this.pullDownTimeStamp <= this.pullDownDisTimeStamp) {
+				return;
+			}
+			if (this._getRefresherTouchDisabled()) {
+				return;
+			}
+			this.pullDownTimeStamp = Number(currentTimeStamp);
+			const touch = zUtils.getCommonTouch(e);
+			let refresherTouchmoveY = touch.touchY;
+			let moveDistance = refresherTouchmoveY - this.refresherTouchstartY;
+			if (moveDistance < 0) {
+				return;
+			}
+			if (this.refresherMaxAngle >= 0 && this.refresherMaxAngle <= 90 && this.lastRefresherTouchmove && this
+				.lastRefresherTouchmove.touchY <= refresherTouchmoveY) {
+				if (!moveDistance && !this.refresherAngleEnableChangeContinued && this.moveDistance < 1 && !this
+					.refresherReachMaxAngle) {
+					return;
+				}
+				const x = Math.abs(touch.touchX - this.lastRefresherTouchmove.touchX);
+				const y = Math.abs(refresherTouchmoveY - this.lastRefresherTouchmove.touchY);
+				const z = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
+				if ((x || y) && x > 1) {
+					const angle = Math.asin(y / z) / Math.PI * 180;
+					if (angle < this.refresherMaxAngle) {
+						this.lastRefresherTouchmove = touch;
+						this.refresherReachMaxAngle = false;
+						return;
+					}
+				}
+			}
+			moveDistance = this._getFinalRefresherMoveDistance(moveDistance);
+			this._handleRefresherTouchmove(moveDistance, touch);
+			if (!this.disabledBounce) {
+				this._handleScrollViewDisableBounce({
+					bounce: false
+				});
+				this.disabledBounce = true;
+			}
+		},
+		//进一步处理拖拽中结果
+		_handleRefresherTouchmove(moveDistance, touch) {
+			this.refresherReachMaxAngle = true;
+			if (!this.isTouchmoving) {
+				this.isTouchmoving = true;
+			}
+			this.isTouchEnded = false;
+			if (moveDistance >= this.finalRefresherThreshold) {
+				this.refresherStatus = 1;
+			} else {
+				this.refresherStatus = 0;
+			}
+			// #ifndef APP-VUE || MP-WEIXIN || MP-QQ  || H5
+			// this.scrollEnable = false;
+			this.refresherTransform = `translateY(${moveDistance}px)`;
+			this.lastRefresherTouchmove = touch;
+			// #endif
+			this.moveDistance = moveDistance;
+			this.$emit('refresherTouchmove', moveDistance);
+		},
+		//拖拽结束
+		_refresherTouchend(e) {
+			if (this._getRefresherTouchDisabled() || !this.isTouchmoving) {
+				return;
+			}
+			const touch = zUtils.getCommonTouch(e);
+			let refresherTouchendY = touch.touchY;
+			let moveDistance = refresherTouchendY - this.refresherTouchstartY;
+			moveDistance = this._getFinalRefresherMoveDistance(moveDistance);
+			this._handleRefresherTouchend(moveDistance);
+			this._handleScrollViewDisableBounce({
+				bounce: true
+			});
+			this.disabledBounce = false;
+		},
+		//进一步处理拖拽结束结果
+		_handleRefresherTouchend(moveDistance) {
+			// #ifndef APP-PLUS || H5 || MP-WEIXIN
+			if (!this.isTouchmoving) {
+				return;
+			}
+			// #endif
+			this.refresherReachMaxAngle = true;
+			if (moveDistance < 0 && this.usePageScroll && this.loadingMoreEnabled && this.useCustomRefresher && this
+				.pageScrollTop === -1) {
+				if (this.showConsoleError) {
+					zUtils.consoleErr(
+						'usePageScroll为true并且自定义下拉刷新时必须引入mixin或在page滚动时通过调用z-paging组件的updatePageScrollTop方法设置当前的scrollTop'
+					)
+				}
+			}
+			this.isTouchEnded = true;
+			if (moveDistance >= this.finalRefresherThreshold && this.refresherStatus === 1) {
+				// #ifndef APP-VUE || MP-WEIXIN || MP-QQ  || H5
+				this.refresherTransform = `translateY(${this.finalRefresherThreshold}px)`;
+				// #endif
+				this.moveDistance = this.finalRefresherThreshold;
+				this.refresherStatus = 2;
+				this._doRefresherLoad();
+			} else {
+				this._refresherEnd(true, false);
+				setTimeout(() => {
+					this.isTouchmoving = false;
+				}, commonDelayTime);
+			}
+			this.scrollEnable = true;
+			this.$emit('refresherTouchend', moveDistance);
+		},
+		//处理scroll-view bounce是否生效
+		_handleScrollViewDisableBounce(e) {
+			if (!this.usePageScroll && this.isIos && !this.scrollToTopBounceEnabled) {
+				if (!e.bounce) {
+					if (this.scrollEnable) {
+						this.scrollEnable = false;
+					}
+				} else {
+					this.scrollEnable = true;
+				}
+			}
+		},
+		//wxs正在下拉处理
+		_handleWxsOnPullingDown(onPullingDown) {
+			this.wxsOnPullingDown = onPullingDown;
+			if (onPullingDown) {
+				if (!this.useChatRecordMode) {
+					this.renderPropScrollTop = 0;
+				}
+			}
+		},
+		//下拉刷新结束
+		_refresherEnd(shouldEndLoadingDelay = true, fromAddData = false) {
+			// #ifndef APP-NVUE
+			if (this.showRefresherWhenReload || this.privateShowRefresherWhenReload) {
+				const stackCount = this.refresherRevealStackCount;
+				this.refresherRevealStackCount--;
+				if (stackCount > 1) {
+					return;
+				}
+				this.refresherStatus = 0;
+			} else {
+				setTimeout(() => {
+					this.refresherStatus = 0;
+				}, commonDelayTime);
+			}
+			// #endif
+			// #ifndef APP-VUE || MP-WEIXIN || MP-QQ  || H5
+			this.refresherTransform = 'translateY(0px)';
+			// #endif
+			// #ifdef APP-VUE || MP-WEIXIN || MP-QQ || H5
+			this.wxsPropType = 'end' + (new Date()).getTime();
+			// #endif
+			this.moveDistance = 0;
+			if (this.refresherEndBounceEnabled && fromAddData) {
+				this.refresherTransition = 'transform 0.3s cubic-bezier(0.19,1.64,0.42,0.72)';
+			}
+			if (shouldEndLoadingDelay) {
+				setTimeout(() => {
+					this.loading = false;
+				}, commonDelayTime);
+			} else {
+				this.loading = false;
+			}
+			this.$emit('onRestore');
+			// #ifdef APP-NVUE
+			this._nRefresherEnd();
+			// #endif
+		},
+		//模拟用户手动触发下拉刷新
+		_doRefresherRefreshAnimate() {
+			this.refresherRevealStackCount++;
+			this.refresherTransform = `translateY(${this.finalRefresherThreshold}px)`;
+			// #ifdef APP-VUE || MP-WEIXIN || MP-QQ || H5
+			this.wxsPropType = 'begin' + (new Date()).getTime();
+			// #endif
+			this.moveDistance = this.finalRefresherThreshold;
+			this.refresherStatus = 2;
+			this.isTouchmoving = true;
+		},
+		//触发下拉刷新
+		_doRefresherLoad() {
+			this._onRefresh();
+			this.loading = true;
+		},
+		//获取处理后的moveDistance
+		_getFinalRefresherMoveDistance(moveDistance) {
+			moveDistance = moveDistance * 0.85;
+			if (moveDistance >= this.finalRefresherThreshold) {
+				moveDistance = this.finalRefresherThreshold + (moveDistance - this.finalRefresherThreshold) * (1 - this
+					.finalRefresherOutRate);
+			}
+			return moveDistance;
+		},
+		//判断当没有更多数据且分页内容未超出z-paging时是否显示没有更多数据的view
+		async _checkShowLoadingMoreWhenNoMoreAndInsideOfPaging(totalData) {
+			try {
+				const scrollViewNode = await this._getNodeClientRect('.zp-scroll-view');
+				if (this.usePageScroll) {
+					if (scrollViewNode) {
+						const scrollViewTotalH = scrollViewNode[0].top + scrollViewNode[0].height;
+						this.showLoadingMore = scrollViewTotalH >= this.systemInfo.windowHeight;
+					}
+				} else {
+					let pagingContainerH = 0;
+					let scrollViewH = 0;
+					const pagingContainerNode = await this._getNodeClientRect('.zp-paging-container-content');
+					if (pagingContainerNode) {
+						pagingContainerH = pagingContainerNode[0].height;
+					}
+					if (scrollViewNode) {
+						scrollViewH = scrollViewNode[0].height;
+					}
+					this.showLoadingMore = pagingContainerH >= scrollViewH;
+				}
+			} catch (e) {
+				this.showLoadingMore = totalData.length;
+			}
+		},
+		//检测z-paging是否超出了页面高度
+		async _checkScrollViewOutOfPage() {
+			try {
+				const scrollViewNode = await this._getNodeClientRect('.zp-scroll-view');
+				if (scrollViewNode) {
+					const scrollViewTotalH = scrollViewNode[0].top + scrollViewNode[0].height;
+					if (scrollViewTotalH > this.systemInfo.windowHeight + 100) {
+						if (this.showConsoleError) {
+							zUtils.consoleWarn(
+								'检测到z-paging的高度超出页面高度,这将导致滚动或展示出现异常,请设置【:fixed="true"】或【确保z-paging有确定的高度(如果通过百分比设置z-paging的高度,请保证z-paging的所有父view已设置高度,同时确保page也设置了height:100%,如:page{height:100%}】,此时z-paging的百分比高度才能生效。详情参考demo或访问:https://ext.dcloud.net.cn/plugin?id=3935)'
+							);
+						}
+					}
+				}
+			} catch (e) {
+
+			}
+		},
+		//检测z-paging是否要全屏覆盖(当使用页面滚动并且不满全屏时,默认z-paging需要铺满全屏,避免数据过少时内部的empty-view无法正确展示)
+		async _checkScrollViewShouldFullHeight() {
+			try {
+				const scrollViewNode = await this._getNodeClientRect('.zp-scroll-view');
+				const pagingContainerNode = await this._getNodeClientRect('.zp-paging-container-content');
+				if (!scrollViewNode || !pagingContainerNode) {
+					return;
+				}
+				const scrollViewHeight = pagingContainerNode[0].height;
+				const scrollViewTop = scrollViewNode[0].top;
+				if (this.isAddedData && scrollViewHeight + scrollViewTop <= this.systemInfo.windowHeight + 10) {
+					this._setAutoHeight(true, scrollViewNode);
+				} else {
+					this._setAutoHeight(false);
+				}
+			} catch (e) {
+
+			}
+		},
+		//设置z-paging高度
+		async _setAutoHeight(shouldFullHeight = true, scrollViewNode = null) {
+			try {
+				if (shouldFullHeight) {
+					let finalScrollViewNode = scrollViewNode ? scrollViewNode : await this._getNodeClientRect(
+						'.scroll-view');
+					if (finalScrollViewNode) {
+						const scrollViewTop = finalScrollViewNode[0].top;
+						const scrollViewHeight = this.systemInfo.windowHeight - scrollViewTop;
+						let additionHeight = this._convertTextToPx(this.autoHeightAddition);
+						this.$set(this.scrollViewStyle, 'height', scrollViewHeight + additionHeight + 'px');
+					}
+				} else {
+					this.$delete(this.scrollViewStyle, 'height');
+				}
+			} catch (e) {
+
+			}
+		},
+		//获取节点尺寸
+		_getNodeClientRect(select, inThis = true) {
+			// #ifdef APP-NVUE
+			select = select.replace('.', '').replace('#', '');
+			const ref = this.$refs[select];
+			if (ref) {
+				return new Promise((resolve, reject) => {
+					weexDom.getComponentRect(ref, option => {
+						if (option && option.result && option.result) {
+							resolve([option.size]);
+						} else {
+							resolve(false);
+						}
+					})
+				});
+			} else {
+				return new Promise((resolve, reject) => {
+					resolve(false);
+				});
+			}
+			return;
+			// #endif
+			let res = null;
+			if (inThis) {
+				res = uni.createSelectorQuery().in(this);
+			} else {
+				res = uni.createSelectorQuery();
+			}
+			//#ifdef MP-ALIPAY
+			res = uni.createSelectorQuery();
+			//#endif
+			res.select(select).boundingClientRect();
+			return new Promise((resolve, reject) => {
+				res.exec(data => {
+					if (data && data != '' && data != undefined && data.length) {
+						resolve(data);
+					} else {
+						resolve(false);
+					}
+				});
+			});
+		},
+		//判断touch手势是否要触发
+		_getRefresherTouchDisabled() {
+			let checkOldScrollTop = this.oldScrollTop > 5;
+			const res = this.loading || this.useChatRecordMode || !this.refresherEnabled || !this.useCustomRefresher ||
+				(
+					this.usePageScroll && this
+					.useCustomRefresher && this
+					.pageScrollTop > 10) || (!(this.usePageScroll && this.useCustomRefresher) && checkOldScrollTop);
+			return res;
+		},
+		//本地分页请求
+		_localPagingQueryList(pageNo, pageSize, localPagingLoadingTime, callback) {
+			pageNo = parseInt(pageNo);
+			pageSize = parseInt(pageSize);
+			if (pageNo < 0 || pageSize <= 0) {
+				callQueryResult(callback, []);
+				return;
+			}
+			if (pageNo == 0) {
+				pageNo = 1;
+			}
+			let totalPagingList = [...this.totalLocalPagingList];
+			let pageNoIndex = (pageNo - 1) * pageSize;
+			if (pageNoIndex + pageSize <= totalPagingList.length) {
+				this._localPagingQueryResult(callback, totalPagingList.splice(pageNoIndex, pageSize),
+					localPagingLoadingTime);
+			} else if (pageNoIndex < totalPagingList.length) {
+				this._localPagingQueryResult(callback, totalPagingList.splice(pageNoIndex, totalPagingList.length -
+						pageNoIndex),
+					localPagingLoadingTime);
+			} else {
+				this._localPagingQueryResult(callback, [], localPagingLoadingTime);
+			}
+		},
+		//本地分页请求回调
+		_localPagingQueryResult(callback, arg, localPagingLoadingTime) {
+			setTimeout(() => {
+				callback(arg);
+			}, localPagingLoadingTime)
+		},
+		//将文本的px或者rpx转为px的值
+		_convertTextToPx(text) {
+			const dataType = Object.prototype.toString.call(text);
+			if (dataType === '[object Number]') {
+				return text;
+			}
+			let isRpx = false;
+			if (text.indexOf('rpx') !== -1 || text.indexOf('upx') !== -1) {
+				text = text.replace('rpx', '').replace('upx', '');
+				isRpx = true;
+			} else if (text.indexOf('px') !== -1) {
+				text = text.replace('px', '');
+			}
+			if (!isNaN(text)) {
+				if (isRpx) {
+					return Number(uni.upx2px(text));
+				}
+				return Number(text);
+			}
+			return 0;
+		},
+
+		//判断是否要显示返回顶部按钮
+		_checkShouldShowBackToTop(newVal, oldVal) {
+			if (!this.autoShowBackToTop) {
+				if (this.showBackToTopClass) {
+					this.showBackToTopClass = false;
+				}
+				return;
+			}
+			if (newVal !== oldVal) {
+				if (newVal > this.finalBackToTopThreshold) {
+					if (!this.showBackToTopClass) {
+						this.showBackToTopClass = true;
+						setTimeout(() => {
+							this.backToTopClass = 'zp-back-to-top zp-back-to-top-show';
+						}, 300)
+					}
+				} else {
+					if (this.showBackToTopClass) {
+						this.backToTopClass = 'zp-back-to-top zp-back-to-top-hide';
+						setTimeout(() => {
+							this.showBackToTopClass = false;
+						}, 300)
+					}
+				}
+			}
+		},
+		_updatePageScrollTopOrBottomHeight(type) {
+			// #ifdef APP-VUE
+			if (!this.usePageScroll) {
+				return;
+			}
+			// #endif
+			const node = `.zp-page-scroll-${type}`;
+			const marginText = `margin${type.slice(0,1).toUpperCase() + type.slice(1)}`;
+			this.$nextTick(() => {
+				let delayTime = 0;
+				// #ifdef MP-BAIDU
+				delayTime = 10;
+				// #endif
+				setTimeout(() => {
+					this._getNodeClientRect(node).then((res) => {
+						if (res) {
+							let pageScrollNodeHeight = res[0].height;
+							if (type === 'bottom') {
+								if (this.safeAreaInsetBottom) {
+									pageScrollNodeHeight += this.safeAreaBottom;
+								}
+							}
+							this.$set(this.scrollViewStyle, marginText,
+								`${pageScrollNodeHeight}px`);
+						} else if (this.safeAreaInsetBottom) {
+							this.$set(this.scrollViewStyle, marginText,
+								`${this.safeAreaBottom}px`);
+						}
+					});
+				}, delayTime)
+			})
+		},
+		//点击了空数据view重新加载按钮
+		_emptyViewReload() {
+			let callbacked = false;
+			this.$emit('emptyViewReload', (reload) => {
+				if (reload === undefined || reload === true) {
+					this.reload();
+				}
+				callbacked = true;
+			});
+			this.$nextTick(() => {
+				if (!callbacked) {
+					this.reload();
+				}
+			})
+		},
+		//获取国际化转换后的文本
+		_getI18nText(key, value) {
+			const dataType = Object.prototype.toString.call(value);
+			if (dataType === '[object Object]') {
+				const nextValue = value[this.finalLanguage];
+				if (nextValue) {
+					return nextValue;
+				}
+			} else if (dataType === '[object String]') {
+				return value;
+			}
+			return zI18n[key][this.finalLanguage];
+		},
+		//修改父view的list
+		_callMyParentList(newVal) {
+			if (this.autowireListName.length) {
+				const myParent = zUtils.getParent(this.$parent);
+				if (myParent && myParent[this.autowireListName]) {
+					myParent[this.autowireListName] = newVal;
+				}
+			}
+		},
+		//调用父view的query
+		_callMyParentQuery() {
+			if (this.autowireQueryName) {
+				if (this.myParentQuery === -1) {
+					const myParent = zUtils.getParent(this.$parent);
+					if (myParent && myParent[this.autowireQueryName]) {
+						this.myParentQuery = myParent[this.autowireQueryName];
+					}
+				}
+				if (this.myParentQuery !== -1) {
+					this.myParentQuery(this.pageNo, this.defaultPageSize);
+				}
+			}
+		},
+		// ------------nvue独有的方法----------------
+		//列表滚动时触发
+		_nOnScroll(e) {
+			const contentOffsetY = e.contentOffset.y;
+			this.$emit('scroll', e);
+			this.nListIsDragging = e.isDragging;
+			this._checkShouldShowBackToTop(-e.contentOffset.y, -e.contentOffset.y - 1);
+		},
+		//下拉刷新刷新中
+		_nOnRrefresh() {
+			if (this.nShowRefresherReveal) {
+				return;
+			}
+			this.nRefresherLoading = true;
+			this.refresherStatus = 2;
+			this._doRefresherLoad();
+		},
+		//下拉刷新下拉中
+		_nOnPullingdown(e) {
+			if (this.refresherStatus === 2 || (this.isIos && !this.nListIsDragging)) {
+				return;
+			}
+			const viewHeight = e.viewHeight;
+			const pullingDistance = e.pullingDistance;
+			if (pullingDistance >= viewHeight) {
+				this.refresherStatus = 1;
+			} else {
+				this.refresherStatus = 0;
+			}
+		},
+		//下拉刷新结束
+		_nRefresherEnd() {
+			this._nDoRefresherEndAnimation(0, -this.nShowRefresherRevealHeight);
+			if (!this.nShowBottom) {
+				setTimeout(() => {
+					this.$nextTick(() => {
+						this.nShowBottom = true;
+					})
+				}, 1000);
+			}
+			if (!this.usePageScroll) {
+				this.$refs["n-list"].resetLoadmore();
+			}
+			this.nRefresherLoading = false;
+		},
+		//执行主动触发下拉刷新动画
+		_nDoRefresherEndAnimation(height, translateY, animate = true, checkStack = true) {
+			if (!this.showRefresherWhenReload && !this.privateShowRefresherWhenReload) {
+				setTimeout(() => {
+					this.refresherStatus = 0;
+				}, commonDelayTime);
+				return;
+			}
+			const stackCount = this.refresherRevealStackCount;
+			if (height === 0 && checkStack) {
+				this.refresherRevealStackCount--;
+				if (stackCount > 1) {
+					return;
+				}
+				this.refresherStatus = 0;
+			}
+			if (stackCount > 1) {
+				this.refresherStatus = 2;
+			}
+			const duration = animate ? 120 : 0;
+			weexAnimation.transition(this.$refs['zp-n-list-refresher-reveal'], {
+				styles: {
+					height: `${height}px`,
+					transform: `translateY(${translateY}px)`,
+				},
+				duration: duration,
+				timingFunction: 'linear',
+				needLayout: true,
+				delay: 0
+			})
+			setTimeout(() => {
+				if (animate) {
+					this.nShowRefresherReveal = height > 0;
+				}
+			}, duration > 0 ? duration - 100 : 0);
+		},
+		//滚动到底部加载更多
+		_nOnLoadmore() {
+			if (this.nShowRefresherReveal || !this.totalData.length) {
+				return;
+			}
+			if (this.useChatRecordMode) {
+				this.doChatRecordLoadMore();
+			} else {
+				this._onLoadingMore('toBottom');
+			}
+		},
+		//获取nvue waterfall单项配置
+		_getNvueWaterfallSingleConfig(key, defaultValue) {
+			const value = this.nvueWaterfallConfig[key];
+			if (value) {
+				return value;
+			}
+			return defaultValue;
+		}
+	},
+};

+ 36 - 0
uni_modules/z-paging/components/z-paging/js/z-paging-mixin.js

@@ -0,0 +1,36 @@
+// z-paging
+// github地址:https://github.com/SmileZXLee/uni-z-paging
+// dcloud地址:https://ext.dcloud.net.cn/plugin?id=3935
+// 反馈QQ群:790460711
+// 使用页面滚动时引入此mixin,用于监听和处理onPullDownRefresh等页面生命周期方法
+
+const ZPagingMixin = {
+	onPullDownRefresh() {
+		if (this.isPagingRefNotFound()) {
+			return;
+		}
+		this.$refs.paging.reload();
+	},
+	onPageScroll(e) {
+		if (this.isPagingRefNotFound()) {
+			return;
+		}
+		this.$refs.paging.updatePageScrollTop(e.scrollTop);
+		if (e.scrollTop < 10) {
+			this.$refs.paging.doChatRecordLoadMore();
+		}
+	},
+	onReachBottom() {
+		if (this.isPagingRefNotFound()) {
+			return;
+		}
+		this.$refs.paging.doLoadMore();
+	},
+	methods: {
+		isPagingRefNotFound() {
+			return !this.$refs.paging || this.$refs.paging === undefined;
+		}
+	}
+}
+
+export default ZPagingMixin;

Fișier diff suprimat deoarece este prea mare
+ 12 - 0
uni_modules/z-paging/components/z-paging/js/z-paging-static.js


+ 179 - 0
uni_modules/z-paging/components/z-paging/js/z-paging-utils.js

@@ -0,0 +1,179 @@
+// z-paging
+// github地址:https://github.com/SmileZXLee/uni-z-paging
+// dcloud地址:https://ext.dcloud.net.cn/plugin?id=3935
+// 反馈QQ群:790460711
+// z-paging工具类
+
+import zI18n from './z-paging-i18n'
+
+const storageKey = 'Z-PAGING-REFRESHER-TIME-STORAGE-KEY'
+
+//判断两个数组是否相等
+function arrayIsEqual(arr1, arr2) {
+	if (arr1 === arr2) {
+		return true;
+	}
+	if (arr1.length !== arr2.length) {
+		return false;
+	}
+	for (let i = 0; i < arr1.length; i++) {
+		if (arr1[i] !== arr2[i]) {
+			return false;
+		}
+	}
+	return true;
+}
+
+//获取最终的touch位置
+function getCommonTouch(e) {
+	let touch = null;
+	if (e.touches && e.touches.length) {
+		touch = e.touches[0];
+	} else if (e.changedTouches && e.changedTouches.length) {
+		touch = e.changedTouches[0];
+	} else if (e.datail && e.datail !== {}) {
+		touch = e.datail;
+	} else {
+		return {
+			touchX: 0,
+			touchY: 0
+		}
+	}
+	return {
+		touchX: touch.clientX,
+		touchY: touch.clientY
+	};
+}
+
+//判断当前手势是否在z-paging内触发
+function getTouchFromZPaging(target) {
+	if (target && target.tagName && target.tagName !== 'BODY' && target.tagName !== 'UNI-PAGE-BODY') {
+		var classList = target.classList;
+		if (classList && classList.contains('zp-paging-touch-view')) {
+			return true;
+		} else {
+			return getTouchFromZPaging(target.parentNode);
+		}
+	} else {
+		return false;
+	}
+}
+
+//获取z-paging所在的parent
+function getParent(parent) {
+	if (!parent) {
+		return null;
+	}
+	if (parent.$refs.paging) {
+		return parent;
+	}
+	return getParent(parent.$parent);
+}
+
+//打印错误信息
+function consoleErr(err) {
+	console.error(`[z-paging]${err}`);
+}
+
+//打印警告信息
+function consoleWarn(warn) {
+	console.warn(`[z-paging]${warn}`);
+}
+
+//设置下拉刷新时间
+function setRefesrherTime(time, key) {
+	try {
+		let datas = getRefesrherTime();
+		if (!datas) {
+			datas = {};
+		}
+		datas[key] = time;
+		uni.setStorageSync(storageKey, datas);
+	} catch {}
+}
+
+//获取下拉刷新时间
+function getRefesrherTime() {
+	try {
+		const datas = uni.getStorageSync(storageKey);
+		return datas;
+	} catch {
+		return null;
+	}
+}
+
+//通过下拉刷新标识key获取下拉刷新时间
+function getRefesrherTimeByKey(key) {
+	const datas = getRefesrherTime();
+	if (datas) {
+		const data = datas[key];
+		if (data) {
+			return data;
+		}
+	}
+	return null;
+}
+
+//通过下拉刷新标识key获取下拉刷新时间(格式化之后)
+function getRefesrherFormatTimeByKey(key) {
+	const time = getRefesrherTimeByKey(key);
+	let timeText = zI18n['refresherUpdateTimeNoneText'][zI18n.getLanguage()];
+	if (time) {
+		timeText = _timeFormat(time);
+	}
+	return `${zI18n['refresherUpdateTimeText'][zI18n.getLanguage()]}${timeText}`;
+}
+
+function _timeFormat(time) {
+	const date = new Date(time);
+	const currentDate = new Date();
+	const dateDay = new Date(time).setHours(0, 0, 0, 0);
+	const currentDateDay = new Date().setHours(0, 0, 0, 0);
+	const disTime = dateDay - currentDateDay;
+	let dayStr = '';
+	const timeStr = _dateTimeFormat(date);
+	if (disTime === 0) {
+		dayStr = zI18n['refresherUpdateTimeTodayText'][zI18n.getLanguage()];
+	} else if (disTime === -86400000) {
+		dayStr = zI18n['refresherUpdateTimeYesterdayText'][zI18n.getLanguage()];
+	} else {
+		dayStr = _dateDayFormat(date, date.getFullYear() !== currentDate.getFullYear());
+	}
+	return `${dayStr} ${timeStr}`;
+}
+
+function _dateDayFormat(date, showYear = true) {
+	const year = date.getFullYear();
+	const month = date.getMonth() + 1;
+	const day = date.getDate();
+	if (showYear) {
+		return `${year}-${_fullZeroToTwo(month)}-${_fullZeroToTwo(day)}`;
+	} else {
+		return `${_fullZeroToTwo(month)}-${_fullZeroToTwo(day)}`;
+	}
+}
+
+function _dateTimeFormat(date) {
+	const hour = date.getHours();
+	const minute = date.getMinutes();
+	return `${_fullZeroToTwo(hour)}:${_fullZeroToTwo(minute)}`;
+}
+
+function _fullZeroToTwo(str) {
+	str = str.toString();
+	if (str.length === 1) {
+		return '0' + str;
+	}
+	return str;
+}
+
+module.exports = {
+	setRefesrherTime,
+	getRefesrherFormatTimeByKey,
+	arrayIsEqual,
+	getCommonTouch,
+	getTouchFromZPaging,
+	getParent,
+	consoleErr,
+	consoleWarn
+};

+ 60 - 0
uni_modules/z-paging/components/z-paging/wxs/z-paging-renderjs.js

@@ -0,0 +1,60 @@
+// z-paging
+// github地址:https://github.com/SmileZXLee/uni-z-paging
+// dcloud地址:https://ext.dcloud.net.cn/plugin?id=3935
+// 反馈QQ群:790460711
+// 使用renderjs在app-vue和h5中对touchmove事件冒泡进行处理
+
+import zUtils from '../js/z-paging-utils'
+export default {
+	data() {
+		return {
+			renderScrollTop: 0,
+			renderUsePageScroll: false,
+			renderIsIos: uni.getSystemInfoSync().platform === 'ios',
+			startY: 0,
+			isTouchFromZPaging: false
+		}
+	},
+	mounted() {
+		this._handleTouch();
+	},
+	methods: {
+		//接收逻辑层发送的数据
+		renderPropScrollTopChange(newVal, oldVal, ownerVm, vm) {
+			this.renderScrollTop = newVal;
+		},
+		renderUsePageScrollChange(newVal, oldVal, ownerVm, vm) {
+			this.renderUsePageScroll = newVal;
+		},
+		//拦截处理touch事件
+		_handleTouch() {
+			if (window && !window.$zPagingRenderJsInited) {
+				window.$zPagingRenderJsInited = true;
+				window.addEventListener('touchstart', this._handleTouchstart, {
+					passive: true
+				})
+				window.addEventListener('touchmove', this._handleTouchmove, {
+					passive: false
+				})
+			}
+		},
+		_handleTouchstart(e) {
+			const touch = zUtils.getCommonTouch(e);
+			this.startY = touch.touchY;
+			this.isTouchFromZPaging = zUtils.getTouchFromZPaging(e.target);
+		},
+		_handleTouchmove(e) {
+			const touch = zUtils.getCommonTouch(e);
+			var moveY = touch.touchY - this.startY;
+			if ((this.isTouchFromZPaging && this.renderScrollTop < 1 && moveY > 0) || (this.isTouchFromZPaging && this
+					.renderIsIos && !this
+					.renderUsePageScroll && moveY <
+					0)) {
+				if (e.cancelable && !e.defaultPrevented) {
+					e.preventDefault();
+				}
+			}
+		},
+
+	}
+};

+ 335 - 0
uni_modules/z-paging/components/z-paging/wxs/z-paging-wxs.wxs

@@ -0,0 +1,335 @@
+// z-paging
+// github地址:https://github.com/SmileZXLee/uni-z-paging
+// dcloud地址:https://ext.dcloud.net.cn/plugin?id=3935
+// 反馈QQ群:790460711
+// 微信小程序、QQ小程序、app-vue、h5上使用wxs实现自定义下拉刷新,降低逻辑层与视图层的通信折损,提升性能
+
+var currentMoveDistance = 0;
+
+function propObserver(newValue, oldValue, ownerInstance, instance) {
+	var state = ownerInstance.getState();
+	state.currentInstance = instance;
+	var dataset = instance.getDataset();
+	var loading = dataset.loading == true;
+	if (newValue.indexOf('end') != -1) {
+		_setTransform('translateY(0px)', instance)
+		state.moveDistance = 0;
+		state.oldMoveDistance = 0;
+		currentMoveDistance = 0;
+	} else if (newValue.indexOf('begin') != -1) {
+		var refresherThreshold = instance.getDataset().refresherthreshold
+		_setTransformValue(refresherThreshold, instance, state);
+	}
+}
+
+function touchstart(e, ownerInstance) {
+	var instance = ownerInstance.getState().currentInstance;
+	var state = instance.getState();
+	var dataset = instance.getDataset();
+	var isTouchEnded = state.isTouchEnded;
+	if (_getRefresherTouchDisabled(e, instance, 0)) {
+		return;
+	}
+	state.oldMoveDistance = 0;
+	var touch = _getCommonTouch(e);
+	var loading = _getIsTrue(dataset.loading);
+	state.startY = touch.touchY;
+	state.lastRefresherTouchmove = touch;
+	if (!loading && isTouchEnded) {
+		state.isTouchmoving = false;
+	}
+	state.isTouchEnded = false;
+	ownerInstance.callMethod('_handleRefresherTouchstart', touch);
+}
+
+function touchmove(e, ownerInstance) {
+	var touch = _getCommonTouch(e);
+	var instance = ownerInstance.getState().currentInstance;
+	var dataset = instance.getDataset();
+	var refresherThreshold = dataset.refresherthreshold;
+	var state = instance.getState();
+	if (_getRefresherTouchDisabled(e, instance, 1)) {
+		_handleTouchMovePullingDown(state, ownerInstance, false);
+		return true;
+	}
+	if (!_getAngleIsInRange(e, touch, state, dataset)) {
+		_handleTouchMovePullingDown(state, ownerInstance, false);
+		return true;
+	}
+	var moveDistanceObj = _getMoveDistance(e, instance);
+	var moveDistance = moveDistanceObj.currentMoveDistance;
+	var prevent = moveDistanceObj.isDown;
+	if (moveDistance < 0) {
+		_setTransformValue(0, instance, state);
+		_handleTouchMovePullingDown(state, ownerInstance, false);
+		return true;
+	}
+	if (prevent && !state.disabledBounce) {
+		ownerInstance.callMethod('_handleScrollViewDisableBounce', {
+			bounce: false
+		});
+		state.disabledBounce = true;
+		_handleTouchMovePullingDown(state, ownerInstance, prevent);
+		return !prevent;
+	}
+	_setTransformValue(moveDistance, instance, state);
+	var oldRefresherStatus = state.refresherStatus;
+	var dataset = instance.getDataset();
+	var oldIsTouchmoving = _getIsTrue(dataset.oldistouchmoving);
+	var isTouchmoving = state.isTouchmoving;
+	if (moveDistance >= refresherThreshold) {
+		state.refresherStatus = 1;
+	} else {
+		state.refresherStatus = 0;
+	}
+	if (!isTouchmoving) {
+		state.isTouchmoving = true;
+		isTouchmoving = true;
+	}
+	if (state.isTouchEnded) {
+		state.isTouchEnded = false;
+	}
+	if (oldRefresherStatus == undefined || oldRefresherStatus != state.refresherStatus || oldIsTouchmoving !=
+		isTouchmoving) {
+		ownerInstance.callMethod('_handleRefresherTouchmove', moveDistance, touch);
+	}
+	_handleTouchMovePullingDown(state, ownerInstance, prevent);
+	return !prevent;
+}
+
+function touchend(e, ownerInstance) {
+	var touch = _getCommonTouch(e);
+	var instance = ownerInstance.getState().currentInstance;
+	var dataset = instance.getDataset();
+	var state = instance.getState();
+	if (_getRefresherTouchDisabled(e, instance, 2)) {
+		return;
+	}
+	state.refresherReachMaxAngle = true;
+	state.hitReachMaxAngleCount = 0;
+	state.disabledBounce = false;
+	state.fixedIsTopHitCount = 0;
+	//ownerInstance.callMethod('_handleScrollViewDisableBounce', {bounce:true});
+	var isTouchmoving = state.isTouchmoving;
+	if (!isTouchmoving) {
+		return;
+	}
+	var oldRefresherStatus = state.refresherStatus;
+	var oldMoveDistance = state.moveDistance;
+	var refresherThreshold = instance.getDataset().refresherthreshold
+	var moveDistance = _getMoveDistance(e, instance).currentMoveDistance;
+	if (!(moveDistance >= refresherThreshold && oldRefresherStatus === 1)) {
+		state.isTouchmoving = false;
+	}
+	ownerInstance.callMethod('_handleRefresherTouchend', moveDistance);
+	state.isTouchEnded = true;
+	if (oldMoveDistance < refresherThreshold) {
+		return;
+	}
+	if (moveDistance >= refresherThreshold) {
+		moveDistance = refresherThreshold;
+	}
+	_setTransformValue(moveDistance, instance, state)
+}
+
+// #ifdef H5
+function isPC() {
+	var userAgentInfo = navigator.userAgent;
+	var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
+	var flag = true;
+	for (var v = 0; v < Agents.length - 1; v++) {
+		if (userAgentInfo.indexOf(Agents[v]) > 0) {
+			flag = false;
+			break;
+		}
+	}
+	return flag;
+}
+
+var movable = false;
+
+function mousedown(e, ins) {
+	if (!isPC()) return;
+	touchstart(e, ins);
+	movable = true;
+}
+
+function mousemove(e, ins) {
+	if (!isPC()) return;
+	if (!movable) return;
+	touchmove(e, ins);
+}
+
+function mouseup(e, ins) {
+	if (!isPC()) return;
+	touchend(e, ins);
+	movable = false;
+}
+
+function mouseleave(e, ins) {
+	if (!isPC()) return;
+	movable = false;
+}
+// #endif
+
+
+function _setTransformValue(value, instance, state) {
+	value = value || 0;
+	if (state.moveDistance == value) {
+		return;
+	}
+	state.moveDistance = value;
+	_setTransform('translateY(' + value + 'px)', instance);
+}
+
+function _setTransform(transform, instance) {
+	if (transform == 'translateY(0px)') {
+		transform = 'none';
+	}
+	instance.requestAnimationFrame(function() {
+		instance.setStyle({
+			transform: transform,
+			'-webkit-transform': transform
+		})
+	})
+}
+
+function _getMoveDistance(e, instance) {
+	var state = instance.getState();
+	var refresherThreshold = instance.getDataset().refresherthreshold;
+	var refresherOutRate = instance.getDataset().refresheroutrate;
+	refresherThreshold = parseFloat(refresherThreshold);
+	refresherOutRate = parseFloat(refresherOutRate);
+	var touch = _getCommonTouch(e);
+	var moveDistance = touch.touchY - state.startY;
+	var oldMoveDistance = state.oldMoveDistance || 0;
+	state.oldMoveDistance = moveDistance;
+	var diffDis = moveDistance - oldMoveDistance;
+	if (diffDis > 0) {
+		diffDis = diffDis * 0.85;
+		if (currentMoveDistance > refresherThreshold) {
+			diffDis = diffDis * (1 - refresherOutRate);
+		}
+	}
+	currentMoveDistance += diffDis;
+	if (currentMoveDistance < 0) {
+		currentMoveDistance = 0;
+	}
+	return {
+		currentMoveDistance: currentMoveDistance,
+		isDown: diffDis > 0
+	};
+}
+
+function _getCommonTouch(e) {
+	var touch = null;
+	if (e.touches && e.touches.length) {
+		touch = e.touches[0];
+	} else if (e.changedTouches && e.changedTouches.length) {
+		touch = e.changedTouches[0];
+	} else if (e.datail && e.datail !== {}) {
+		touch = e.datail;
+	} else {
+		touch = e;
+	}
+	return {
+		touchX: touch.clientX,
+		touchY: touch.clientY
+	};
+}
+
+function _getRefresherTouchDisabled(e, instance, processTag) {
+	var dataset = instance.getDataset();
+	var state = instance.getState();
+	var loading = _getIsTrue(dataset.loading);
+	var useChatRecordMode = _getIsTrue(dataset.usechatrecordmode);
+	var refresherEnabled = _getIsTrue(dataset.refresherenabled);
+	var useCustomRefresher = _getIsTrue(dataset.usecustomrefresher);
+	var usePageScroll = _getIsTrue(dataset.usepagescroll);
+	var pageScrollTop = parseFloat(dataset.pagescrolltop);
+	var scrollTop = parseFloat(dataset.scrolltop);
+	var finalScrollTop = usePageScroll ? pageScrollTop : scrollTop;
+	var fixedIsTop = false;
+	var isIos = _getIsTrue(dataset.isios);
+	if (!isIos && finalScrollTop == (state.startScrollTop || 0) && finalScrollTop <= 105) {
+		fixedIsTop = true;
+	}
+	var fixedIsTopHitCount = state.fixedIsTopHitCount || 0;
+	if (fixedIsTop) {
+		fixedIsTopHitCount++;
+		if (fixedIsTopHitCount <= 3) {
+			fixedIsTop = false;
+		}
+		state.fixedIsTopHitCount = fixedIsTopHitCount;
+	} else {
+		state.fixedIsTopHitCount = 0;
+	}
+	if (!isIos && processTag === 0) {
+		state.startScrollTop = finalScrollTop || 0;
+	}
+	if (!isIos && processTag === 2) {
+		fixedIsTop = true;
+	}
+	var res = loading || useChatRecordMode || !refresherEnabled || !useCustomRefresher || ((
+		usePageScroll && useCustomRefresher && pageScrollTop > 5) && !fixedIsTop) || ((
+		!usePageScroll && useCustomRefresher && scrollTop > 5) && !fixedIsTop);
+	return res;
+}
+
+function _getAngleIsInRange(e, touch, state, dataset) {
+	var refresherMaxAngle = dataset.refreshermaxangle;
+	var refresherAecc = _getIsTrue(dataset.refresheraecc);
+	var lastRefresherTouchmove = state.lastRefresherTouchmove;
+	var refresherReachMaxAngle = state.refresherReachMaxAngle;
+	var moveDistance = state.oldMoveDistance;
+	if (!lastRefresherTouchmove) {
+		return true;
+	}
+	if (refresherMaxAngle >= 0 && refresherMaxAngle <= 90 && lastRefresherTouchmove) {
+		if ((!moveDistance || moveDistance < 1) && !refresherAecc && refresherReachMaxAngle != null && !
+			refresherReachMaxAngle) {
+			return false;
+		}
+		var x = Math.abs(touch.touchX - lastRefresherTouchmove.touchX);
+		var y = Math.abs(touch.touchY - lastRefresherTouchmove.touchY);
+		var z = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
+		if ((x || y) && x > 1) {
+			var angle = Math.asin(y / z) / Math.PI * 180;
+			if (angle < refresherMaxAngle) {
+				var hitReachMaxAngleCount = state.hitReachMaxAngleCount || 0;
+				state.hitReachMaxAngleCount = ++hitReachMaxAngleCount;
+				if (state.hitReachMaxAngleCount > 2) {
+					state.lastRefresherTouchmove = touch;
+					state.refresherReachMaxAngle = false;
+				}
+				return false;
+			}
+		}
+	}
+	state.lastRefresherTouchmove = touch;
+	return true;
+}
+
+function _handleTouchMovePullingDown(state, instance, onPullingDown) {
+	var oldOnPullingDown = state.onPullingDown || false;
+	if (oldOnPullingDown != onPullingDown) {
+		instance.callMethod('_handleWxsOnPullingDown', onPullingDown);
+	}
+	state.onPullingDown = onPullingDown;
+}
+
+function _getIsTrue(value) {
+	value = (typeof(value) === 'string' ? JSON.parse(value) : value) || false;
+	return value == true || value == 'true';
+}
+
+module.exports = {
+	touchstart: touchstart,
+	touchmove: touchmove,
+	touchend: touchend,
+	mousedown: mousedown,
+	mousemove: mousemove,
+	mouseup: mouseup,
+	mouseleave: mouseleave,
+	propObserver: propObserver
+}

+ 239 - 0
uni_modules/z-paging/components/z-paging/z-paging.vue

@@ -0,0 +1,239 @@
+ <!--                        _             
+  ____     _ __   __ _  __ _(_)_ __   __ _ 
+ |_  /____| '_ \ / _` |/ _` | | '_ \ / _` |
+  / /_____| |_) | (_| | (_| | | | | | (_| |
+ /___|    | .__/ \__,_|\__, |_|_| |_|\__, |
+          |_|          |___/         |___/ 
+V1.9.3
+by ZXLee 2021-07-12
+-- >
+<!-- API文档地址:http://z-paging.com -->
+<!-- github地址:https://github.com/SmileZXLee/uni-z-paging -->
+<!-- dcloud地址:https://ext.dcloud.net.cn/plugin?id=3935 -->
+<!-- 反馈QQ群:790460711 -->
+
+<template name="z-paging">
+	<!-- #ifndef APP-NVUE -->
+	<view :class="!usePageScroll&&fixed?'z-paging-content z-paging-content-fixed':'z-paging-content'"
+		:style="[finalPagingStyle]">
+		<!-- 顶部固定的slot -->
+		<slot v-if="!usePageScroll&&$slots.top" name="top"></slot>
+		<view class="zp-page-scroll-top" v-else-if="usePageScroll&&$slots.top" :style="[{'top':`${windowTop}px`,'z-index':topZIndex}]">
+			<slot name="top"></slot>
+		</view>
+		<view :class="{'zp-scroll-view-super':!usePageScroll}" :style="[finalScrollViewStyle]">
+			<scroll-view
+				:class="{'zp-scroll-view':true,'zp-scroll-view-absolute':!usePageScroll}"
+				:scroll-top="scrollTop"
+				:scroll-y="scrollable&&!usePageScroll&&scrollEnable" :enable-back-to-top="finalEnableBackToTop"
+				:show-scrollbar="showScrollbar" :scroll-with-animation="finalScrollWithAnimation"
+				:scroll-into-view="scrollIntoView" :lower-threshold="finalLowerThreshold" :upper-threshold="5"
+				:refresher-enabled="finalRefresherEnabled&&!useCustomRefresher" :refresher-threshold="finalRefresherThreshold"
+				:refresher-default-style="finalRefresherDefaultStyle" :refresher-background="refresherBackground"
+				:refresher-triggered="refresherTriggered" @scroll="_scroll" @scrolltolower="_onLoadingMore('toBottom')"
+				@scrolltoupper="_scrollToUpper" @refresherrestore="_onRestore" @refresherrefresh="_onRefresh"  
+				>	
+				<view class="zp-paging-touch-view"
+				<!-- #ifndef APP-VUE || MP-WEIXIN || MP-QQ  || H5 -->
+				@touchstart="_refresherTouchstart" @touchmove="_refresherTouchmove" @touchend="_refresherTouchend" @touchcancel="_refresherTouchend"
+				<!-- #endif -->
+				<!-- #ifdef APP-VUE || 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-color': refresherFixedBackground,'height': `${finalRefresherFixedBacHeight}px`}]"></view>
+					<view class="zp-paging-main" :style="[{'transform': finalRefresherTransform,'transition': refresherTransition}]"
+					<!-- #ifdef APP-VUE || MP-WEIXIN || MP-QQ || H5 -->
+					:change:prop="pagingWxs.propObserver" :prop="wxsPropType"
+					:data-refresherThreshold="finalRefresherThreshold" :data-isIos="isIos"
+					:data-loading="loading" :data-useChatRecordMode="useChatRecordMode" 
+					:data-refresherEnabled="refresherEnabled" :data-useCustomRefresher="useCustomRefresher" :data-pageScrollTop="wxsPageScrollTop"
+					:data-scrollTop="wxsScrollTop" :data-refresherMaxAngle="refresherMaxAngle" 
+					:data-refresherAecc="refresherAngleEnableChangeContinued" :data-usePageScroll="usePageScroll"
+					:data-oldIsTouchmoving="isTouchmoving" :data-refresherOutRate="finalRefresherOutRate"
+					<!-- #endif -->
+					<!-- #ifdef APP-VUE || H5 -->
+					:change:renderPropScrollTop="pagingRenderjs.renderPropScrollTopChange" :renderPropScrollTop="renderPropScrollTop"
+					:change:renderUsePageScroll="pagingRenderjs.renderUsePageScrollChange" :renderUsePageScroll="renderUsePageScroll"
+					<!-- #endif -->
+					>	
+						<view v-if="finalRefresherEnabled&&useCustomRefresher&&isTouchmoving" class="zp-custom-refresher-view"
+							:style="[{'margin-top': `-${finalRefresherThreshold}px`,'background-color': refresherBackground}]">
+							<view :style="[{'height': `${finalRefresherThreshold}px`,'background-color': refresherBackground}]">
+								<!-- 下拉刷新view -->
+								<slot 
+								<!-- #ifdef MP-WEIXIN || MP-QQ || MP-TOUTIAO || MP-BAIDU  -->
+								v-if="zScopedSlots.refresher"
+								<!-- #endif -->
+								<!-- #ifndef MP-WEIXIN || MP-QQ || MP-TOUTIAO || MP-BAIDU -->
+								v-if="$scopedSlots.refresher||$slots.refresher"
+								<!-- #endif -->
+								<!-- #ifndef MP-QQ -->
+								:refresherStatus="refresherStatus"
+								<!-- #endif -->
+								name="refresher" />
+								<z-paging-refresh ref="refresh" v-else :style="[{'height': `${finalRefresherThreshold}px`}]" :refresherStatus="refresherStatus"
+									:defaultThemeStyle="finalRefresherThemeStyle" :refresherDefaultText="finalRefresherDefaultText"
+									:refresherPullingText="finalRefresherPullingText" :refresherRefreshingText="finalRefresherRefreshingText" 
+									:showRefresherUpdateTime="showRefresherUpdateTime" :refresherUpdateTimeKey="refresherUpdateTimeKey"></z-paging-refresh>
+							</view>
+						</view>
+						<view class="zp-paging-container">
+							<slot v-if="useChatRecordMode&&$slots.chatLoading&&loadingStatus!==2&&realTotalData.length"
+								name="chatLoading" />
+							<view v-else-if="useChatRecordMode&&loadingStatus!==2&&realTotalData.length"
+								class="zp-chat-record-loading-container">
+								<text v-if="loadingStatus!==1" @click="_scrollToUpper()"
+									:class="defaultThemeStyle==='white'?'zp-loading-more-text zp-loading-more-text-white':'zp-loading-more-text zp-loading-more-text-black'">{{chatRecordLoadingMoreText}}</text>
+								<image v-else :src="base64Flower" class="zp-chat-record-loading-custom-image">
+								</image>
+							</view>
+							<slot v-if="$slots.loading&&!firstPageLoaded&&(autoHideLoadingAfterFirstLoaded?!pagingLoaded:true)&&loading" name="loading" />
+							<!-- 空数据图 -->
+							<view class="zp-empty-view"
+								v-if="showEmpty">
+								<slot v-if="$slots.empty" name="empty" />
+								<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" @reload="_emptyViewReload">
+								</z-paging-empty-view>
+							</view>
+							<!-- 主体内容 -->
+							<view class="zp-paging-container-content" :style="[finalPagingContentStyle]">
+								<slot />
+							</view>
+							<!-- 上拉加载更多view -->
+							<!-- #ifndef MP-ALIPAY -->
+							<slot v-if="_shouldShowLoading('loadingMoreDefault')" name="loadingMoreDefault" />
+							<slot v-else-if="_shouldShowLoading('loadingMoreLoading')" name="loadingMoreLoading" />
+							<slot v-else-if="_shouldShowLoading('loadingMoreNoMore')" name="loadingMoreNoMore" />
+							<slot v-else-if="_shouldShowLoading('loadingMoreFail')" name="loadingMoreFail" />
+							<z-paging-load-more @click.native="_onLoadingMore('click')"
+								v-else-if="_shouldShowLoading('loadingMoreCustom')" :zConfig="zPagingLoadMoreConfig">
+							</z-paging-load-more>
+							<!-- #endif -->
+							<!-- #ifdef MP-ALIPAY -->
+							<slot v-if="loadingStatus===0&&$slots.loadingMoreDefault&&showLoadingMore&&loadingMoreEnabled&&!useChatRecordMode"
+								name="loadingMoreDefault" />
+							<slot v-else-if="loadingStatus===1&&$slots.loadingMoreLoading&&showLoadingMore&&loadingMoreEnabled"
+								name="loadingMoreLoading" />
+							<slot v-else-if="loadingStatus===2&&$slots.loadingMoreNoMore&&showLoadingMore&&showLoadingMoreNoMoreView&&loadingMoreEnabled&&!useChatRecordMode"
+								name="loadingMoreNoMore" />
+							<slot v-else-if="loadingStatus===3&&$slots.loadingMoreFail&&showLoadingMore&&loadingMoreEnabled&&!useChatRecordMode"
+								name="loadingMoreFail" />
+							<z-paging-load-more @click.native="_onLoadingMore('click')" v-else-if="showLoadingMore&&showDefaultLoadingMoreText&&!(loadingStatus===2&&!showLoadingMoreNoMoreView)&&loadingMoreEnabled&&!useChatRecordMode" :zConfig="zPagingLoadMoreConfig">
+							</z-paging-load-more>
+							<!-- #endif -->
+						</view>
+					</view>
+				</view>
+			</scroll-view>
+		</view>
+		<slot v-if="!usePageScroll&&$slots.bottom" name="bottom"></slot>
+		<view class="zp-page-scroll-bottom" v-else-if="usePageScroll&&$slots.bottom" :style="[{'bottom': `${windowBottom}px`}]">
+			<slot name="bottom"></slot>
+		</view>
+		<view v-if="showBackToTopClass" :class="backToTopClass" :style="[finalBackToTopStyle]" @click.stop="_backToTopClick">
+			<image class="zp-back-to-top-img" :src="backToTopImg.length?backToTopImg:base64BackToTop"></image>
+		</view>  
+	</view>
+	<!-- #endif -->
+	<!-- #ifdef APP-NVUE -->
+	<view :is="finalNvueSuperListIs">
+		<view ref="zp-page-scroll-top" :is="nViewIs" class="zp-page-scroll-top" v-if="$slots.top" :style="[{'top':`${windowTop}px`,'z-index':topZIndex}]">
+			<slot name="top"></slot>
+		</view>
+		<view ref="n-list" id="z-paging-nlist" :style="[scrollViewStyle,useChatRecordMode ? {transform: nIsFirstPageAndNoMore?'rotate(0deg)':'rotate(180deg)'}:{}]" :is="finalNvueListIs" alwaysScrollableVertical="true"
+			:fixFreezing="nFixFreezing" :show-scrollbar="showScrollbar" :loadmoreoffset="finalLowerThreshold"
+			:scrollable="scrollable&&scrollEnable" :bounce="nvueBounce" :column-count="nWaterfallColumnCount" :column-width="nWaterfallColumnWidth"
+			:column-gap="nWaterfallColumnGap" :left-gap="nWaterfallLeftGap" :right-gap="nWaterfallRightGap"
+			@loadmore="_nOnLoadmore" @scroll="_nOnScroll">
+			<refresh class="zp-n-refresh" v-if="finalNvueListIs!=='view'&&refresherEnabled&&!nShowRefresherReveal&&!useChatRecordMode" :display="nRefresherLoading?'show':'hide'" @refresh="_nOnRrefresh"
+				@pullingdown="_nOnPullingdown">
+				<view ref="zp-n-refresh-container" class="zp-n-refresh-container">
+					<!-- 下拉刷新view -->
+					<slot v-if="zScopedSlots.refresher" :refresherStatus="refresherStatus" name="refresher" />
+					<z-paging-refresh ref="refresh" v-else :refresherStatus="refresherStatus" :defaultThemeStyle="finalRefresherThemeStyle"
+						:refresherDefaultText="finalRefresherDefaultText" :refresherPullingText="finalRefresherPullingText" :refresherRefreshingText="finalRefresherRefreshingText" 
+						:showRefresherUpdateTime="showRefresherUpdateTime" :refresherUpdateTimeKey="refresherUpdateTimeKey"></z-paging-refresh>
+				</view>
+			</refresh>
+			<view ref="zp-n-list-top-tag" class="zp-n-list-top-tag" :is="nViewIs"></view>
+			<view v-if="nShowRefresherReveal" ref="zp-n-list-refresher-reveal" :style="[{transform:`translateY(-${nShowRefresherRevealHeight}px)`,height:'0px'}]" :is="nViewIs">
+				<slot v-if="zScopedSlots.refresher" :refresherStatus="refresherStatus" name="refresher" />
+				<z-paging-refresh ref="refresh" v-else :refresherStatus="refresherStatus" :defaultThemeStyle="finalRefresherThemeStyle"
+					:refresherDefaultText="finalRefresherDefaultText" :refresherPullingText="finalRefresherPullingText" :refresherRefreshingText="finalRefresherRefreshingText" 
+					:showRefresherUpdateTime="showRefresherUpdateTime" :refresherUpdateTimeKey="refresherUpdateTimeKey"></z-paging-refresh>
+			</view>
+			<slot />
+			<!-- 空数据图 -->
+			<view style="flex: 1;" key="z-paging-empty-view" :style="[scrollViewStyle,useChatRecordMode ? {transform: nIsFirstPageAndNoMore?'rotate(0deg)':'rotate(180deg)'}:{}]" v-if="showEmpty" :is="finalNvueListIs==='scroller'?'view':finalNvueListIs==='waterfall'?'header':'cell'">
+				<view class="zp-empty-view">
+					<slot v-if="$slots.empty" name="empty" />
+					<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" @reload="_emptyViewReload">
+					</z-paging-empty-view>
+				</view>
+			</view>
+			<view ref="zp-n-list-bottom-tag" class="zp-n-list-bottom-tag" is="header"></view>
+			<!-- 全屏 -->
+			<view style="flex: 1;" :style="[scrollViewStyle,useChatRecordMode ? {transform: nIsFirstPageAndNoMore?'rotate(0deg)':'rotate(180deg)'}:{}]" v-if="$slots.loading&&!firstPageLoaded&&(autoHideLoadingAfterFirstLoaded?!pagingLoaded:true)&&loading" :is="finalNvueListIs==='scroller'?'view':finalNvueListIs==='waterfall'?'header':'cell'">
+				<slot name="loading" />
+			</view>
+			<!-- 上拉加载更多view -->
+			<view :is="nViewIs">
+				<view v-if="useChatRecordMode">
+					<view v-if="loadingStatus!==2&&realTotalData.length">
+						<slot v-if="$slots.chatLoading"
+							name="chatLoading" />
+						<view v-else class="zp-chat-record-loading-container">
+							<text v-if="loadingStatus!==1" @click="_scrollToUpper()"
+								:class="defaultThemeStyle==='white'?'zp-loading-more-text zp-loading-more-text-white':'zp-loading-more-text zp-loading-more-text-black'">{{chatRecordLoadingMoreText}}</text>
+							<view>
+								<loading-indicator v-if="loadingStatus===1" :animating="true"
+									class="zp-loading-more-line-loading-image">
+								</loading-indicator>
+							</view>
+						</view>
+					</view>
+				</view>
+				<view :style="nLoadingMoreFixedHeight?{height:loadingMoreCustomStyle&&loadingMoreCustomStyle.height?loadingMoreCustomStyle.height:'80rpx'}:{}">
+					<slot v-if="_shouldShowLoading('loadingMoreDefault')" name="loadingMoreDefault" />
+					<slot v-else-if="_shouldShowLoading('loadingMoreLoading')" name="loadingMoreLoading" />
+					<slot v-else-if="_shouldShowLoading('loadingMoreNoMore')" name="loadingMoreNoMore" />
+					<slot v-else-if="_shouldShowLoading('loadingMoreFail')" name="loadingMoreFail" />
+					<z-paging-load-more @click.native="_onLoadingMore('click')"
+						v-else-if="_shouldShowLoading('loadingMoreCustom')" :zConfig="zPagingLoadMoreConfig">
+					</z-paging-load-more>
+				</view>
+			</view>
+		</view>
+		<slot name="bottom"></slot>
+		<view v-if="showBackToTopClass" :class="backToTopClass" :style="[finalBackToTopStyle]" @click.stop="_backToTopClick">
+			<image class="zp-back-to-top-img" :src="backToTopImg.length?backToTopImg:base64BackToTop"></image>
+		</view>
+	</view>
+	<!-- #endif -->
+</template>
+
+<script
+    src="./js/z-paging-main.js"></script>
+<!-- #ifdef APP-VUE || MP-WEIXIN || MP-QQ || H5 -->
+<script
+    src="./wxs/z-paging-wxs.wxs"
+    module="pagingWxs"
+    lang="wxs"
+></script>
+<!-- #endif -->
+
+<!-- #ifdef APP-VUE || H5 -->
+<script module="pagingRenderjs" lang="renderjs">
+	import pagingRenderjs from './wxs/z-paging-renderjs.js';
+	export default {
+		mixins: [pagingRenderjs]
+	}
+</script>
+<!-- #endif -->
+
+<style scoped>
+	@import "./css/z-paging-main.css";
+	@import "./css/z-paging-static.css";
+</style>

+ 80 - 0
uni_modules/z-paging/package.json

@@ -0,0 +1,80 @@
+{
+  "id": "z-paging",
+  "displayName": "超简单、低耦合!仅需两步轻松完成完整分页逻辑(下拉刷新、上拉加载更多)",
+  "version": "1.9.3",
+  "description": "【支持nvue,使用wxs+renderjs实现】全平台兼容,支持自定义下拉刷新、上拉加载更多,支持自动管理空数据图、点击返回顶部,支持聊天分页、本地分页,支持展示最后更新时间,支持国际化等等",
+  "keywords": [
+    "分页器",
+    "nvue",
+    "wxs",
+    "自定义下拉刷新",
+    "自定义上拉加载"
+],
+  "repository": "https://github.com/SmileZXLee/uni-z-paging",
+  "engines": {
+    "HBuilderX": "^3.0.7"
+  },
+  "dcloudext": {
+    "category": [
+        "前端组件",
+        "通用组件"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": "393727164"
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": ""
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "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"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        }
+      }
+    }
+  }
+}

+ 233 - 0
uni_modules/z-paging/readme.md

@@ -0,0 +1,233 @@
+# z-paging
+
+> 【uni-app自动分页器】超简单,低耦合!仅需两步轻松完成完整分页逻辑(下拉刷新、上拉加载更多),分页全自动处理。支持自定义加载更多的文字或整个view,自定义下拉刷新样式,自动管理空数据view,支持吸顶效果,支持国际化等。
+
+### API文档地址:[http://z-paging.com](http://z-paging.com)
+### 备用API文档地址:[https://www.kancloud.cn/zxlee/z-paging/content](https://www.kancloud.cn/zxlee/z-paging/content) 
+
+### 功能&特点
+
+* 【配置简单】仅需两步(绑定网络请求方法、绑定分页结果数组)轻松完成完整下拉刷新,上拉加载更多功能。
+* 【低耦合,低侵入】分页自动管理。在page中无需处理任何分页相关逻辑,无需在data中定义任何分页相关变量,全由z-paging内部处理。
+* 【超灵活,支持各种类型自定义】支持自定义下拉刷新,自定义上拉加载更多,自带自定义下拉刷新效果,及其他数十种自定义属性。
+* 【功能丰富】支持国际化,支持自定义且自动管理空数据图,支持主题模式切换,支持本地分页,支持聊天分页模式,支持展示最后更新时间,支持吸顶效果,支持内部scroll-view滚动与页面滚动,支持一键滚动到顶部等诸多功能。
+* 【多平台兼容,细致,流畅】支持nvue,支持h5、app及各家小程序;在app-vue、h5、微信小程序、QQ小程序上使用wxs实现下拉刷新,大幅提升性能。多处细节优化,给您精致流畅的体验。
+
+### 反馈qq群(点击加群):[790460711](https://jq.qq.com/?_wv=1027&k=vU2fKZZH)
+
+<p style="font-size:25px;color:red;font-weight:bold">【注意】由V1.9.0起,fixed属性默认值为true,z-paging默认会铺满屏幕。老项目更新请注意,使用侧滑滚动切换选项卡或需要局部使用z-paging请设置:fixed="false"。如果您希望fixed属性默认为false,请参考文档:z-paging.com,将fixed默认值设置为false。</p>
+
+#### 关于自动引入组件
+
+> `z-paging` 支持[easycom组件规范](https://uniapp.dcloud.io/component/README?id=easycom组件规范),无需引用和注册组件即可直接使用,在正在运行的项目中导入`z-paging`可能会提示:`Unknown custom element:<z-paging> - did you register the component corrently?... `,此时需要重新运行项目即可。
+
+### 预览
+
+***
+
+|                 自定义下拉刷新效果+分页演示                  |                      吸顶效果+分页演示                       |
+| :----------------------------------------------------------: | :----------------------------------------------------------: |
+| ![](http://www.zxlee.cn/github/uni-z-paging/uni-z-paging.gif) | ![](http://www.zxlee.cn/github/uni-z-paging/uni-z-paging2.gif) |
+
+|                   滑动切换选项卡+分页演示                    |                    聊天记录模式+分页演示                     |
+| :----------------------------------------------------------: | :----------------------------------------------------------: |
+| ![](http://www.zxlee.cn/github/uni-z-paging/z-paging-demo3.gif) | ![](http://www.zxlee.cn/github/uni-z-paging/z-paging-demo4.gif) |
+
+### 在线demo体验地址:
+
+* [http://www.zxlee.cn/github/uni-z-paging/demo/index.html](http://www.zxlee.cn/github/uni-z-paging/demo/index.html)
+
+| 扫码体验                                                     |
+| ------------------------------------------------------------ |
+| ![](http://www.zxlee.cn/github/uni-z-paging/z-paging-demo.png) |
+
+### 此组件已支持`uni_modules`,下载完整示例时组件在`uni_modules`目录下。
+
+## 基本使用
+
+* ①在`<template>` 中使用@query绑定js中分页请求的方法(`z-paging`会将计算好的pageNo和pageSize两个参数传递到此方法中),然后通过` v-model`绑定列表for循环的list。
+* ②在请求结果回调中,通过调用`z-paging`的`complete()`方法,将请求返回的数组传递给`z-paging`处理,如:`this.$refs.paging.complete(服务器返回的数组);`;若请求失败,调用:`this.$refs.paging.complete(false);`即可。
+* 当tab切换或搜索时,可以通过`this.$refs.paging.reload()`刷新整个列表。
+
+```html
+<template>
+    <view class="content">
+        <z-paging ref="paging" v-model="dataList" @query="queryList">
+            <!-- list数据,建议像下方这样在item外层套一个view,而非直接for循环item,因为slot插入有数量限制 -->
+            <view>
+                <view class="item" v-for="(item,index) in dataList">
+                    <view class="item-title">{{item.title}}</view>
+                </view>
+            </view>
+        </z-paging>
+    </view>
+</template>
+
+<script>
+    export default {
+        data() {
+            return {
+                dataList: [],
+            };
+        },
+        methods: {
+            queryList(pageNo, pageSize) {
+              	//这里的pageNo和pageSize会自动计算好,直接传给服务器即可
+              	//这里的请求只是演示,请替换成自己的项目的网络请求,请在网络请求回调中
+              	//通过this.$refs.paging.complete(请求回来的数组);将请求结果传给z-paging
+                this.$request.queryList(pageNo, pageSize, (data) => {
+                    this.$refs.paging.complete(data);
+                });
+            },
+        },
+    };
+</script>
+
+<style scoped>
+    
+</style>
+```
+
+## 设置自定义emptyView组件示例
+
+* 设置自定义emptyView组件,非必须。空数据时会自动展示空数据组件,不需要自己处理
+
+```html
+<z-paging ref="paging" v-model="dataList" @query="queryList">
+    <!-- 设置自己的emptyView组件,非必须。空数据时会自动展示空数据组件,不需要自己处理 -->
+    <empty-view slot="empty"></empty-view>
+    <view>
+        <view class="item" v-for="(item,index) in dataList">
+            <view class="item-title">{{item.title}}</view>
+        </view>
+    </view>
+</z-paging>
+```
+
+## 自定义加载更多各个状态的描述文字示例
+
+* 以修改【没有更多了】状态描述文字为例(将默认的"没有更多了"修改为"我也是有底线的!")
+
+```html
+<z-paging ref="paging" v-model="dataList" loading-more-no-more-text="我也是有底线的!" @query="queryList">
+    <!-- 设置自己的emptyView组件,非必须。空数据时会自动展示空数据组件,不需要自己处理 -->
+    <view>
+        <view class="item" v-for="(item,index) in dataList">
+            <view class="item-title">{{item.title}}</view>
+        </view>
+    </view>
+</z-paging>
+```
+
+## 自定义下拉刷新view示例
+
+* `use-custom-refresher`需要设置为true(默认为true),此时将不会使用uni自带的下拉刷新,转为使用z-paging自定义的下拉刷新,通过slot可以插入开发者自定义的下拉刷新view。
+
+```html
+<z-paging ref="paging" v-model="dataList" :refresher-threshold="80" @query="queryList">
+  <!-- 自定义下拉刷新view -->
+  <!-- 注意注意注意!!QQ小程序或字节跳动小程序中自定义下拉刷新不支持slot-scope,将导致custom-refresher无法显示 -->
+	<!-- 如果是QQ小程序或字节跳动小程序,请参照demo中的sticky-demo.vue中的写法,此处使用slot-scope是为了减少data中无关变量声明,降低依赖 -->
+	<custom-refresher slot="refresher" slot-scope="{refresherStatus}" :status="refresherStatus"></custom-refresher>
+  <!-- list数据,建议像下方这样在item外层套一个view,而非直接for循环item,因为slot插入有数量限制 -->
+  <view>
+    <view class="item" v-for="(item,index) in dataList" @click="itemClick(item)">
+      <view class="item-title">{{item.title}}</view>
+      <view class="item-detail">{{item.detail}}</view>
+      <view class="item-line"></view>
+    </view>
+  </view>
+</z-paging>
+```
+
+## 自定义加载更多各个状态的描述view示例
+
+* 以修改【没有更多了】状态描述view为例
+
+```html
+<z-paging ref="paging" v-model="dataList" @query="queryList">
+    <view>
+        <view class="item" v-for="(item,index) in dataList">
+            <view class="item-title">{{item.title}}</view>
+        </view>
+    </view>
+    <view style="background-color: red" slot="loadingMoreNoMore">这是完全自定义的没有更多数据view</view>
+</z-paging>
+```
+
+## 使用页面滚动示例
+
+```html
+<!-- 使用页面滚动示例(无需设置z-paging的高度) -->
+<template>
+	<view class="content">
+		<!-- 此时使用了页面的滚动,z-paging不需要有确定的高度,use-page-scroll需要设置为true -->
+		<!-- 注意注意!!这里的ref必须设置且必须等于"paging",否则mixin方法无效 -->
+		<z-paging ref="paging" v-model="dataList" use-page-scroll @query="queryList">
+			<!-- 如果希望其他view跟着页面滚动,可以放在z-paging标签内 -->
+			<!-- list数据,建议像下方这样在item外层套一个view,而非直接for循环item,因为slot插入有数量限制 -->
+			<view>
+				<view class="item" v-for="(item,index) in dataList" :key="index" @click="itemClick(item)">
+					<view class="item-title">{{item.title}}</view>
+					<view class="item-detail">{{item.detail}}</view>
+					<view class="item-line"></view>
+				</view>
+			</view>
+		</z-paging>
+	</view>
+</template>
+
+<script>
+	//使用页面滚动时引入此mixin,用于监听和处理onPullDownRefresh等页面生命周期方法(如果全局引入了,就不要这一步,全局引入示例见main.js)
+	import ZPagingMixin from '@/uni_modules/z-paging/components/z-paging/js/z-paging-mixin'
+	export default {
+		//注意这一步不要漏掉,必须注册mixins(如果全局引入了,就不要这一步,全局引入示例见main.js)
+		mixins: [ZPagingMixin],
+		data() {
+			//参见demo
+		},
+		methods: {
+			//参见demo
+		}
+	}
+</script>
+```
+
+## i18n示例
+
+* 请参照demo:`i18n-demo.vue`
+
+## 性能与建议
+
+|            |                   使用内置scroll-view滚动                    |                         使用页面滚动                         |                           使用nvue                           |
+| :--------: | :----------------------------------------------------------: | :----------------------------------------------------------: | :----------------------------------------------------------: |
+|  **说明**  | 默认模式,`z-paging`需要有确定的高度,下拉刷新与上拉加载更多由`z-paging`内部处理,配置简单。 | `use-page-scroll`设置为true时生效,使用页面滚动而非内置scroll-view滚动,无需固定`z-paging`的高度,但需要在页面滚动到底部时调用`z-paging`的`doLoadMore()`方法。<br>当使用页面的下拉刷新时,需要引入mixin(可全局引入),具体可参见demo。 | 创建nvue页面并引入`z-paging`且运行在APP上生效,`z-paging`将使用nvue独有的`<list>`和`<refresh>`代替原有的scroll-view和自定义的下拉刷新,可大幅提升性能。 |
+|  **性能**  |                             不佳                             |                             一般                             |                              优                              |
+| **优缺点** | 【优点】配置简单、耦合度低。普通的简单列表不会有明显卡顿。<br/>【缺点】需要固定`z-paging`高度,超出页面部分渲染的资源无法自动回收,当列表item比较复杂或数据量过多时,可能会造成明显卡顿。 | 【优点】性能优于使用内置的scroll-view滚动,超出页面部分渲染的资源会自动回收,能适应绝大多数列表滚动的情况,即使列表item比较复杂,一般也不会感知到卡顿。<br>【缺点】配置略麻烦,耦合度较高。 | 【优点】原生渲染,极致性能,`<list>`组件在不可见部分的渲染资源回收有特殊的优化处理,`<refresh>`组件是app端独有的下拉刷新组件,性能远超普通vue页面中的自定义下拉刷新。<br>【缺点】仅App端支持,nvue页面写法不如vue页面方便,在`z-paging`中一些配置和方法在nvue中不支持,且nvue页面中支持的第三方组件也比vue页面少。 |
+
+#### 【总结】
+
+* 如果项目列表item比较简单,分页数据量不是特别多,建议使用默认的「内置scroll-view滚动」。
+* 如果项目列表item比较复杂,数据量多,且使用「内置scroll-view滚动」时卡顿明显,建议使用页面滚动。
+* 如果是App项目,且对性能和细节有较高要求,建议在nvue中使用`z-paging`。
+
+## 注意事项及常见问题
+
+* 【若无法下拉刷新】请确认要在@query所绑定的方法中调用`this.$refs.paging.complete()`,无论是否需要网络请求都要调用,只有告知z-paging刷新状态结束了,才可以开始下次的下拉刷新。
+
+* 【使用内置scroll-view滚动时】z-paging必须有确定的高度!否则上拉加载更多将无法触发,建议设置`:fixed=true`即可不设置高度!!(不希望跟着滚动的view可以设置`slot="top"`)。
+
+* 【使用页面滚动时】使用z-paging内置的scroll-view滚动性能不及使用页面的滚动。若您要使用页面的滚动,请勿固定z-paging的高度,并且必须设置`use-page-scroll`为true,否则将导致页面无法滚动(不希望跟着滚动的view可以设置`slot="top"`)。
+
+* 【使用页面滚动时】必须引入mixin(可全局引入)(具体可参照demo中的`page-default-demo.vue`文件)
+
+  或在页面的`onReachBottom`事件中调用`this.$refs.paging.doLoadMore()`且在`onPageScroll(e)`事件中调用`this.$refs.paging.updatePageScrollTop(e.scrollTop)`。(具体可参照demo中的`page-default-demo.vue`文件)
+
+* 【出现实际上有更多数据,而显示没有更多数据时】默认的pageSize(每页显示数量)为10,如果您服务端不需要传pageSize(例如有默认的pageSize:8),则您需要将默认的pageSize改成您与后端约定好的(8),若没有修改,则z-paging会认为传给服务端的pageSize是10,而服务端只返回了8条,因此会直接判定为没有更多数据。
+
+* 【若页面无法滚动】请检查z-paging是否有固定的高度;若您想使用页面滚动而非z-paging内置的scroll-view的滚动,请设置`use-page-scroll`为true。
+
+* 【关于自定义导航栏】若设置了`:fixed=true`,则必须将自定义导航栏放在z-paging标签中且添加slot="top",如:`<custom-nav slot="top"></custom-nav>`,如果有多个需要固定顶部的元素,则书写`<view slot="top">需要固定顶部的元素</view>`。
+
+### API文档地址:[http://z-paging.com](http://z-paging.com)
+### 备用API文档地址:[https://www.kancloud.cn/zxlee/z-paging/content](https://www.kancloud.cn/zxlee/z-paging/content) 

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff