左小白的技术日常
Github
2020/08/15
Author: guoqzuo

vue中$attrs$listeners 的使用场景

在vue中,$attrs,$listeners 分别记录了当前组件上绑定的属性以及事件,一般可能用的比较少,下面来看看

this.$attrs

$attrs包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。

v-bind="$attrs" 他类似属性展开运算符,将父组件调用子组件时传入的属性展开(不包含props已接收的)、v-bind到当前的元素上。这里以封装input表单组件为例,来看看效果

<!-- 调用 zuo-input组件时传参 -->
<zuo-input v-model="value" placeholder="请输入" maxlength="50"/>

<!-- zuo-input 组件内部实现 -->
<input :value="value" @input="oninput" v-bind="$attrs"> 
<!-- 上面的代码渲染出来效果如下 -->
<input :value="value" @input="oninput" placeholder="请输入" maxlength="50"/>

this.$listeners

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

之前的笔记有提过,如果A组件包含B组件,B组件包含C组件。C组件想要触发A组件的方法,可以在B组件上加 v-on="$listeners" , 这样 C组件可以直接通过emit触发A组件的事件

// this.$listeners
{
  focus: function (event) { /* ... */ }
  input: function (value) { /* ... */ },
}

除了跨层级向下传递事件外,还可以用于将原生事件绑定到组件

<zuo-input @focus="focus" @input="xxx" @change="xx"/>
<!-- zuo-input 组件内部实现 -->
<input v-on="$listeners"> 
<!-- 上面的代码渲染出来效果如下 -->
<input onfocus="focus" oninput="xxx" onchange="xx"> 

实战应用

为了实践上面的$attrs$listeners我们可以自己尝试封装一个element form表单组件,参考示例 elementForm表单组件模仿实现 | github

参考