目录
一、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-fieldv-model="segmentSign.text"clearablelabel="所属列表"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-pickershow-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"><divstyle="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-listv-if="valueLists.length > 0"v-model="loading":finished="finished"finished-text="没有更多了":immediate-check="false"offset="50"@load="onLoad"><group-itemsv-for="(item, index) in valueLists":key="index":infoItems="item"></group-items></van-list><van-emptyimage-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() {// 请求页码+1let 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-fieldv-model="times"readonlyclearableplaceholder="点击选择日期"class="custom-field"><template #right-icon><van-icon name="arrow" @click="showDate = true" /></template></van-field><!-- 日历 --><van-calendarv-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-searchv-model="searchValue"placeholder="请输入姓名"show-action@input="trimLR"><template #action><div @click="getCheckList">搜索</div></template></van-search>// 过滤空格trimLR() {this.searchValue = this.searchValue.replace(/\s+/g, "");},