基于Vant UI框架實(shí)現(xiàn)時(shí)間段選擇器
本文實(shí)例為大家分享了Vant UI框架實(shí)現(xiàn)時(shí)間段選擇器的具體代碼,供大家參考,具體內(nèi)容如下
組件代碼如下:
<template>
<van-picker
:title="title"
:show-toolbar="showToolbar"
:columns="columns"
@confirm="onConfirm"
@cancel="onCancel"
@change="onChange"
:confirm-button-text="confirmButtonText"
:cancel-button-text="cancelButtonText"
:loading="loading"
:readonly="readonly"
:item-height="itemHeight"
:visible-item-count="visibleItemCount"
:swipe-duration="swipeDuration"
>
<template slot="default">
<slot name="default"></slot>
</template>
<template slot="title">
<slot name="title"></slot>
</template>
<template slot="confirm">
<slot name="confirm"></slot>
</template>
<template slot="cancel">
<slot name="cancel"></slot>
</template>
<template slot="option">
<slot name="option"></slot>
</template>
<template slot="columns-top">
<slot name="columns-top"></slot>
</template>
<template slot="columns-bottom">
<slot name="columns-bottom"></slot>
</template>
</van-picker>
</template>
<script>
import Vue from 'vue'
import { Field, Picker, Popup } from 'vant';
Vue.use(Field).use(Picker).use(Popup);
export default {
name: "VanDatePicker",
props: {
value: {
type: Date,
default: () => new Date()
},
minDate: {
type: Date,
default: () => new Date(new Date().getFullYear()-5,0,1)
},
maxDate: {
type: Date,
default: () => new Date(new Date().getFullYear()+5,0,1)
},
showToolbar: {
type: Boolean,
default: () => false
},
title: {
type: String,
default: () => ''
},
confirmButtonText: {
type: String,
default: () => '確認(rèn)'
},
cancelButtonText: {
type: String,
default: () => '取消'
},
loading: {
type: Boolean,
default: () => false
},
readonly: {
type: Boolean,
default: () => false
},
itemHeight: {
type: Number||String,
default: () => 44
},
visibleItemCount: {
type: Number||String,
default: () => 6
},
swipeDuration: {
type: Number||String,
default: () => 1000
},
},
data() {
return {
monthArr: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'],
dayArr: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12','13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24','25', '26', '27', '28', '29', '30', '31'],
};
},
computed: {
columns: function () {
let minYear = this.minDate.getFullYear();
let maxYear = this.maxDate.getFullYear();
let year = this.value.getFullYear();
let month = this.value.getMonth();
let day = this.value.getDate();
let yearArr = [];
let i = 0;
while (i < maxYear - minYear + 1) {
yearArr.unshift((maxYear - i) + '');
i ++;
}
let columns = [
{
values: yearArr,
defaultIndex: Math.floor(year) - minYear
},
{
values: this.monthArr,
defaultIndex: Math.floor(month)
},
{
values: this.dayArr,
defaultIndex: Math.floor(day-1)
},
{
values: ['-']
},
{
values: yearArr,
defaultIndex: Math.floor(year) - minYear
},
{
values: this.monthArr,
defaultIndex: Math.floor(month)
},
{
values: this.dayArr,
defaultIndex: Math.floor(day-1)
},
];
return columns
}
},
watch: {
},
methods: {
onConfirm(value, index) {
// console.log(`當(dāng)前值:${value}, 當(dāng)前索引:${index}`);
this.$emit('confirm',value,index);
},
onChange(picker, value, index) {
// console.log(`當(dāng)前值:${value}, 當(dāng)前索引:${index}`);
let _this = this;
let minMonth = this.minDate.getMonth();
let minDay = this.minDate.getDate();
let maxMonth = this.maxDate.getMonth();
let maxDay = this.maxDate.getDate();
let d = new Date(value[0],value[1],0);
setDate(0);
setDate(4);
function setDate(i) {
//最小年份
if (value[i]-0===_this.minDate.getFullYear()) {
picker.setColumnValues(i+1,_this.monthArr.slice(minMonth));
let strMinM = '';
if (minMonth<9) {
strMinM = '0'+(minMonth+1)
} else {
strMinM = strMinM + 1 + ''
}
picker.setColumnValue(i+1,value[i+1]-1<minMonth?strMinM:value[i+1]);
if (index===i&&value[i+1]-1<minMonth) {
picker.setColumnValues(i+2,_this.dayArr.slice(minDay-1,d.getDate()));
picker.setColumnValue(i+2,value[i+2]<minDay?minDay.toString():value[i+2]);
} else {
if (value[i+1]-1===_this.minDate.getMonth()) {
picker.setColumnValues(i+2,_this.dayArr.slice(minDay-1,d.getDate()));
picker.setColumnValue(i+2,value[i+2]<minDay?minDay.toString():value[i+2]);
} else {
picker.setColumnValues(i+2,_this.dayArr.slice(0,d.getDate()));
picker.setColumnValue(i+2,value[i+2]>d.getDate()?d.getDate().toString():value[i+2]);
}
}
}
//最大年份
else if (value[i]-0===_this.maxDate.getFullYear()) {
picker.setColumnValues(i+1,_this.monthArr.slice(0,maxMonth+1));
let strManM = '';
if (maxMonth<9) {
strManM = '0'+(maxMonth+1)
} else {
strManM = maxMonth + 1 + ''
}
picker.setColumnValue(i+1,value[i+1]-1>maxMonth?strManM:value[i+1]);
if (index===i&&value[i+1]-1>maxMonth) {
picker.setColumnValues(i+2,_this.dayArr.slice(0,maxDay));
picker.setColumnValue(i+2,value[i+2]>maxDay?maxDay.toString():value[i+2]);
} else {
if (value[i+1]-1===_this.maxDate.getMonth()) {
picker.setColumnValues(i+2,_this.dayArr.slice(0,maxDay));
picker.setColumnValue(i+2,value[i+2]>maxDay?maxDay.toString():value[i+2]);
} else {
picker.setColumnValues(i+2,_this.dayArr.slice(0,d.getDate()));
picker.setColumnValue(i+2,value[i+2]>d.getDate()?d.getDate().toString():value[i+2]);
}
}
}
//其他年份
else {
picker.setColumnValues(i+1,_this.monthArr);
picker.setColumnValue(i+1,value[i+1]);
picker.setColumnValues(i+2,_this.dayArr.slice(0,d.getDate()));
picker.setColumnValue(i+2,value[i+2]>d.getDate()?d.getDate().toString():value[i+2]);
}
}
let finallyVal = picker.getValues();
let len = Math.floor(finallyVal.length/2);
//開(kāi)始時(shí)間不大于結(jié)束時(shí)間
if (finallyVal.slice(0,len).join("")>finallyVal.slice(len+1).join("")){
picker.setValues([...finallyVal.slice(0,len),"-",...finallyVal.slice(0,len)]);
if (new Date(finallyVal.slice(0,len).join("-")+' 00:00:00').getTime()===this.maxDate.getTime()) {
console.log(111);
picker.setColumnValues(5,_this.monthArr.slice(0,maxMonth+1));
picker.setColumnValues(6,_this.dayArr.slice(0,maxDay));
}
}
this.$emit('change',picker,finallyVal,index);
},
onCancel() {
// console.log('取消');
this.$emit('cancel');
},
},
}
</script>
<style scoped>
</style>
調(diào)用demo
<template>
<div>
<van-field
readonly
clickable
label="時(shí)間段"
:value="value"
placeholder="選擇時(shí)間段"
@click="showPicker = true"
/>
<van-popup v-model="showPicker" round position="bottom">
<van-date-picker
show-toolbar
v-model="currentDate"
title="選擇時(shí)間段"
:min-date="minDate"
:max-date="maxDate"
@cancel="showPicker = false"
@confirm="onConfirm"
@change="onChange"
>
</van-date-picker>
</van-popup>
</div>
</template>
<script>
import VanDatePicker from '@/components/VanDatePicker';
export default {
name: "Test",
components: {VanDatePicker},
data() {
return {
value: '',
showPicker: false,
minDate: new Date(2010, 5, 15),
maxDate: new Date(2025, 10, 15),
currentDate: new Date(),
startDate: '',
endDate: '',
};
},
mounted() {
},
methods: {
onConfirm(value, index) {
console.log(`當(dāng)前值:${value}, 當(dāng)前索引:${index}`);
this.startDate = value.slice(0,3).join('-');
this.endDate = value.slice(4,7).join('-');
this.value = this.startDate + '至' + this.endDate;
this.showPicker = false
},
onChange(picker, value, index) {
console.log(`當(dāng)前值:${value}, 當(dāng)前索引:${index}`);
},
},
}
</script>
<style scoped>
</style>
UI示例

API:注意紅色劃掉的沒(méi)有實(shí)現(xiàn)



以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Vue中接收二進(jìn)制文件流實(shí)現(xiàn)pdf預(yù)覽的方法
本文主要介紹了Vue中接收二進(jìn)制文件流實(shí)現(xiàn)pdf預(yù)覽的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-12-12
Vue項(xiàng)目之ES6裝飾器在項(xiàng)目實(shí)戰(zhàn)中的應(yīng)用
作為一個(gè)曾經(jīng)的Java?coder,當(dāng)?shù)谝淮慰吹絡(luò)s里面的裝飾器Decorator,就馬上想到了Java中的注解,當(dāng)然在實(shí)際原理和功能上面,Java的注解和js的裝飾器還是有很大差別的,這篇文章主要給大家介紹了關(guān)于Vue項(xiàng)目之ES6裝飾器在項(xiàng)目實(shí)戰(zhàn)中應(yīng)用的相關(guān)資料,需要的朋友可以參考下2022-06-06
vue-router 中router-view不能渲染的解決方法
本篇文章主要結(jié)合了vue-router 中router-view不能渲染的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05
vue element-ui實(shí)現(xiàn)input輸入框金額數(shù)字添加千分位
這篇文章主要介紹了vue element-ui實(shí)現(xiàn)input輸入框金額數(shù)字添加千分位,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12
基于vue實(shí)現(xiàn)一個(gè)禪道主頁(yè)拖拽效果
最近在做一個(gè)基于vue的后臺(tái)管理項(xiàng)目。接下來(lái)通過(guò)本文給大家分析一款基于vue做一個(gè)禪道主頁(yè)拖拽效果,需要的朋友可以參考下2019-05-05
vue中關(guān)于confirm確認(rèn)框的用法
這篇文章主要介紹了vue中關(guān)于confirm確認(rèn)框的用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08
關(guān)于Nuxt的五種渲染模式的差異和使用場(chǎng)景全解析
這篇文章主要介紹了關(guān)于Nuxt的五種渲染模式的差異和使用場(chǎng)景全解析,在過(guò)去傳統(tǒng)開(kāi)發(fā)中,頁(yè)面渲染任務(wù)是由服務(wù)端完成的,那么Nuxt是如何渲染的呢,需要的朋友可以參考下2023-04-04
Vue 多層組件嵌套二種實(shí)現(xiàn)方式(測(cè)試實(shí)例)
本篇文章主要介紹了Vue組件嵌套二種實(shí)現(xiàn)方式(測(cè)試實(shí)例),具有一定的參考價(jià)值,代碼很簡(jiǎn)單,感興趣的小伙伴們可以參考一下2017-09-09
用npm安裝vue和vue-cli,并使用webpack創(chuàng)建項(xiàng)目的方法
今天小編就為大家分享一篇用npm安裝vue和vue-cli,并使用webpack創(chuàng)建項(xiàng)目的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09
vue.js動(dòng)態(tài)數(shù)據(jù)綁定學(xué)習(xí)筆記
這篇文章主要為大家詳細(xì)介紹了vue.js動(dòng)態(tài)數(shù)據(jù)綁定學(xué)習(xí)筆記,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05

