预期效果
官网默认样式:
修改后的样式:
代码实现
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 属性绑定到子组件的根元素上,以确保这些属性能够正确传递给子组件内部的其他组件或元素。