目录
一、Picker 选择器
1.1、数组对象处理
1.2、每个选项颜色设置
二、滚动分页加载列表
三、Calendar 日历(可选范围限制)
四、input值过滤
官网:Vant 2 - Mobile UI Components built on Vue
一、Picker 选择器
官网示例数据:
columns: ['杭州', '宁波', '温州', '绍兴', '湖州', '嘉兴', '金华', '衢州'],
1.1、数组对象处理
一般接口返回格式是数组对象,在项目中van-picker的数组如果含有对象,则需要包含 text 属性用于显示的文本、value 属性作为选择器的值,如果接口返回的结果中属性名和我们期望的不一样,就自己map设置一下。
<template>
<van-field
v-model="segmentSign.text"
clearable
label="所属列表"
placeholder="点击选择所属列表"
>
<template #right-icon>
<van-icon name="arrow" @click="showPicker = true" />
</template>
</van-field>
<!-- 复杂数组的选择器 -->
<van-popup v-model="showPicker" position="bottom" :lazy-render="false">
<van-picker
show-toolbar
:columns="segmentList"
@confirm="onConfirm"
@cancel="showPicker = false"
>
</van-picker>
</van-popup>
</template>
<script>
data() {
showPicker: false,
segmentList: [],
segmentSign: {},
};
},
methods: {
onConfirm(val) {
this.segmentSign = val;
this.showPicker = false;
},
async getDepartList() {
let res = await findDepartList();
if (res.data.code == 200) {
let data = res.data.result || [];
if (data.length > 0) {
let result = data.map((item) => {
let res = {};
res.text = item.deptName;
res.value = item.deptId;
res.teacherId = item.teacherId;
return res;
});
this.segmentList = result;
if (this.segmentList && this.segmentList.length > 0) {
this.segmentSign = this.segmentList[0];
}
}
} else {
Toast(res.data.message);
}
},
}
</script>
1.2、每个选项颜色设置
#option="option"里面放个div,是为了让每一行的样式可以自己设置,也可以加更多内容!
<template>
<van-picker
:columns="columns"
ref="van_picker"
:default-index="StatusVal.status"
@change="PickerChange"
>
<template #option="option">
<div
style="display: flex; flex-direction: column; align-items: center"
>
<div :style="'color:' + colorType(option.id)">
{{ option.value }}
</div>
</div>
</template>
</van-picker>
</template>
<script>
data() {
columns: [
{ id: 0, value: "出勤" },
{ id: 1, value: "迟到" },
{ id: 2, value: "旷课" },
{ id: 3, value: "早退" },
{ id: 4, value: "请假" },
],
StatusVal: {},
selectId: "",
};
},
methods: {
// picker选项改变
PickerChange(val, index) {
this.selectId = index.id;
},
colorType(index) {
const colors = ["#6BC25E", "#F0A55C", "#E77575", "#F0A55C", "#6FBFF1"];
return colors[index] || "";
},
}
</script>
列表默认值属性 :default-index结合setIndexes才能将默认值修改自己想要的结果
this.$nextTick(() => {
this.$refs.van_picker.setIndexes([this.StatusVal.status]); // 注意这里是数组[索引值]
});
二、滚动分页加载列表
页面初始化时加载初始列表方法,随着页面向下滚动和刷新,页面递增,此时发送请求,获取下一页数据,这个适用于vue2,只需要换成自己的接口和循环组件即可!
<template>
<!-- 下拉刷新 -->
<van-pull-refresh v-model="isLoading" @refresh="onRefresh">
<!-- 列表 -->
<van-list
v-if="valueLists.length > 0"
v-model="loading"
:finished="finished"
finished-text="没有更多了"
:immediate-check="false"
offset="50"
@load="onLoad"
>
<group-items
v-for="(item, index) in valueLists"
:key="index"
:infoItems="item"
></group-items>
</van-list>
<van-empty
image-size="150"
v-else
:image="
require('../../../../static/images/courseSelection/wu.png')
"
description="暂无数据"
class="empty"
/>
<!-- end -->
</van-pull-refresh>
</template>
<script>
data() {
return {
finished: false,
loading: false,
isLoading: false,
valueLists: [],
pageNum: 1,
pageSize: 10,
pages: 0,
};
},
created() {
this.findRecordPageFun();
},
methods: {
// 下拉刷新
onRefresh() {
// 重置页码
this.pageNum = 1;
// 重置刷新状态
this.finished = false;
this.loading = false;
// 请求列表
this.findRecordPageFun();
},
// 加载更多
onLoad() {
this.findRecordPageMore();
},
// 获取初始列表
findRecordPageFun() {
let params = {
pageNo: this.pageNum,
pageSize: this.pageSize,
};
this.invokeApi(findRecordPage, params).then((res) => {
if (res.data.code == 200) {
this.valueLists = res && res.data.result.records;
this.pages = res && res.data.result.pages;
if (this.isLoading) return (this.isLoading = false);
} else {
Toast(res.data.message);
this.valueLists = [];
this.pages = 0;
this.pageNum = 1;
this.finished = false;
this.loading = false;
}
});
},
async findRecordPageMore() {
// 请求页码+1
let finePage = this.pageNum + 1;
// 判断页码极限
if (finePage > this.pages) return (this.finished = true);
let params = {
pageNo: this.pageNum,
pageSize: this.pageSize,
};
this.invokeApi(findRecordPage, params).then((res) => {
if (res.data.code == 200) {
this.pages = res.data.result.pages;
this.valueLists.push(...res.data.result.records);
this.pageNum = finePage;
this.loading = false;
} else {
Toast(res.data.message);
this.valueLists = [];
this.pages = 0;
this.pageNum = 1;
this.finished = false;
this.loading = false;
}
});
},
}
</script>
三、Calendar 日历(可选范围限制)
<template>
<van-field
v-model="times"
readonly
clearable
placeholder="点击选择日期"
class="custom-field"
>
<template #right-icon>
<van-icon name="arrow" @click="showDate = true" />
</template>
</van-field>
<!-- 日历 -->
<van-calendar
v-model="showDate"
@confirm="dateConfirm"
color="#1989fa"
:min-date="minDate"
:max-date="maxDate"
/>
</template>
<script>
data() {
return {
times:'',
showDate: false,
minDate: this.getStartOfWeek(new Date()),
maxDate: this.getEndOfWeek(new Date()),
};
},
methods: {
getStartOfWeek(date) {
const day = date.getDay();
const diff = date.getDate() - day + (day === 0 ? -6 : 1);
return new Date(date.setDate(diff));
},
getEndOfWeek(date) {
const startOfWeek = this.getStartOfWeek(date);
const endOfWeek = new Date(startOfWeek);
endOfWeek.setDate(endOfWeek.getDate() + 6);
return endOfWeek;
},
dateConfirm(time) {
const date = new Date(time);
const year = date.getFullYear();
const month = (date.getMonth() + 1).toString().padStart(2, "0");
const day = date.getDate().toString().padStart(2, "0");
this.times = `${year}-${month}-${day}`;
this.showDate = false;
},
}
</script>
场景介绍:
点击field栏,选择本周时间,选中后将值回显(minDate和maxDate在方法里限制了范围,在确定事件里整理格式,然后赋值给field栏绑定的值)
四、input值过滤
为啥不用 v-model.trim="xx",因为它只能过滤头部和尾部的空格,而不能过滤中间的,所以自己再写了个方法。
<van-search
v-model="searchValue"
placeholder="请输入姓名"
show-action
@input="trimLR"
>
<template #action>
<div @click="getCheckList">搜索</div>
</template>
</van-search>
// 过滤空格
trimLR() {
this.searchValue = this.searchValue.replace(/\s+/g, "");
},