2018 年 12 月更新:

要求禁用时间不能小于启用时间。
问题: 启用时间是动态更新的,不同数据启用时间不同,导致禁用时间范围也不一样。在data初始赋值后不会再更新pickerOptions
解决方法:watch 启用时间,每次更新启用时间都动态更新一次pickerOptions

Template

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<el-form-item label="启用月份" prop="start_year_month">
<el-date-picker
v-model="form.start_year_month"
type="month"
format="yyyy 年 MM"
value-format="yyyyMM"
style="width: 100%"
placeholder="请选择启用月份"
:clearable="false"
:editable="false"
></el-date-picker>
</el-form-item>
<el-form-item
label="禁用月份"
prop="stop_year_month"
>
<el-date-picker
:picker-options="pickerOptions"
v-model="form.stop_year_month"
:clearable="false"
:editable="false"
type="month"
style="width: 100%"
format="yyyy 年 MM"
value-format="yyyyMM"
placeholder="请选择禁用月份"
></el-date-picker>
</el-form-item>

Script

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
data: {
pickerOptions: {},
form: {
start_year_month: '',
stop_year_month: ''
}
}

watch: {
// time.getTime是把选中的时间转化成自1970年1月1日 00:00:00 UTC到当前时间的毫秒数
// 当前启用日期为 ‘201912’ ,只包含日期,导致return范围不对,需要转换为‘2019-12’
['form.start_year_month'](val) {
this.pickerOptions = Object.assign({}, this.pickerOptions, {
// disabledDate 为true表示不可选,false表示可选
disabledDate: (time) => {
let str = val.slice(0, 4) + '-' + val.slice(4, 7)
str = new Date(str).getTime()
return time.getTime() < str // 可选时间范围大于等于启用日期
}
})
}

实现效果

image


2018 年 7 月更新:

产品觉得饿了么的时间范围选择器不方便,要求使用两个单独的时间选择器做时间范围筛选。

Template

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<el-date-picker
v-model="startDate"
type="date"
placeholder="选择开始日期"
:picker-options="pickerOptionsStart"
@change="changeEnd"
>
</el-date-picker>

<el-date-picker
v-model="endDate"
type="date"
placeholder="选择结束日期"
:picker-options="pickerOptionsEnd"
@change="changeStart"
>
</el-date-picker>

Script

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
data() {
return {
pickerOptionsStart: {},
pickerOptionsEnd:{},
startDate: '',
endDate: '',
};

methods:{
changeStart (){
this.pickerOptionsStart = Object.assign({},this.pickerOptionsStart,{
disabledDate: (time) => {
return time.getTime() > this.endDate
}
})
},
changeEnd (){
this.pickerOptionsEnd = Object.assign({},this.pickerOptionsEnd,{
disabledDate: (time) => {
return time.getTime() < this.startDate
}
})
}
}

2018 年 4 月更新:

做企业合同办理入住遇到新的需求,特此记录一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import moment from 'moment'
export default function () {
let that = this
return {
/** *
* 不允许选择未来日期
* 允许选择合同开始前的30天,(即往前推29天)
* 如果合同租期已结束,可选最大时间为租期结束时间
*/
pickerOptions: {
disabledDate(time) {
let curDate = (new Date()).getTime()
let start = new Date(that.form.rent_start).getTime()
let end = new Date(that.form.rent_end).getTime()
let three = 30 * 24 * 3600 * 1000
if (moment().isAfter(that.form.rent_end, 'day')) {
return time.getTime() < start - three || time.getTime() > end
}
return time.getTime() < start - three || time.getTime() > curDate
}
}
}

应用场景:

双栏日期选择。选定开始日期后,结束日期只能限定在开始日期后三个月内的任意一天。

缺点:

内部循环遍历所有日期,性能较差

代码:
  • datepick.html
1
2
3
<div id="datepick">
<datepick></datepick>
</div>
  • datepick.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<template>
<div class="block">
<el-date-picker
v-model="value1"
type="date"
placeholder="开始日期"
:picker-options="pickerOptions0">
</el-date-picker>
<el-date-picker
v-model="value2"
type="date"
placeholder="结束日期"
:picker-options="pickerOptions1">
</el-date-picker>
</div>
</template>

<script>
export default {
data(){
return {
value1:'',
value2:'',
pickerOptions1: {
//disabledDate是日期组件的一个方法
disabledDate: (time) => {
//这里就涉及到日期的指定了 setMonth()函数可以设置月份
let currentTime = this.value1;
let threeMonths = currentTime.setMonth(currentTime.getMonth()+3);
//一开始我没加下面减三个月的那个语句,他的值会一直累加
currentTime.setMonth(currentTime.getMonth()-3)
return time.getTime() < this.value1 || time.getTime() > threeMonths ;
}
}
}
}
}
</script>
  • datepick.js
1
2
3
4
5
6
7
8
9
10
11
12
import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import datepick from '../components/datepick.vue';

Vue.use(ElementUI);

new Vue({
el: "#datepick",
template:'<datepick/>',
components: {datepick}
})