日期选择器组件
核心
可以查阅这篇文章,看一些v-model的具体实现;
简介来讲,就是自定义属性和自定义方法的结合使用。
Vue2.0、Vue3.0分别使用v-model封装组件
首先新建引入element-ui组件和样式;
<!--
* @Descripttion:
* @version:
* @Author: ZhangJunQing
* @Date: 2022-06-08 15:55:18
* @LastEditors: ZhangJunQing
* @LastEditTime: 2022-08-10 17:55:23
-->
<template>
<div class="inputBox" :style="inputBoxStyle">
<p class="inputBoxP" :style="titleStyle" v-if="title ? true : false">
{
{
title }}:
</p>
<el-date-picker
:disabled="disabled"
:format="format"
:value-format="valueFormat"
class="datepicker"
v-model="dataTime"
@change="inputFun"
:clearable="clearable"
:picker-options="returnpickerOptions"
:type="type"
placeholder="选择日期"
:default-time="returnDefaultTime"
></el-date-picker>
</div>
</template>
<script>
export default {
model: {
prop: "value",
event: "inputFun",
},
data() {
return {
dataTime: "",
changeNum: 1,
};
},
computed: {
returnpickerOptions({
pickerOptions, end, startTime }) {
// 默认等于空的时候 并且是属于结束时间 并且 startTime传入了 说明 是结束时间
if (pickerOptions === '' && end && String(startTime)) {
const timeer = startTime
return {
disabledDate(time) {
return new Date(time).getTime() < new Date(timeer).getTime() || time.getTime() > Date.now();
}
}
}
// 什么也没穿
if (pickerOptions === '') {
return {
disabledDate(time) {
return time.getTime() > Date.now();
}
}
}
// 传入了 pickerOptions
// console.log(this.pickerOptions, 'this.pickerOptions')
return pickerOptions
},
returnDefaultTime({
format, end }) {
if (format === 'yyyy-MM-dd HH:mm:ss') {
if (end) {
return '23:59:59'
} else {
return '00:00:00'
}
} else {
return ''
}
}
},
props: {
// 是否显示取消按钮
clearable: {
type: Boolean,
require: true
},
// 输入框前边的文字样式
titleStyle: {
type: String,
require: false,
},
// 输入框前边的文字
title: {
type: String,
require: false,
// default: "请传入Titlt"
},
// 文字和输入框父级 可以设置样式
inputBoxStyle: {
type: String,
require: false,
},
// v-model 绑定的value值 对应 model: { prop: "value",event: "inputFun",},
value: {
type: [Date, String],
require: false,
},
// 输入框默认显示日期
placeholder: {
type: String,
require: false,
default: "请选择日期",
},
// 日期格式化格式
format: {
type: String,
default: "yyyy-MM-dd HH:mm:ss",
},
// 返回日期格式化格式
valueFormat: {
type: String,
default: "yyyy-MM-dd HH:mm:ss",
},
// 日期组件类型
type: {
type: String,
// 可选 year/month/date/dates/ week/datetime/datetimerange/ daterange/monthrange
default: "datetime",
},
// 传入 end 即代表 是结束时间不能大于当前时间 end和startTime一起使用
end: {
type: Boolean,
default: false,
},
// 传入 startTime 即代表 是结束时间不能大于当前时间 end和startTime一起使用
startTime: {
type: [Date, String],
required: false,
},
// 禁选日期函数 当然也还有很多属性
pickerOptions: {
type: [Object, String],
default: ""
},
disabled: {
type: Boolean,
require: false,
default: false,
},
},
watch: {
value: {
handler(e) {
this.dataTime = e;
},
immediate: true,
},
dataTime: {
handler(e, old) {
let newV = e
// 排除第一次加载的情况
if (this.changeNum !== 1) {
// 是结束时间并且是 yyyy-MM-dd HH:mm:ss 格式
if (this.end && e && e !== 'null' && this.format === 'yyyy-MM-dd HH:mm:ss') {
// 选择当天 time返回现在的时间
if (this.returnTodayDate('1') === e.substr(0, 10)) {
// 1、点击当天
// 2、当天时间切换
if (old.substr(0, 11) !== e.substr(0, 11)) {
newV = this.returnTodayDate('2')
} else {
// 在新日期中切换时间
newV = e
}
} else {
// 有两种情况
// 1、直接点击的新日期
// 2、在新日期中切换时间
// 选择历史时间返回 23:59:59
if (old.substr(0, 11) !== e.substr(0, 11)) {
newV = e.substr(0, 11) + '23:59:59'
} else {
// 在新日期中切换时间
newV = e
}
}
this.dataTime = newV
}
}
this.$emit('CallBackFun', newV)
this.changeNum += 1
}
}
},
methods: {
returnTodayDate(flag) {
function add0(m) {
return m < 10 ? "0" + m : String(m);
}
let todayDateObj = new Date();
let dateStr = todayDateObj.getFullYear() +
"-" +
add0(todayDateObj.getMonth() + 1) +
"-" +
add0(todayDateObj.getDate())
if (flag === '1') {
return dateStr
} else if (flag === '2') {
return dateStr + " " +
add0(todayDateObj.getHours()) +
":" +
add0(todayDateObj.getMinutes()) +
":" +
add0(todayDateObj.getSeconds());
}
},
inputFun(e) {
// 触发 v-model 的更新事件 对应 model: { prop: "value",event: "inputFun",},
if (e === null || e === 'null') {
e = ''
}
this.$emit("inputFun", e);
},
},
};
</script>
<style lang="less" scoped>
.inputBox {
margin-bottom: 10px;
display: flex;
justify-content: flex-start;
align-items: center;
width: var(--boxWidth);
.inputBoxP {
font-weight: 500;
font-size: 12px;
text-align: right;
white-space: nowrap;
width: 150px;
}
.inputBoxIpt {
// width: 200px;
width: var(--el_form_width);
}
.datepicker {
// width: 200px;
width: var(--el_form_width);
}
/deep/.el-input--small .el-input__icon {
line-height: 32px;
}
}
</style>
使用:
<div class="LongSelectWidthBox">
<v-date-time-picker
:format="dateTimeFormat"
:valueFormat="dateTimeFormat"
:type="DateTypeStr"
title="开始时间"
:pickerOptions="{
disabledDate(time) {
return time.getTime() > new Date().getTime();
},
}"
v-model="startDate"
/>
<v-date-time-picker
end
:format="dateTimeFormat"
:valueFormat="dateTimeFormat"
:startTime="startDate"
:type="DateTypeStr"
:pickerOptions="{
disabledDate(time) {
return time.getTime() > new Date().getTime();
},
}"
title="结束时间"
v-model="endDate"
/>
</div>
data(){
return {
dateTimeFormat: "yyyy-MM-dd",
DateTypeStr: "datetime",
endDate:"",
startDate:""
}
}