一、现象
el-input的双删除图标现象,如图:
上图的组件是根据业务需要封装的,简单的搜索图标内置,原生的也有这个现象;
二、原因
el-input组件设置clearable
,封装成独立组件,调用时其外部有一级祖先组件使用了el-form,并且设置了检验(设置了自定义rules),大致代码如下:
<el-form :model="formData" :rules="rules" ref="form" class="clearfix">
<el-form-item label="姓名" class="form-item" prop="userName">
<!-- 中间有很多次元素包裹el-input begin -->
<el-input v-model="searchText" clearable />
<!-- 中间有很多次元素包裹el-input end -->
</el-form-item>
</el-form>
审查元素发现:
第二个x是检验不通过的图标,查看elementUI的源码,如下:
发现是有validateIcon变量控制的,检查发现,这是一个计算属性,如下:
可以看出,当this.validateState === error
时,就会出现x,而validateState
是由this.elFormItem
算出来的,接着追查,发现this.elFormItem
是一个inject
属性,如下:
inject: {
elForm: {
default: ''
},
elFormItem: {
default: ''
}
},
找到了,inject的锅。
三、解决方法
可能有多种解决方法,我的方法是在封装el-input的组件里,再设置一个同名provide
,思路就是继承属性重写,在java里非常基础(笑),这样就不会显示校验的x了,这样改满足我的需求。知道了原因,改起来就方便多了,这种方法只是bug补丁,也可能下一个版本的ElementUI已经改掉这个功能,所以方法仅供参考。
四、思考
vue的provide/inject为封装多层次组件提供了方便,但是这种强大的穿透性也带来了很多问题,比如变量追踪比较困难、容易被拦截重写或变量冲突。
- 安全与效率往往互斥,需要权衡,找到一个平衡点来解决问题;
- 谨慎拿来主义,小心有坑;
- 第三方库可能有问题,但不能因噎废食,所有组件都自己封装;
- 有问题看源码,事半功倍。