之前遇到一个需求,需要在日期选择器(DatePicker) 组件内容被清空后做一些处理,但是看了文档之后发现 DatePicker 并没有像 Input 或 Select 组件那样提供 clear 事件,没法直接监听清空动作。我不死心,于是就去看了 DatePicker 组件的源码(element-ui 版本 2.15.6),发现点击清空按钮时会执行以下方法:
handleClickIcon(event) {
if (this.readonly || this.pickerDisabled) return;
if (this.showClose) {
this.valueOnOpen = this.value;
event.stopPropagation();
this.emitInput(null);
this.emitChange(null);
this.showClose = false;
if (this.picker && typeof this.picker.handleClear === 'function') {
this.picker.handleClear();
}
} else {
this.pickerVisible = !this.pickerVisible;
}
},
handleClickIcon
方法中只触发了 input 和 change 事件,没有 clear 事件。好了,无法实现 clear 监听,需求被毙(怎么可能)。。。
后来我想到通过 $refs
可以访问组件内部的方法,比如
// 父组件中
this.$refs.datePicker.focus();
那我只要为 handleClickIcon
重新赋个值,就可以让它实现我想要的功能了。
为了不影响 handleClickIcon
原有的行为,我只在其原来的基础上加了一行触发 clear 事件的代码。
<script>
/**
* 重写点击清空的事件处理函数
*/
const handleClickIcon = function (event) {
if (this.readonly || this.pickerDisabled) return;
if (this.showClose) {
this.valueOnOpen = this.value;
event.stopPropagation();
// 添加的下面这行代码,以在清空时通知父组件
this.$emit('clear');
this.emitInput(null);
this.emitChange(null);
this.showClose = false;
if (this.picker && typeof this.picker.handleClear === 'function') {
this.picker.handleClear();
}
} else {
this.pickerVisible = !this.pickerVisible;
}
};
export default {
mounted () {
let datePicker = this.$refs.datePicker;
datePicker.handleClickIcon = handleClickIcon.bind(datePicker);
},
}
</script>
需要注意的是,新的 handleClickIcon
是不能再 methods
选项中声明的,否则被替换的handleClickIcon
不会按预期执行。
更需要注意的是以上方法在实际开发中是不推荐使用的。修改组件行为会让 Element 文档失去意义,而且如果某次升级,Element 修改了该方法的实现,那就有趣了。