你可能有很屡次想要在一个组件的根元素上间接监听一个原生事件。这时,你能够应用 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 监听器。