vant list refresh 二次封装
组件:
<template>
<div>
<van-pull-refresh v-model="refreshing" @refresh="onRefresh" :disabled="disabled" :style="fullScreen? 'min-height: 100vh;': ''">
<van-list
v-model="loading"
:finished="finished"
:finished-text="finishedText"
error-text="请求失败,点击重新加载"
@load="onLoad"
:immediate-check="immeCheck"
>
<slot></slot>
<div v-if="noData" class="no-data-cont" :class="noDataClass">
<!-- 暂无数据图片展示 -->
<img :src="noDateIcon" alt="">
<p>{{searchInput ? '没有查询到任何内容':'- 暂无数据 -'}}</p>
</div>
<div slot="finished" class="finished-data">
<p v-if="!noData">{{ finishedText }}</p>
</div>
</van-list>
</van-pull-refresh>
</div>
</template>
<script>
export default {
props: {
immeCheck: {
type: Boolean,
default: false
},
searchInput: {
type: String,
default: ''
},
fullScreen: { // 是否需要让下拉区域始终为全屏
type:Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
},
noDataClass: {
type: String,
default: ''
},
finishedText: {
type: String,
default: '没有更多了'
}
},
data () {
return {
refreshing: false,
loading: false,
finished: false,
noData: false,
noDateIcon: require('@/assets/common/page-empty.png'),
len: 0,
total: 0
}
},
methods: {
// 刷新加载完成
onRefreshSuc () {
this.refreshing = false
this.finished = false
},
onRefresh () {
setTimeout(() => {
this.$emit('onRefreshList')
}, 500)
},
// true false 是否全部加载完成
// onLoadSuc (isOver) {
// this.loading = false
// this.finished = isOver
// },
// len 已加载数据 total 总数据
onLoadSuc(len, total) {
this.loading = false
this.len = len
this.total = Number(total)
if (Number(total) > 0) {
this.noData = false
if (len < Number(total)) {
this.finished = false
} else {
this.finished = true
}
} else {
this.finished = true
this.noData = true
}
},
onLoad () {
setTimeout(() => {
if (this.len < this.total) {
this.$emit('onLoadMore')
} else {
this.finished = true
}
}, 500)
}
}
}
</script>
<style lang="scss" scoped>
/deep/ .van-pull-refresh {
// overflow: visible!important;
}
.data-none {
font-size: .2rem;
color: #888888;
line-height: .4rem;
}
.finished-data {
p:nth-child(2) {
text-align: center;
color: #969799;
font-size: .28rem;
}
}
.no-data-cont {
// height: 4rem;
min-height: 4rem;
width: 100%;
padding-top: 0.3rem;
text-align: center;
img {
// display: block;
// margin: 0 auto;
display: inline-block;
height: 3rem;
width: 3rem;
}
p {
text-align: center;
color: #969799;
font-size: .28rem;
}
}
.no-h-data-cont {
height: auto;
img {
display: block;
margin: 0 auto;
height: auto;
width: auto;
}
}
</style>
使用:
<template>
<div>
<div class="panel-title">
<div class="left-avatar">
<img :src="userInfo.avatar || defaultAvatar" alt="" />
<span v-if="userInfo.gender == 1" class="gender-icon">
<svg-icon icon-class="nan"></svg-icon>
</span>
<span v-if="userInfo.gender == 2" class="gender-icon">
<svg-icon icon-class="ru"></svg-icon>
</span>
</div>
<div class="left-info">
<div class="nickname">
<span>{{ userInfo.title || '-' }}</span>
</div>
<div class="info">
<span>{{ userInfo.age || '-' }}岁</span>
<span></span>
<span>{{ userInfo.phone || '-' }}</span>
</div>
</div>
</div>
<LoadMore
class="loadMore"
key="ehbList"
@onRefreshList="onRefreshList"
@onLoadMore="onLoadMore"
ref="loadMoreCont"
>
<div class="userItem" v-for="(item, index) in list" :key="index">
<div class="item-top">
<van-image
class="item-top-left-avatar"
round
:src="item.customerHeadImg || defaultAvatar"
/>
<p class="item-top-left-name">{{ item.customerName }}</p>
</div>
<div class="item-bottom">
<div class="item-bottom-content">
<span class="label">添加时间</span>
<span class="value">2023-10-19 17:37:45</span>
</div>
<div class="item-bottom-content">
<span class="label">所属部门</span>
<span class="value">产品部、技术部、测试部共3个部门</span>
</div>
</div>
</div>
</LoadMore>
</div>
</template>
<script>
import LoadMore from '@/components/loadMore/index'
export default {
name: 'friends',
components: {
LoadMore
},
data() {
return {
userInfo: {},
defaultAvatar: require('@/assets/qwGuide/headportrait.png'),
pageNum: 1,
pageSize: 10,
list: [
{
customerName: '张三'
},
{
customerName: '张三'
},
{
customerName: '张三'
},
{
customerName: '张三'
},
{
customerName: '张三'
},
{
customerName: '张三'
}
]
}
},
created() {
// this.getList()
},
methods: {
getList() {
const params = {
pageNum: this.pageNum,
pageSize: this.pageSize
}
this.$toast.loading({
message: '加载中...',
forbidClick: true,
duration: 0
})
// receiveRecordPageList(params).then(res => {
// this.$toast.clear()
// if (this.$refs.loadMoreCont) this.$refs.loadMoreCont.onRefreshSuc()
// if (this.pageNum == 1) {
// this.list = res.data.list || []
// } else {
// this.list = this.list.concat(res.data.list || [])
// }
// if (this.$refs.loadMoreCont) this.$refs.loadMoreCont.onLoadSuc(this.list.length, res.data.total)
// }).catch(() => {
// this.$toast.clear()
// })
},
onRefreshList() {
this.pageNum = 1
this.getList()
},
onLoadMore() {
this.pageNum++
this.getList()
}
}
}
</script>
<style lang="scss" scoped>
.panel-title {
background: #ffffff;
border-radius: 0px 0px 0.08rem 0.08rem;
padding: 0.48rem 0.32rem 0.32rem;
display: flex;
align-items: center;
.left-avatar {
position: relative;
width: 0.88rem;
height: 0.88rem;
margin-right: 0.16rem;
img {
width: 100%;
height: 100%;
border-radius: 50%;
}
.gender-icon {
position: absolute;
display: block;
width: 0.28rem;
height: 0.28rem;
line-height: 0.28rem;
bottom: 0;
right: 0;
border-radius: 50%;
// background: #165DFF;
}
.boy-class {
background: #165dff;
border-radius: 50%;
}
.girl-class {
background: #f77234;
}
}
.left-info {
height: 0.88rem;
.nickname {
display: flex;
align-items: center;
span {
max-width: 2.56rem;
font-size: 0.32rem;
font-weight: 700;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
/deep/ .van-rate__item:not(:last-child) {
padding-right: 0.04rem;
}
}
.info {
display: flex;
align-items: center;
font-size: 0.24rem;
margin-top: 0.08rem;
color: #c9cdd4;
span:nth-child(2) {
width: 1px;
height: 0.24rem;
background-color: #86909c;
margin: 0 0.16rem;
}
}
}
}
.loadMore {
height: calc(100vh - 1.68rem);
overflow: hidden;
/deep/ {
.van-pull-refresh {
height: calc(100vh - 1.68rem)!important;
overflow: auto;
}
}
}
.userItem {
padding: 0.32rem;
margin: 0.24rem;
display: flex;
flex-direction: column;
background: #ffffff;
border-radius: 0.08rem;
position: relative;
.item-top {
display: flex;
align-items: center;
gap: 0.16rem;
margin-bottom: 0.24rem;
.item-top-left-avatar {
width: 0.64rem;
height: 0.64rem;
flex-shrink: 0;
}
.item-top-left-name {
font-size: 0.32rem;
line-height: 0.44rem;
color: #1d2129;
font-weight: 500;
}
}
.item-bottom {
display: flex;
flex-direction: column;
gap: 0.16rem;
line-height: 0.32rem;
font-size: 0.28rem;
.item-bottom-content {
display: flex;
word-break: break-all;
gap: 0.16rem;
}
.label {
color: #86909c;
width: 1.68rem;
flex-shrink: 0;
}
.value {
color: #4e5969;
}
}
}
</style>

浙公网安备 33010602011771号