vant组件二次封装-下拉刷新列表组件
一,二次封装的组件代码<template><van-pull-refreshv-model="refreshing"@refresh="onRefresh"success-text="已为您刷新成功"><van-listv-model:loading="myLoading":finished="finished"finished-text="没有更多了"@load="
·
一,二次封装的组件代码
<template>
<van-pull-refresh
v-model="refreshing"
@refresh="onRefresh"
success-text="已为您刷新成功"
>
<van-list
v-model:loading="myLoading"
:finished="finished"
finished-text="没有更多了"
@load="onLoad"
>
<div class="item-list" v-for="item in list" :key="item">
<slot :item="item"></slot>
</div>
<img
src="@/assets/img/empty.png"
alt=""
class="empty-image"
v-if="list.length === 0"
/>
</van-list>
</van-pull-refresh>
</template>
<script setup>
import { ref, computed } from 'vue';
let emits = defineEmits([
'update:loading',
'update:finished',
'update:pageCurrent',
'update:pageSize',
'getList'
]);
let props = defineProps({
loading: {
type: Boolean,
require: true,
default: false
},
finished: {
type: Boolean,
require: true,
default: false
},
list: {
type: Array,
require: true,
default: () => []
},
pageCurrent: {
type: Number,
require: true,
default: 1
},
pageSize: {
type: Number,
require: true,
default: 10
}
});
const refreshing = ref(false);
let timeout;
const myLoading = computed({
get: () => props.loading,
set: val => {
emits('update:loading', val);
}
});
//加载
const onLoad = () => {
if (refreshing.value) {
refreshing.value = false;
emits('update:finished', false);
emits('update:loading', true);
emits('update:pageCurrent', 1);
}
emits('getList');
};
//防抖处理,1s内只能下拉刷新一次
const onRefresh = () => {
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(onLoad, 1000);
};
</script>
<style lang="scss" scoped>
.van-pull-refresh {
min-height: calc(100vh - 90px);
:deep().van-pull-refresh__track {
min-height: calc(100vh - 90px);
}
:deep() .van-pull-refresh__head {
color: #8d8c8c;
}
:deep() .van-loading__text {
color: #8d8c8c;
}
:deep() .van-loading__circular,
.van-loading__text {
color: #8d8c8c;
}
}
.empty-image {
margin-top: 50px;
width: 50%;
}
</style>
二,父组件的使用
<template>
<div class="order-box">
<VantRefresh
v-model:pageCurrent="pageCurrent"
v-model:pageSize="pageSize"
v-model:loading="loading"
v-model:finished="finished"
:list="list"
@getList="getList"
>
<template #default="slotProps">
<OrderListItem :item="slotProps.item"></OrderListItem>
</template>
</VantRefresh>
</div>
</template>
<script setup>
import OrderListItem from './componcents/OrderListItem.vue';
import VantRefresh from '@/componcents/vant-refresh/VantRefresh.vue';
import { ref, onActivated } from 'vue';
import { httpPost } from '@/vue-use/useHttp.js';
const pageCurrent = ref(1); //当前页
const pageSize = ref(10); //每页个数
const list = ref([]); //数据列表
const loading = ref(false); //开启加载
const finished = ref(false); //已经到底了
//获取列表数据
async function getList() {
let params = {
TXCODE: 'STN011',
pageCurrent: pageCurrent.value,
pageSize: pageSize.value
};
const res = await httpPost(params);
const orderList = res.data.orderList;
if (pageCurrent.value === 1) {
list.value = orderList;
} else {
list.value = list.value.concat(orderList);
}
console.log('我的订单列表', list.value);
loading.value = false;
pageCurrent.value++;
if (res.data.orderList.length < pageSize.value) {
finished.value = true;
}
}
</script>
<style lang="scss" scoped>
.order-box {
height: calc(100vh - 90px);
padding-bottom: 180px;
box-sizing: border-box;
overflow: scroll;
}
</style>
三,解析
主要是用到这三个知识点
1,v-model:bindName
属性绑定,然后子组件props接收后,要要修改父组件的值,只需要emits(‘update:finished’, newValue)即可。无需再父组件中再调用函数。
2,computed的set函数
为了避免子组件自动变更props的值,通过computed进行一次转化,利用set函数变更父组件中的值。
3,作用域插槽
这里是父组件把list传给子组件使用,子组件又把list的item绑定到插槽上,提供给父组件使用。
更多推荐
所有评论(0)