关于javascript:VUE将原生事件绑定到组件

8次阅读

共计 1169 个字符,预计需要花费 3 分钟才能阅读完成。

你可能有很屡次想要在一个组件的根元素上间接监听一个原生事件。这时,你能够应用 v-on 的 .native 修饰符:

<base-input v-on:focus.native="onFocus"></base-input>

在有的时候这是很有用的,不过在你尝试监听一个相似 <input> 的十分特定的元素时,这并不是个好主见。比方上述 <base-input> 组件可能做了如下重构,所以根元素实际上是一个 <label> 元素:

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

这时,父级的 .native 监听器将静默失败。它不会产生任何报错,然而 onFocus 处理函数不会如你预期地被调用。
为了解决这个问题,Vue 提供了一个 $listeners property,它是一个对象,外面蕴含了作用在这个组件上的所有监听器。例如:

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

有了这个 $listeners property,你就能够配合 v-on=”$listeners” 将所有的事件监听器指向这个组件的某个特定的子元素。对于相似 <input> 的你心愿它也能够配合 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> 组件是一个齐全通明的包裹器了,也就是说它能够齐全像一个一般的 <input> 元素一样应用了:所有跟它雷同的 attribute 和监听器都能够工作,不用再应用 .native 监听器。

正文完
 0