236 lines
5.2 KiB
Vue
236 lines
5.2 KiB
Vue
<template>
|
|
<scroll-view class="list-template-wrapper" :scroll-y="!disableScroll" :refresher-enabled="true"
|
|
:refresher-triggered="refreshTriggered" @refresherrefresh="onRefresh" @scrolltolower="onLoadMore">
|
|
<slot name="top" />
|
|
<view class="list-content" v-if="list.length > 0">
|
|
<view v-for="(item, index) in list" :key="item[idKey]" :class="{ left: index % 2 === 0 }"
|
|
class="flex-column-start news-item" @click="clickCell(item)">
|
|
<slot style="width: 100%" name="item" :data="{
|
|
...item,
|
|
...listExtraFields,
|
|
deleteSelect: !!item.deleteSelect,
|
|
}" />
|
|
</view>
|
|
<uni-load-more v-if="isLoading || (!isLoading && total && total === list.length)"
|
|
:status="isLoading ? 'loading' : 'nomore'"></uni-load-more>
|
|
</view>
|
|
<view v-else class="empty-container">
|
|
<image class="home-ration" mode="widthFix" :src="emptyImage || defaultEmptyImage" />
|
|
<text v-if="emptyText" class="empty-text">{{ emptyText }}</text>
|
|
</view>
|
|
<slot name="bottom" />
|
|
|
|
</scroll-view>
|
|
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
name: "ListPageTemp",
|
|
props: {
|
|
getDataPromise: {
|
|
type: Function,
|
|
},
|
|
// 格式化请求结果的方法
|
|
resultFormatFunc: {
|
|
type: Function,
|
|
},
|
|
requestData: {
|
|
defult: () => { },
|
|
type: Object,
|
|
},
|
|
// 列表元素额外字段
|
|
listExtraFields: {
|
|
type: Object,
|
|
default: () => { },
|
|
},
|
|
reloadFlag: {
|
|
default: 0,
|
|
type: Number,
|
|
},
|
|
// 是否分页
|
|
isPagiantion: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
// 分页数量, 不分页时有效
|
|
pageSize: {
|
|
type: Number,
|
|
default: 999,
|
|
},
|
|
defaultList: {
|
|
type: Array,
|
|
default: () => [],
|
|
},
|
|
disableScroll: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
idKey: {
|
|
type: String,
|
|
default: "id",
|
|
},
|
|
// 占位图片地址
|
|
emptyImage: {
|
|
type: String,
|
|
default: "",
|
|
},
|
|
// 空状态文本(传入时才显示)
|
|
emptyText: {
|
|
type: String,
|
|
default: "",
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
isLoading: false,
|
|
total: 0,
|
|
list: [],
|
|
refreshTriggered: false,
|
|
p: 1,
|
|
num: 10,
|
|
defaultEmptyImage: 'https://activity.wagoo.live/empty.png', // 默认占位图片
|
|
};
|
|
},
|
|
|
|
watch: {
|
|
reloadFlag: {
|
|
handler(value) {
|
|
if (value) {
|
|
this.p = 1;
|
|
this.num = 10;
|
|
this.list = [];
|
|
this.total = 0;
|
|
this.getList();
|
|
}
|
|
},
|
|
immediate: true,
|
|
},
|
|
requestData: {
|
|
handler(data) {
|
|
if (data) {
|
|
this.p = 1;
|
|
this.num = 10;
|
|
this.list = [];
|
|
this.total = 0;
|
|
this.getList();
|
|
}
|
|
},
|
|
deep: true,
|
|
},
|
|
defaultList: {
|
|
handler(list) {
|
|
this.list = list;
|
|
this.$forceUpdate();
|
|
},
|
|
immediate: true,
|
|
},
|
|
},
|
|
methods: {
|
|
onRefresh() {
|
|
if (this.refreshTriggered) return;
|
|
this.refreshTriggered = true;
|
|
this.p = 1;
|
|
this.num = 10;
|
|
// this.list = [];
|
|
this.total = 0;
|
|
this.getList();
|
|
},
|
|
|
|
onLoadMore() {
|
|
if (!this.isPagiantion) {
|
|
return;
|
|
}
|
|
if (!this.isLoading && this.total > this.list.length) {
|
|
this.p++;
|
|
this.getList();
|
|
}
|
|
},
|
|
clickCell(item) {
|
|
this.$emit("clickCell", item);
|
|
},
|
|
getList() {
|
|
if (this.isLoading) return;
|
|
this.isLoading = true;
|
|
|
|
// TODO: 删除测试数据
|
|
if (!this.getDataPromise) {
|
|
this.list = [0, 1, 2, 3, 4, 5, 6].map((v, k) => {
|
|
return {
|
|
title: "消息名称0000sssss撒大苏打大苏打" + v,
|
|
id: k,
|
|
len: 10,
|
|
};
|
|
});
|
|
this.total = 9;
|
|
this.isLoading = false;
|
|
this.refreshTriggered = false;
|
|
uni.stopPullDownRefresh();
|
|
return;
|
|
}
|
|
|
|
const data = Object.assign(
|
|
{},
|
|
{ p: this.p, num: !this.isPagiantion ? this.pageSize : this.num },
|
|
this.requestData
|
|
);
|
|
this.getDataPromise(data)
|
|
.then((res) => {
|
|
const list =
|
|
this.p === 1
|
|
? res?.data || []
|
|
: [...this.list, ...(res?.data || [])];
|
|
this.list = this.resultFormatFunc
|
|
? this.resultFormatFunc(list)
|
|
: list;
|
|
this.total = res?.count || 0;
|
|
this.$emit("getList", this.list, res);
|
|
// console.log(this.list,'???')
|
|
})
|
|
.finally(() => {
|
|
this.isLoading = false;
|
|
this.refreshTriggered = false;
|
|
uni.stopPullDownRefresh();
|
|
});
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.list-template-wrapper {
|
|
height: 100%;
|
|
width: 100%;
|
|
|
|
.list-content {
|
|
width: 100%;
|
|
}
|
|
|
|
.news-item {
|
|
width: 100%;
|
|
}
|
|
|
|
.empty-container {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin: 400rpx auto 0;
|
|
padding: 0 40rpx;
|
|
}
|
|
|
|
.home-ration {
|
|
width: 160px;
|
|
height: 174px;
|
|
display: block;
|
|
margin-bottom: 24rpx;
|
|
}
|
|
|
|
.empty-text {
|
|
font-size: 28rpx;
|
|
color: #999;
|
|
text-align: center;
|
|
}
|
|
}
|
|
</style>
|