ElementUI全局配置默认属性
太长不看
props
// 设置组件默认prop
Element.Input.props.clearable.default = true;
原生属性
通常情况下,以maxlength属性为例
import Element from 'element-ui'
const render = Element.Input.render;
Element.Input.render = function () {
// 设置组件默认原生属性(attr)
this.$attrs.maxlength || (this.$attrs.maxlength = 2);
return render.apply(this, arguments)
}
场景介绍
在项目遇到一个需求,给所有输入框都要有默认的字数限制。
第一时间想到了maxlength这个原生属性,但是项目中有很多输入框,一个一个的添加非常的不优雅。所以我们的目的是像设置全局变量一样,设置组件的原生属性。
设置组件的默认属性
众所周知,组件的默认props可以这么设置.
// 设置组件默认prop
Element.Input.props.clearable.default = true;
设置组件的默认原生属性
同样的思路,我们可以通过修改组件的注册参数,实现目的。
我们可以利用组件实例的$attrs属性。
利用生命周期?
import Element from 'element-ui'
const created = Element.Input.created;
//劫持
Element.Input.created = function () {
this.$attrs.maxlength || (this.$attrs.maxlength = 2);
created.apply(this, arguments)
}
这么写乍一看没啥问题,然而实际效果是只有第一次渲染时属性是生效的,后面双向改变触发渲染属性就会失效。
created,mounted,updated都不可以!
为啥不行?
翻阅源码找到$attrs相关部分
取自src/core/instance/lifecycle.js 函数updateChildComponent
// update $attrs and $listeners hash
// these are also reactive so they may trigger child update if the child
// used them during render
vm.$attrs = parentVnode.data.attrs || emptyObject
vm.$listeners = listeners || emptyObject
重点是这句
vm.$attrs = parentVnode.data.attrs
parentVnode是父级虚拟Dom。parentVnode.data.attrs就是模板编译后通过createElement的第二参数传入的。
何时调用
通过F12断点
我们根据调用栈,Vue组件在每次dom-diff中,在同级节点更新完毕,执行更新子节点前执行这段代码。去父级的render函数中去获取attrs
因此我们在created等生命周期中执行是不可以的。
结论:利用render函数
import Element from 'element-ui'
const render = Element.Input.render;
Element.Input.render = function () {
// 设置组件默认原生属性(attr)
this.$attrs.maxlength || (this.$attrs.maxlength = 2);
return render.apply(this, arguments)
}