vue将原生事件绑定到组件--方法详细解释

  1. 使用 v-on 的 .native 修饰符:
<base-input v-on:focus.native="onFocus"></base-input>

在有的时候这是很有用的,不过在你尝试监听一个类似 的非常特定的元素时,这并不是个好主意。比如上述 组件可能做了如下重构,所以根元素实际上是一个

<label>
  {{ label }}
  <input
    v-bind="$attrs"
    v-bind:value="value"
    v-on:input="$emit('input', $event.target.value)"
  >
</label>

这时,父级的 .native 监听器将静默失败。它不会产生任何报错,但是 onFocus 处理函数不会如你预期地被调用。

**原因:父级元素 的根元素是,元素监听了focus事件,但实际上,事件的触发源是 元素。并且

  • 元素没有focus事件
  • 即使有focus事件,当前template中元素只默认监听了input事件。事件向上传递后,也无法触发根元素事件 **
  1. 使用Vue 提供的一个 $listeners 属性
    Vue 提供了一个 $listeners 属性,它是一个对象,里面包含了作用在这个组件上的所有监听器。例如:
{
  focus: function (event) { /* ... */ }
  input: function (value) { /* ... */ },
}

对于类似 的你希望它也可以配合 v-model 工作的组件来说,为这些监听器创建一个类似下述 inputListeners 的计算属性通常是非常有用的:

Vue.component('base-input', {
  inheritAttrs: false,
  props: ['label', 'value'],
  computed: {
    inputListeners: function () {
      var vm = this
      // `Object.assign` 将所有的对象合并为一个新对象
      return Object.assign({},
        // 我们从父级添加所有的监听器
        this.$listeners,
        // 然后我们添加自定义监听器,
        // 或覆写一些监听器的行为
        {
          // 这里确保组件配合 `v-model` 的工作
          input: function (event) {
            vm.$emit('input', event.target.value)
          }
        }
      )
    }
  },
  template: `
    <label>
      {{ label }}
      <input
        v-bind="$attrs"
        v-bind:value="value"
        v-on="inputListeners"
      >
    </label>
  `
})

然后使用方式如下:

<base-input v-on:listener-name="methodName"></base-input>

说明: 上面的代码中, this. l i s t e n e r s 其 实 是 获 取 了 &lt; b a s e − i n p u t &gt; 这 个 父 级 组 件 中 定 义 的 所 有 的 监 控 事 件 l i s t e n e r − n a m e , 再 加 上 i n p u t 事 件 , 就 能 使 得 &lt; b a s e − i n p u t &gt; 组 件 像 一 个 普 通 的 &lt; i n p u t &gt; 元 素 一 样 使 用 了 。 ∗ ∗ 特 别 说 明 : ∗ ∗ 如 果 在 &lt; b a s e − i n p u t &gt; 通 过 v − o n 或 v − m o d e l 的 方 式 , 监 听 i n p u t 事 件 , 那 么 t h i s . listeners其实是获取了&lt;base-input&gt;这个父级组件中定义的所有的监控事件listener-name,再加上input事件,就能使得&lt;base-input&gt; 组件像一个普通的 &lt;input&gt; 元素一样使用了。 **特别说明:**如果在&lt;base-input&gt; 通过v-on或v-model的方式,监听input事件,那么this. listeners<baseinput>listenernameinput使<baseinput><input>使<baseinput>vonvmodelinputthis.listeners就会取到这个input监听事件,但在Object.assign()时,同名的监听事件,后者会覆盖前者。因此即使在父级组件中定义input监听,也不会出现问题。

另外

<base-input v-on:listener-name="methodName"></base-input>

对组件的子组件建立监控的时候,其实更像是在的实例中定义了一个listener-name为名称的函数,然后通过$emit反射调用。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值