因为项目使用到了nvue经过一系列的碰壁和研究,写一下总结
下面是封装list的组件
template部分
<template>
<list class="list-wrap" :loadmoreoffset="loadmoreoffset" @loadmore="scrolltolower">
<header>
<slot name="top"></slot>
</header>
<cell v-for="(item, index) in list" :key="index">
<slot :item="item"></slot>
</cell>
<cell>
<slot name="loading">
<u-loadmore v-if="statusRef" :status="statusRef" line @loadmore="scrolltolower"></u-loadmore>
<u-empty v-else mode="list" height="280" marginTop="50"></u-empty>
</slot>
</cell>
</list>
</template>
setup部分
import { computed, ref, onMounted, reactive } from 'vue';
const props = defineProps({
// limit为0时不分页
limit: {
type: [String, Number],
default: 8,
},
// 初始化 不获取数据
initNoFetchList: {
type: Boolean,
default: false
},
height: {
type: [String, Number],
default: 0,
},
loadmoreoffset: {
type: [String, Number],
default: 100,
}
})
const emits = defineEmits(['getList']);
const pagination = reactive({
page: 1,
pageSize: props.limit,
total: 0,
});
const list = ref([]);
onMounted(async () => {
if (props.initNoFetchList) return;
setTimeout(async () => {
fetchList(); // 发送请求
}, 1000);
});
const loadingRef = ref(true);
const finishedRef = computed(() => (pagination.page * pagination.pageSize >= pagination.total));
const emptyRef = computed(() => (pagination.total === 0));
const statusRef = computed(() => {
console.log("finishedRef.value", loadingRef.value, emptyRef.value, finishedRef.value)
if (loadingRef.value) return 'loading';
else if (emptyRef.value) return '';
else if (finishedRef.value) return 'nomore';
else return 'loadmore';
});
const fetchList = (refresh = false) => {
if (refresh) {
pagination.page = 1;
}
loadingRef.value = true;
emits('getList', { // 把请求参数抛出去,并使用callback在组件中处理
params: {
pageNo: pagination.page,
pageSize: pagination.pageSize, // limit == 0 不分页
},
callback: (res) => {
loadingRef.value = false;
if (refresh) {
list.value = [];
}
list.value.push(...res.records);
pagination.total = res.total;
}
});
}
const scrolltolower = () => {
if (finishedRef.value) return;
pagination.page++;
fetchList();
}
const refreshList = () => {
fetchList(true);
}
defineExpose({
refreshList,
});
组件的使用
<ListNvue class="hf-list-page" ref="hflistRef" @getList="getList" :limit="20">
<template #top>
<view class="static-wrap">
<view class="search">
<u-search bgColor="rgb(50,144,252)" color="#FFFFFF" :clearabled="false" searchIconColor="#FFFFFF"
placeholderColor="rgba(255,255,255, 0.5)" v-model="keyWords" :showAction="false"
placeholder="请输搜索内容" @search="refresh"></u-search>
</view>
</view>
</template>
<template v-slot="{ item }">
<text>{{ item.name }}</text>
</template>
</ListNvue>
setup部分
import ListNvue from '@/components/hf-list/list-nvue.vue'
import {
computed,
onMounted,
reactive,
ref
} from 'vue'
const keyWords = ref('')
const hflistRef = ref(null);
const refresh = () => {
hflistRef.value && hflistRef.value.refreshList(true)
}
async function getList({
params,
callback
}) {
const res = await queryPageList({ // 发送api
keyword: keyWords.value,
...params,
});
callback({
total: res.total, // 总页数
records: res.records.map((item, index) => { // 在这里可以过滤一些不要的参数
return {
...item
}
})
});
}
上述下拉刷新未实现,后续进行补充
参考官网文档:https://uniapp.dcloud.net.cn/component/list.html#list