Skip to content
本页目录

$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>

你会发现 maxlengthminlength根本就没再props中定义

不传递则这2个属性不起作用,因为子input上没有这2个属性。

那是如何将其传递给素内的原生input子元素呢?

答案就是通过v-bind="$attrs"来实现

它将父元素所有非prop的特性都绑定在了子元素input上,否则还得在props里声明maxlength,minlength,代码量增大。这就是$attrs的使用。

对应的还有$listeners,

包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用

最后别忘了官方括号那段话

class和style是不会被继承的,用脑子想想就知道,这要是被继承,那还得了,页面不都得乱套了。