$attrs、$listeners的实际用法
官方解释
2.4.0 新增,包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。
官方只是提点,看不懂,云里雾里,什么鬼玩意儿,尤其后面那句可以通过 v-bind="$attrs"传入内部组件,到底是怎么个传法,懵逼。
以下是element-ui input源码
vue
<input
:tabindex="tabindex"
v-if="type !== 'textarea'"
class="el-input__inner"
v-bind="$attrs"
:type="type"
:disabled="inputDisabled"
:readonly="readonly"
:autocomplete="autoComplete || autocomplete"
:value="currentValue"
ref="input"
@compositionstart="handleComposition"
@compositionupdate="handleComposition"
@compositionend="handleComposition"
@input="handleInput"
@focus="handleFocus"
@blur="handleBlur"
@change="handleChange"
:aria-label="label"
>
<!--注意看 v-bind="$attrs"-->
el-input的props源码:
vue
props: {
value: [String, Number],
size: String,
resize: String,
form: String,
disabled: Boolean,
readonly: Boolean,
type: {
type: String,
default: 'text'
},
autosize: {
type: [Boolean, Object],
default: false
},
autocomplete: {
type: String,
default: 'off'
},
/** @Deprecated in next major version */
autoComplete: {
type: String,
validator(val) {
process.env.NODE_ENV !== 'production' &&
console.warn('[Element Warn][Input]\'auto-complete\' property will be deprecated in next major version. please use \'autocomplete\' instead.');
return true;
}
},
validateEvent: {
type: Boolean,
default: true
},
suffixIcon: String,
prefixIcon: String,
label: String,
clearable: {
type: Boolean,
default: false
},
tabindex: String
}
我们怎么使用el-input的
vue
<el-input maxlength="5" minlength="2">
</el-input>
你会发现 maxlength
和 minlength
根本就没再props中定义
不传递则这2个属性不起作用,因为子input上没有这2个属性。
那是如何将其传递给素内的原生input子元素呢?
答案就是通过v-bind="$attrs"
来实现
它将父元素所有非prop的特性都绑定在了子元素input上,否则还得在props里声明maxlength,minlength,代码量增大。这就是$attrs的使用。
对应的还有$listeners,
包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用
最后别忘了官方括号那段话
class和style是不会被继承的,用脑子想想就知道,这要是被继承,那还得了,页面不都得乱套了。