预期效果
官网默认样式:
修改后的样式:
代码实现
DatePicker.vue
<template>
<div class="date-picker-container">
<el-date-picker v-model="date" @change="handleChange" type="date" value-format="YYYY-MM-DD" placeholder="请选择日期" />
</div>
</template>
<script setup>
import { ref, reactive, defineModel } from 'vue'
// const date = ref('')
const date = defineModel()
// 父传子
const props = defineProps({ width: { type: String, default: '150px' } })
// 子传父
const emits = defineEmits(['datePickerChange'])
const handleChange = () => {
console.log(' handleChange ')
emits('datePickerChange', date)
}
</script>
<style lang="scss" scoped>
.date-picker-container {
width: 150px;
height: 20px;
color: #8dd8ff;
}
:deep(.el-date-editor.el-input) {
--el-date-editor-width: v-bind(props.width);
}
:deep(.el-input__inner) {
margin-left: -5px;
}
:deep(.el-input__wrapper) {
background-color: transparent !important;
border: 1px solid #47b7ff;
box-shadow: none;
}
:deep(.el-input__prefix) {
margin-left: -5px;
color: #8dd8ff;
}
</style>
父组件调用
<DatePicker v-model="dataPickerDate" @datePickerChange="changeDate" :width="'200px'"></DatePicker>
import DatePicker from './TreeTable/DatePicker.vue'
const dataPickerDate = ref('')
onMounted(() => {
date.value = moment().format('YYYY-MM-DD') // 在父组件修改日期
getData() // 调用接口的函数
})
const changeDate = () => {
console.log('dataPickerDate父亲', dataPickerDate.value)
getData() // 调用接口的函数
}
这里面用defineMode来实现父子组件的数据绑定,比props和emits更加方便,defineModel用法讲解传送门
代码优化
新增一个功能:未来的日期不可以选择
父组件:
<DatePicker :disabled-date="disabledDate" v-model="dataPickerDate" @datePickerChange="changeDate" :width="'200px'"></DatePicker>
const disabledDate = (time) => {
return time.getTime() > Date.now()
}
子组件增加v-bind=“$attrs”
在子组件中,
v-bind="$attrs"
的作用是将父组件传递给子组件的非 prop 属性绑定到子组件的根元素上。
<el-date-picker v-bind="$attrs" v-model="date" @change="handleChange" type="date" value-format="YYYY-MM-DD" placeholder="请选择日期" />
使用v-bind="$attrs"后就可以把之前在父子组件写了两边的的emits和v-model删掉,修改后代码:
父组件:
<DatePicker :disabled-date="disabledDate" v-model="dataPickerDate" @change="changeDate" :width="'200px'"></DatePicker>
const dataPickerDate = ref('')
onMounted(() => {
date.value = moment().format('YYYY-MM-DD') // 在父组件修改日期
getData() // 调用接口的函数
})
const changeDate = () => {
console.log('dataPickerDate父亲', dataPickerDate.value)
getData() // 调用接口的函数
}
const disabledDate = (time) => {
return time.getTime() > Date.now()
}
子组件:
<template>
<div class="date-picker-container">
<el-date-picker v-bind="$attrs" type="date" value-format="YYYY-MM-DD" placeholder="请选择日期" />
</div>
</template>
// 父传子
const props = defineProps({ width: { type: String, default: '150px' } })
v-bind="$attrs"
详细解释:
当父组件使用子组件时,父组件可能会传递一些额外的属性给子组件,这些属性在子组件中并没有声明为 prop。使用 v-bind="$attrs"
可以将这些额外的属性传递给子组件的根元素。
在你提供的代码中,父组件使用了 <DatePicker>
组件,并传递了 v-model
、@change
和 :disabled-date
这些属性给子组件。然而,在子组件的 <el-date-picker>
标签中,并没有声明这些属性。
通过在子组件的 <el-date-picker>
标签上使用 v-bind="$attrs"
,可以将父组件传递的这些额外属性绑定到子组件的根元素上,确保这些属性能够正确地传递给 <el-date-picker>
组件。
这样,子组件就能够接收到父组件传递的 v-model
、@change
和 :disabled-date
属性,并在子组件内部使用它们。
总结起来,v-bind="$attrs"
的作用是将父组件传递给子组件的非 prop 属性绑定到子组件的根元素上,以确保这些属性能够正确传递给子组件内部的其他组件或元素。