ElementUI和iView日历控件datepicker时间限制

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、虽然可以把内部的两个日期限制在外部的两个日期之间,但是做数据回显时,日期又需做一番处理,此时并不能完整的限制时间,只能在用户提交之前,判断前一个日期是否大于等于后一个日期,弹出一个提示。
也就是说,最后还是要在做一次时间的验证,判断开始时间不能大于等于结束时间。

网站导航

网站导航

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容