封装组件库-时间选择器
2023, Mar 01
实现时间选择器的封装
基于Element-plus框架的TimeSelect时间选择组件和DatePicker日期选择器组件,封装为时间选择器和日期选择器。
初始配置
- 注册路由组件chooseTime,配置为Container组件的子路由组件
- 采用路由懒加载,箭头函数异步引入组件。
- 注册通用组件chooseTime,为路由组件的子组件,以便组件间通信。
- 将通用组件chooseTime注册为全局组件
时间选择器组件
- 子组件
<!-- 传参及类型 -->
let props = defineProps({
//开始时间占位符
startPlaceholder:{
type: String,
default: '请选择开始时间'
},
//开始时间的初始化
startTimeStart: {
type: String,
default: '08:00'
},
//开始时间的步进
startStep: {
type: String,
default: '00:30'
},
//开始时间的结束
startTimeEnd: {
type: String,
default: '24:00'
},
//结束时间占位符
endPlaceholder:{
type: String,
default: '请选择结束时间'
},
//结束时间的初始化
endTimeStart: {
type: String,
default: '08:00'
},
//结束时间的步进
endStep: {
type: String,
default: '00:30'
},
//结束时间的结束
endTimeEnd: {
type: String,
default: '24:00'
}
})
//开始时间
let startTime = ref<string>('')
//结束时间
let endTime = ref<string>('')
//结束时间的禁用
let endTimeDisabled = ref<boolean>(true)
- 绑定
<el-time-select
v-model="startTime"
:max-time="endTime"
class="mr-4"
:placeholder="startPlaceholder"
:start="startTimeStart"
:step="startStep"
:end="startTimeEnd"
//未配置props的传参,经过attrs并分类
v-bind="$attrs.startOptions"
/>
<el-time-select
v-model="endTime"
:min-time="startTime"
:placeholder="endPlaceholder"
:start="endTimeStart"
:step="endStep"
:end="endTimeEnd"
:disabled="endTimeDisabled"
v-bind="$attrs.endOptions"
/>
- 实现联动效果,并向父组件分发事件
//监听开始时间的变化
watch(()=>startTime.value,val=>{
//未选择或删除开始时间,则将结束时间置空,并禁用结束时间
if(val === '') {
endTime.value = ''
endTimeDisabled.value = true
}
//开始时间变化,开启结束组件,并向父组件传递开始时间
else{
endTimeDisabled.value = false
//给父组件分发事件
emits('startChange',val)
}
})
//监听结束时间的变化
watch(()=>endTime.value,val=>{
//选择结束时间则向父组件传递一个对象,包含开始和结束时间
if(val !== ''){
emits('endChange',{
startTime: startTime.value,
endTime: endTime.value
})
}
})
- 父组件
<my-choose-time
@startChange="startChange"
@endChange="endChange"
:startOptions="startOptions"
>
//可配置剩余项
let startOptions= {
size: 'default',
clearable: false
}
日期选择器组件
- 定义chooseDate组件,并进行全局注册
<!-- 传参及类型 -->
let props = defineProps({
//开始时间占位符
startPlaceholder:{
type: String,
default: '请选择开始日期'
},
//结束时间占位符
endPlaceholder:{
type: String,
default: '请选择结束日期'
},
//是否禁用选择今天之前的日期
disableToday: {
type: Boolean,
default: true
}
})
let startDate = ref<Date | null>(null)
let endDate = ref<Date | null>(null)
//控制结束日期的禁用状态
let endDateDisabled = ref<boolean>(true)
- 开始日期对今天以前的日期进行禁用
let startDisabledDate = (time: Date)=>{
//对日期小于当前时间 - 一天的日期禁用
if(props.disableToday) return time.getTime() < Date.now() - 1000 * 60 * 60 * 24
}
<el-date-picker :disabled-date="startDisabledDate"/>
let endDisabledDate = (time: Date)=>{
if(startDate.value) {
return time.getTime() < startDate.value.getTime() + 1000 * 60 * 60 * 24
}
}
//结束组件
<el-date-picker :disabled-date="endDisabledDate"/>
- 联动效果设计
//监听开始日期
watch(()=>startDate.value,val=>{
//未选择开始日期或删除,则禁用结束组件并清空
if(!val){
endDateDisabled.value = true
endDate.value = null
}else{
//选择开始日期则向父组件传递开始日期,解禁结束组件
endDateDisabled.value = false
emits('startChange',val)
}
})
//监听结束日期
watch(()=>endDate.value,val=>{
//选择结束日期,则向父组件传递对象,包含开始日期和结束日期
if(val){
emits('endChange',{
startDate: startDate.value,
endDate: endDate.value
})
}
})
- 父组件
<my-choose-date @startChange="dateStartChange" @endChange="dateEndChange" :endOptions="endOptions">
//示例,为结束组件配置 $attrs.endOptions进行接收
let endOptions= {
size: 'default',
clearable: false
}