van-list 分页查询,节流处理(含tabs)

1. 代码环境

vue2 + vant 2 版本
使用的是 van-tabs,van-list  van-pull-refresh 组件

2. 业务需求

如图所示:
1. 点击不同的tabs时进入记录页面,都只显示第一页的数据;
2. 同的tabs,只要是下拉刷新的操作,都只加载和显示第一页的数据;
3. 滚动条向下滚动,只要滚动条的位置距离底部的位置小于offset设置的值,则触发onLoad事件;
4. 需要防止滚动事件频繁处罚,则利用定时器做节流处理
5. 加载完成后显示 finished-text 中的内容 van-list 分页查询,节流处理(含tabs)_第1张图片

3. 父组件(tabs页面)

?为什么没有将van-tab使用循环显示,切只显示一次list,是因为循环后,每个tab对应的查询接口都会调用三次,目前还未解决,所以就每个tab单独写。
原因(自己理解):每次tabs中的内容都会重新触发,且多次循环时也全部加载(多次)

只是单页面分页查询,请点击–>

<template>
  <div class="record">
	<van-tabs v-model="tabsName" sticky color="#409eff" offset-top="96" title-active-color="#409eff" @change="changeTab(tabsName)">
		<van-tab title="过车记录" name="passing">
			<list tabsName="passing" ref="passingChild" :plateNo="plateNo"></list>
		</van-tab>
		<van-tab title="布控记录" name="control">
			<list tabsName="control" ref="controlChild" :plateNo="plateNo"></list>
		</van-tab>
		<van-tab title="违章信息" name="violation">
			<list tabsName="violation" ref="violationChild" :plateNo="plateNo"></list>
		</van-tab>
    </van-tabs>
  </div>
</template>

<script>
import List from '../component/list';
export default {
	name: 'Record',
	components: {
    	List
	},
    data() {
        return {
            showFilter: false,
			tabsName:'passing',
			plateNo: ''
        }
	},
    methods: {
		// tab页切换,调子组件查询方法
		changeTab(tabsName, plateNo) {
			this.tabsName = tabsName;
			this.plateNo = plateNo;
			if (tabsName === 'passing') {
			// 使用this.$refs 调用子组件的方法
				if (this.$refs.passingChild) {
					this.$refs.passingChild.onRefresh();
				}
				return;
			}
			if (tabsName === 'control') {
				if (this.$refs.controlChild) {
					this.$refs.controlChild.onRefresh();
				}
				return;
			}
			if (tabsName === 'violation') {
				if (this.$refs.violationChild) {
					this.$refs.violationChild.onRefresh();
				}
				return;
			}
		},
		// 根据车牌号查询数据
		onSearch(val) {
			this.plateNo = val;
			this.changeTab(this.tabsName, this.plateNo);
		}
    }
}
</script>

4. 子组件

具体实现的逻辑可参考van-list分页加载,代码如下:

<template>
  <div class="record-lists">
    <van-pull-refresh v-model="refreshing" @refresh="onRefresh" success-text="刷新成功">
        <van-list
            v-if="recordList.length"
            v-model="loading"
            :finished="finished"
            :offset="80"
            :immediate-check="false"
            finished-text="没有更多了"
            @load="onLoad"
        >
            <van-cell v-for="item in recordList" :key="item" @click="handleDetail(item)">
                <!-- <van-swipe-cell right-width="80"> -->
                    <div class="record-lists-items">
                        <img :src="getCarImgUrl(item.carImgUrl)" alt="车辆图片">
                        <div class="record-lists-items-content">
                            <div class="info">
                                <span :class="`info-${item.carNumcolor}`">{{ item.carNum }}</span>
                                <span class="info-type" v-if="item.surveyTypeStr"> {{ item.surveyTypeStr }} </span>
                                <span  class="info-type" v-if="item.recTypeStr">{{ item.recTypeStr }}</span>
                            </div>
                            <div class="address-speed">
                                <span> 地点:</span>{{ item.devChnname }}
                            </div>
                                <div class="address-speed">
                                <span>车速:</span>{{ item.carSpeed || 0 }}km/h
                            </div>
                        </div>
                        <div class="record-lists-items-time">{{ item.capDateStr }}</div>
                    </div>
                    <!-- <template #right v-if="tabsName === 'passing'">
                        <van-button class="track-btn" square text="轨迹查询" type="info" @click="trackSearch(item.id)" />
                    </template> -->
                <!-- </van-swipe-cell> -->
            </van-cell>
        </van-list>
        <van-empty description="暂无数据" v-else />
  </van-pull-refresh>
  </div>
</template>

<script>
import api from "../record/factory"
let startDate = dayjs(dayjs().startOf('date')).format('YYYY-MM-DD HH:mm:ss')
let endDate = dayjs(dayjs().endOf('date')).format('YYYY-MM-DD HH:mm:ss')
export default {
     props: {
        tabsName: {
            type: String,
            default: 'passing'
        },
        // 车牌号
        plateNo: {
            type: String,
            default: ''
        },
    },
    data() {
        return {
            recordList: [],
            loading: false,
            finished: false,
            refreshing: false,
            defaultUrl: require('@/assets/img/record/default.png'), //车辆默认占位图
            params: {
                autoCount: 1,
                page: 0,
                plateNo: '',
                rows: 10,
                startDate: `${dayjs(startDate).unix()}`, // 秒级时间戳
                endDate: `${dayjs(endDate).unix()}`
            },
            timer: null
        }
    },
    created() {
        this.onLoad();
    },
    methods: {
        // 获取车牌照片
        getCarImgUrl(url) {
            if (!url) {
                return this.defaultUrl
            }
            let carImgUrl = url === '0' ? this.defaultUrl : `${window.location.origin}/evo-apigw/evo-oss/${url}`;
            return carImgUrl
        },
        onLoad() {
            this.params.plateNo = this.plateNo;
            this.loading = false;
            if(!this.timer) {
                this.timer = setTimeout(() => {
                    this.params.page++;
                    this.getListData();
                    this.timer = null;
                }, 1000)
            }
        },
        // 下拉刷新
        onRefresh() {
            // 清空列表数据
            this.finished = false;
            // 重置页码数和list
            this.params.page = 0;
            this.recordList =  [];
            // 重新加载数据
            // 将 loading 设置为 true,表示处于加载状态
            this.loading = true;
            this.onLoad()
        },
        // 根据tabsName调不同的列表数据
        getListData() {
            switch (this.tabsName) {
                case 'control':
                    this.queryControl(this.params);
                    break;
                case 'violation':
                    this.queryViolation(this.params);
                    break;
                default:
                    this.queryPassing(this.params);
                    break;
            }
        },
        // 查询过车记录
        queryPassing(params) {
            let queryparams = {
                ...this.params,
                maxSpeed: 220,
                minSpeed: 0,
            }
            api.queryPassingRecord({data: queryparams}).then((data) => {
                this.recordList =  this.recordList.concat(data.list);
                this.refreshing = false
                if (this.recordList.length >= data.totalSize) {
                    this.finished = true
                }
            }, (err) => {
                console.log(err);     
            })
        },
        // 查询布控记录
        queryControl() {
            let queryparams = {
                ...this.params,
                surveyType: ""
            }
            api.queryControlRecord({data: queryparams}).then((data) => {
                this.recordList =  this.recordList.concat(data.list);
                this.refreshing = false
                if (this.recordList.length >= data.totalSize) {
                    this.finished = true
                }
            }, (err) => {
                console.log(err);       
            })
        },
        // 查询违章记录
        queryViolation() {
             let queryparams = {
                ...this.params,
                peccancyType: null,
                sortType: "DESC"
            }
            api.queryViolationRecord({data: queryparams}).then((data) => {
                this.recordList =  this.recordList.concat(data.list);
                this.refreshing = false
                if (this.recordList.length >= data.totalSize) {
                    this.finished = true
                }
            }, (err) => {
               console.log(err);
            })
        },
        // 查看详情
        handleDetail(item) {
            this.$router.push({path: '/h5recordDetail', query: {data: item}})
        }
        // 次本版不做轨迹查询
        // trackSearch(id) {
        //     this.$router.push({path: '/h5trackQuery', query: {data: id}})
        // }
    }
}
</script>

<style scoped lang="less">
@grey: #969799;
.record-lists {
    width: 100%;
    height: calc(100% - 145px );
    background: #f9f9f9;
    .van-list__error-text,
    .van-list__finished-text,
    .van-list__loading {
        font-size: 12px;
    }
    &-items {
        display: flex;
        position: relative;
        img {
            width: 60px;
            height: 60px;
        }
        &-content {
            margin-left: 8px;
        }
        &-time {
           position: absolute; 
           right: 0;
           color: @grey;
           font-size: 10px;
        }
    }
    &-items-content {
        .info {
            margin-bottom: 6px;
            font-size: 12px;
            color: #fff;
            // 未识别 其他颜色
            span:nth-of-type(1) {
                display: inline-block;
                min-width: 70px;
                padding: 3px;
                line-height: 18px;
                text-align: center;
                background-repeat: no-repeat;
                background-size: 100%;
                border-radius: 3px;
            }
            &-99,
            &-100  {
                color: #323233;
                background-image: url('~@/assets/img/record/other.png');
            }
            // 蓝色
            &-0 {
                background-image: url('~@/assets/img/record/blue.png');
            }
            // 蓝色
            &-1 {
                background-image: url('~@/assets/img/record/yellow.png');
            }
            &-3 {
                background-image: url('~@/assets/img/record/black.png');
            }
            &-4 {
                background: green;
            }
            // 渐变绿色
            &-5 {
                background-image: url('~@/assets/img/record/green.png');
            }
            &-type {
                display: inline-block;
                min-width: 60px;
                text-align: center;
                color: #1890ff;
                margin-left: 3px;
                padding: 3px 1px;
                line-height: 15px;
                background-color: #e6f7ff;
                border: 1px solid #1890ff;
                border-radius: 3px;
            }
        }
        .address-speed {
            font-size: 12px;
            line-height: 18px;
            span {
                color: @grey;
            }
        }
    }
    .track-btn {
        height: 100%;
    }
}
.van-pull-refresh {
    height: calc(100vh - 145px) !important;
    overflow-y: scroll !important;
}
.van-list {
    height: auto !important;
}
</style>

你可能感兴趣的:(van-list,分页节流,vue.js)