创建 ListMoreDataMixin
// 由于没有超类的限制这里要判断下
function ____checkGetData(context) {
if (!context.getData || typeof context.getData !== "function") {
throw new Error("使用[ListMoreDataMixin]必须实现getData函数");
}
}
export const ListMoreDataMixin = {
data() {
return {
listData: [], // 数据列表
page: 1, // 1
limit: 10,
isLoading: false, // 是否在加载数据
isRefresh: false, // 下拉刷新
autoInitListData: true,
};
},
methods: {
// 初始化数据
async initData() {
____checkGetData(this);
this.page = 1;
this.isLoading = true;
const data = await this.getData();
this.listData = data;
this.isLoading = false;
},
// 上拉加载更多
async loadMore() {
____checkGetData(this);
this.isLoading = true;
this.page += 1;
const data = await this.getData();
// 没有更多了
if (!data || !data.length) {
this.page--;
if (this.notMoreData) {
this.notMoreData?.();
} else {
uni.showToast({
title: "到底了...",
icon: "none",
});
}
}
this.listData = [...this.listData, ...data];
this.isLoading = false;
},
// 下拉刷新
async onRefresh(done) {
____checkGetData(this);
this.isRefresh = true;
await this.initData();
this.isRefresh = false;
if (done && typeof done === "function") done();
},
},
mounted() {
if (this.autoInitListData) this.initData();
},
};
在组件中使用
<template>
<scroll-view
v-if="listData.length"
:scroll-y="true"
:scroll-with-animation="true"
:refresher-enabled="true"
:refresher-triggered="isRefresh"
@refresherrefresh="onRefresh"
@scrolltolower="loadMore"
>
<list-item v-for="item of listData" :key="item.id" :data="item" />
</scroll-view>
</template>
<script>
import { ListMoreDataMixin } from 'list-more-data-mixin.js';
export default {
mixins: [ListMoreDataMixin],
methods: {
// 必须实现
async getData() {
return this.api.get("/api/xxx", { page: this.page, limit: this.limit });
},
}
};
</script>
长列表
创建 LongListMoreDataMixin
// 由于没有超类的限制这里要判断下
function ____checkGetData(context) {
if (!context.getData || typeof context.getData !== "function") {
throw new Error("使用[LongListMoreDataMixin]必须实现getData函数");
}
}
export const LongListMoreDataMixin = (manage) => {
const PAGE = 1;
const LIMIT = 20;
return {
data() {
return {
sections: [],
page: PAGE,
limit: LIMIT,
isLoading: false, // 是否在加载数据
isRefresh: false, // 下拉刷新
autoInitListData: true,
};
},
methods: {
// 初始化数据
async initData() {
____checkGetData(this);
this.page = PAGE;
this.isLoading = true;
this._list = manage.clear();
this.sections = [];
const data = await this.getData();
this._appendData(data);
this.isLoading = false;
},
// 上拉加载更多
async loadMore() {
____checkGetData(this);
this.isLoading = true;
this.page += 1;
const data = await this.getData();
// 没有更多了
if (!data || !data.length) {
this.page--;
if (this.notMoreData) {
this.notMoreData?.();
} else {
uni.showToast({
title: "到底了...",
icon: "none",
});
}
}
this._appendData(data);
this.isLoading = false;
},
// 下拉刷新
async onRefresh(done) {
____checkGetData(this);
this.isRefresh = true;
await this.initData();
this.isRefresh = false;
if (done && typeof done === "function") done();
},
_addSection(data) {
if (!data.length) return;
this.sections.push({
begin: this._list.length - data.length,
end: this._list.length
})
},
_appendData(data) {
this._list.push(...data);
this._addSection(data);
}
},
mounted() {
if (this.autoInitListData) this.initData();
},
};
}
组件中将你的列表分段
<template>
<view>
<my-section v-for="(item, index) in sections" :key="index" :section="item"></my-section>
</view>
</template>
<script>
import manage from './list-manage';
import { LongListMoreDataMixin } from './LongListMoreDataMixin.js';
export default {
mixins: [LongListMoreDataMixin(manage)],
onPullDownRefresh() {
this.onRefresh(() => {
uni.stopPullDownRefresh();
});
},
onReachBottom() {
this.loadMore();
},
methods: {
getData() {
return new Promise(_res => {
this.request({
page: this.page,
size: this.limit,
success: res => {
_res(res);
}
});
});
}
}
};
</script>
my-section:
<template>
<my-item v-for="(item, index) in list" :key="index" :data="item"></my-item>
</template>
<script>
import manage from './list-manage';
export default {
props: ['section'],
data() {
return {
list: []
};
},
created() {
this.list = manage.getSection(this.section);
}
};
</script>
<style></style>
在 list-manage.js
中导出静态列表,和一些管理函数
const manage = {
list: [],
clear() {
return manage.list = []
},
getSection(section) {
return manage.list.slice(section.begin, section.end);
}
}
export default manage;