vue2 + vant 2 版本
使用的是 van-tabs,van-list 和 van-pull-refresh 组件
如图所示:
1. 点击不同的tabs时进入记录页面,都只显示第一页的数据;
2. 同的tabs,只要是下拉刷新的操作,都只加载和显示第一页的数据;
3. 滚动条向下滚动,只要滚动条的位置距离底部的位置小于offset设置的值,则触发onLoad事件;
4. 需要防止滚动事件频繁处罚,则利用定时器做节流处理
5. 加载完成后显示 finished-text 中的内容
?为什么没有将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>
具体实现的逻辑可参考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>