Element
特定时间范围
设置某个时间之前的日期被禁用(设置某个时间之后的时间禁用同理)
方式一
html:
<el-date-picker
v-model="startDate"
type="date"
placeholder="开始日期"
:picker-options="pickerOptionsStart">
</el-date-picker>
js:
data () {
return {
pickerOptionsStart: {}
}
},
methods:{
// 这个方法可以在生命周期中调用,也可以通过操作触发,获取时间戳
getData () {
axios.get('/user').then((res) => {
// 这里可以做其他处理,比如:若时间小于今天,则设置为今天
// var startTime;
// if (res.data.startTime < new Date(new Date().toLocaleDateString()).getTime()) {
// startTime = new Date(new Date().toLocaleDateString()).getTime()
// } else {
// startTime = res.data.startTime
// }
var startTime = res.data.startTime
this.pickerOptionsStart = {
disabledDate (time) {
// 设置日期之前的时间都被禁用
// 在这里可以加减一天时间,比如前一个日历不能选最后一天,后一个日历不能选第一天
// return time.getTime() < startTime + 1000 * 60 * 60 * 24;
return time.getTime() < startTime;
}
}
})
}
}
方式二
html:
<el-date-picker
v-model="startDate"
type="date"
placeholder="开始日期"
:picker-options="pickerOptionsStart">
</el-date-picker>
js:
data () {
return {
startTime: null,
pickerOptionsStart: {
disabledDate: time => {
// 可通过箭头函数的方式访问到this
return time.getTime() < this.startTime
}
}
}
}
开始时间小于结束时间
html:
<el-date-picker
v-model="startDate"
type="date"
format="yyyy-MM-dd" value-format="yyyy-MM-dd"
@change="changeEnd"
placeholder="开始日期"
:picker-options="pickerOptionsStart">
</el-date-picker>
<el-date-picker
v-model="endDate"
type="date"
format="yyyy-MM-dd" value-format="yyyy-MM-dd"
@change="changeStart"
placeholder="结束日期"
:picker-options="pickerOptionsEnd">
</el-date-picker>
js:
data () {
return {
pickerOptionsStart: {},
pickerOptionsEnd: {},
// 可通过后台获取后赋值
startDate: null,
endDate: null,
}
},
methods:{
changeStart () {
this.pickerOptionsStart = Object.assign({}, this.pickerOptionsStart, {
disabledDate: (time) => {
// 若时间有误差,可加减一天1000*3600*24
return time.getTime() > new Date(this.endDate).getTime()
}
})
},
changeEnd () {
this.pickerOptionsEnd = Object.assign({}, this.pickerOptionsEnd, {
disabledDate: (time) => {
return time.getTime() < new Date(this.startDate).getTime()
}
})
}
}
今日之前的日期禁用
html:
<el-date-picker
v-model="startDate"
type="date"
placeholder="开始日期"
:picker-options="pickerOptionsStart">
</el-date-picker>
包含今日
js:
data () {
return {
pickerOptionsStart: {
disabledDate (time) {
return time.getTime() < new Date(new Date().toLocaleDateString()).getTime()+24*60*60*1000-1;
}
}
}
},
不包含今日
js:
data () {
return {
pickerOptionsStart: {
disabledDate (time) {
return time.getTime() < new Date(new Date().toLocaleDateString()).getTime();
}
}
}
},
三个月之后的日期禁用
html:
<el-date-picker
v-model="endDate"
type="date"
placeholder="结束日期"
:picker-options="pickerOptionsEnd">
</el-date-picker>
js:
data () {
return {
pickerOptionsStart: {
disabledDate (time) {
let curDate = new Date(new Date().toLocaleDateString()).getTime();
let three = 90 * 24 * 3600 * 1000;
let threeMonths = curDate + three;
return time.getTime() > threeMonths;
}
}
}
},
设置默认时间
默认开始时间今日,结束时间明日
setDefaultTime () {
// 若格式不支持date对象,可将时间转为格式化的字符串
this.startDate = new Date()
// 获取明日的天数
let tomorrowDay = (new Date()).getDate()+1
// 设置时间为明日,返回值为时间戳
let tomorrowTimestamp = (new Date()).setDate(tomorrowDay)
this.endDate = new Date(tomorrowTimestamp)
},
设置多个条件
return time.getTime() < this.startDate || time.getTime() > this.endTime;
注意事项
1、当你用后台获取的时间与今天做比较的时候,不能用(new Date()).getTime()来作为今天的时间,而要使用new Date(new Date().toLocaleDateString()).getTime()。它俩的区别是一个是当前时间,另一个是今天零点的时间,如果用当前时间,会出现限制多一天或少一天的bug。
2、与后台沟通,让他返回你的时间都为当日的零点时间,不然会出现限制多一天或少一天的bug。
间隔不连续时间禁用
需求描述
后台返回一个数组,数组中包含多个对象,对象中有两个属性:某天零点的时间戳和是否禁用的布尔值,若布尔值为false,则禁用当天。
时间禁用
pickerOptionsStart: {
disabledDate (time) {
// 这里是为了方便理解下面的time写的
}
}
禁用的原理:time是日历每天的时间对象,time.getTime() 可以获取当天零点的时间戳。日历控件会遍历每天,返回true则禁用。
this.pickerOptionsStart = {
disabledDate (time) {
// 限制某时期之外的时间禁用
if (time.getTime() < travelStartTime || time.getTime() > travelEndTime - 1000 * 60 * 60 * 24) {
return true;
} else {
// 限制某时期内选定的日期禁用
// res.data为后台返回的数组,包含某时期内要禁用的不连续日期
// 这里要使用for循环,forEach不能中断循环,导致禁用不生效
for(let i = 0; i < res.data.length; i++) {
if (res.data[i].Date === time.getTime() && res.data[i].flag === false) {
return true;
}
}
}
}
}
iView
方法同理,设置格式如下:
html:
<DatePicker
v-model="startDate "
:options="pickerOptionsStart"
@on-change="changeEnd"
:clearable="false"
type="date"
placeholder="开始时间">
</DatePicker>
区别在于将:picker-options替换为:options,将@change替换为@on-change;
另外,假如同时使用iview和element的日历控件,iview的时间限制相比element可能存在误差,同时使用两者的话,需要加减一天,自己视情况调整。
限制在两个日期之间的日期
需求:有两个日期,开始时间可以选择今天,结束时间可以选择明天。另外又有两个日期,范围限制在前两个日期之间
<Form class="form-cycle" ref="formCreateCycle" :model="formCreateCycle" inline >
<FormItem label="外部周期:" prop="outerStartTime">
<FormItem >
<DatePicker type="date" :options="pickerOptionsOuterStart" @on-change="changeOuterEnd" v-model="formCreateCycle.outerStartTime" placeholder="开始时间" format="yyyy-MM-dd" :editable="false" ></DatePicker>
</FormItem>
<span> 至 </span>
<FormItem prop="outerEndTime" >
<DatePicker type="date" :options="pickerOptionsOuterEnd" @on-change="changeOuterStart" v-model="formCreateCycle.outerEndTime" placeholder="结束时间" format="yyyy-MM-dd" :editable="false" ></DatePicker>
</FormItem>
</FormItem>
<!-- 内部周期要限制在外部周期之间 -->
<FormItem label="内部周期:" prop="innerStartTime">
<FormItem >
<DatePicker type="date" :options="pickerOptionsInnerStart" @on-change="changeInnerEnd" v-model="formCreateCycle.innerStartTime" placeholder="开始时间" format="yyyy-MM-dd" :editable="false" ></DatePicker>
</FormItem>
<span> 至 </span>
<FormItem prop="innerEndTime" >
<DatePicker type="date" :options="pickerOptionsInnerEnd" @on-change="changeInnerStart" v-model="formCreateCycle.innerEndTime" placeholder="结束时间" format="yyyy-MM-dd" :editable="false" ></DatePicker>
</FormItem>
</FormItem>
</Form>
data: {
formCreateCycle: {
outerStartTime: '',
outerEndTime: '',
innerStartTime: '',
innerEndTime: '',
},
// 日期禁用初始化
// 外部周期
pickerOptionsOuterStart: {
disabledDate (time) {
return time.getTime() < new Date(new Date().toLocaleDateString()).getTime();
}
},
pickerOptionsOuterEnd: {
disabledDate (time) {
return time.getTime() < new Date(new Date().toLocaleDateString()).getTime()+24*60*60*1000-1;
}
},
// 内部周期
pickerOptionsInnerStart: {
disabledDate (time) {
return time.getTime() < new Date(new Date().toLocaleDateString()).getTime();
}
},
pickerOptionsInnerEnd: {
disabledDate (time) {
return time.getTime() < new Date(new Date().toLocaleDateString()).getTime()+24*60*60*1000-1;
}
},
},
methods: {
// 设置外部周期时间限制
changeOuterEnd () {
// 外部周期结束时间大于开始时间
this.pickerOptionsOuterEnd = Object.assign({}, this.pickerOptionsOuterEnd, {
disabledDate: (time) => {
return time.getTime() < new Date(this.formCreateCycle.outerStartTime).getTime()+24*60*60*1000
}
})
// 内部周期开始时间大于等于外部周期开始时间
this.pickerOptionsInnerStart = Object.assign({}, this.pickerOptionsInnerStart, {
disabledDate: (time) => {
return time.getTime() < new Date(this.formCreateCycle.outerStartTime).getTime()
}
})
// 内部周期结束时间大于外部周期开始时间(大于等于今天) 并且小于等于外部周期结束时间
this.pickerOptionsInnerEnd = Object.assign({}, this.pickerOptionsInnerEnd, {
disabledDate: (time) => {
return time.getTime() < new Date(this.formCreateCycle.outerStartTime).getTime()+24*60*60*1000 || time.getTime() > new Date(this.formCreateCycle.outerEndTime).getTime()
}
})
},
changeOuterStart () {
// 外部周期开始时间小于结束时间 并且大于等于今天
this.pickerOptionsOuterStart = Object.assign({}, this.pickerOptionsOuterStart, {
disabledDate: (time) => {
return time.getTime() > new Date(this.formCreateCycle.outerEndTime).getTime()-24*60*60*1000 || time.getTime() < new Date(new Date().toLocaleDateString()).getTime()
}
})
// 内部周期开始时间小于外部周期结束时间 并且大于等于外部周期开始时间(大于等于今天)
this.pickerOptionsInnerStart = Object.assign({}, this.pickerOptionsInnerStart, {
disabledDate: (time) => {
return time.getTime() > new Date(this.formCreateCycle.outerEndTime).getTime()-24*60*60*1000 || time.getTime() < new Date(this.formCreateCycle.outerStartTime).getTime()
}
})
// 内部周期结束时间小于等于外部周期结束时间 并且大于内部周期开始时间 并且大于外部周期开始时间 并且大于今天
this.pickerOptionsInnerEnd = Object.assign({}, this.pickerOptionsInnerEnd, {
disabledDate: (time) => {
return time.getTime() > new Date(this.formCreateCycle.outerEndTime).getTime() || time.getTime() < new Date(this.formCreateCycle.innerStartTime).getTime()+24*60*60*1000 || time.getTime() < new Date(this.formCreateCycle.outerStartTime).getTime()+24*60*60*1000 || time.getTime() < new Date(new Date().toLocaleDateString()).getTime()+24*60*60*1000
}
})
},
// 设置内部周期时间限制
changeInnerEnd () {
// 内部周期结束时间大于开始时间 并且小于等于外部周期结束时间
this.pickerOptionsInnerEnd = Object.assign({}, this.pickerOptionsInnerEnd, {
disabledDate: (time) => {
return time.getTime() < new Date(this.formCreateCycle.innerStartTime).getTime()+24*60*60*1000 || time.getTime() > new Date(this.formCreateCycle.outerEndTime).getTime()
}
})
},
changeInnerStart () {
// 内部周期开始时间小于结束时间 并且大于等于外部周期开始时间(大于等于今天)
this.pickerOptionsInnerStart = Object.assign({}, this.pickerOptionsInnerStart, {
disabledDate: (time) => {
return time.getTime() > new Date(this.formCreateCycle.innerEndTime).getTime()-24*60*60*1000 || time.getTime() < new Date(this.formCreateCycle.outerStartTime).getTime()
}
})
},
}
最后
虽然日期禁用可以做很多,但是依然无法完美的做出所有限制。
比如:
1、之前做不连续时间禁用,如果用户选择了两个日期,两个日期之间有一些日期已经被选择过了,所以被禁用了,这时候就只能额外再判断用户选择的日期是否连续;
2、虽然可以把内部的两个日期限制在外部的两个日期之间,但是做数据回显时,日期又需做一番处理,此时并不能完整的限制时间,只能在用户提交之前,判断前一个日期是否大于等于后一个日期,弹出一个提示。
也就是说,最后还是要在做一次时间的验证,判断开始时间不能大于等于结束时间。