# Подписка на нативные события в компонентах

Иногда нужно подписаться на нативные события браузера на корневом элементе компонента. В таких случаях можно применять модификатор `.native` для `v-on`:

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

Иногда это может быть полезно, но это не очень хорошая идея, когда вы пытаетесь прослушивать очень специфичный элемент, к примеру `<input>`. Например, компонент `<base-input>` можно переделать так, чтобы корневой элемент был фактически элементом `<label>`:

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

В этом случае слушатель `.native` в родителе просто тихо перестанет работать. Ошибок не будет, но обработчик `onFocus` не будет вызываться, когда мы этого ожидаем.

Для решения этой проблемы Vue предоставляет свойство `$listeners`, содержащее объект всех слушателей, которые используются на компоненте. Например:

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

Используя свойство `$listeners`, вы можете передать все слушатели событий на компоненте на определённый дочерний элемент с помощью `v-on="$listeners"`. Для таких элементов как `<input>`, вы также можете захотеть работоспособности с `v-model`, для чего бывает полезно создать новое вычисляемое свойство для слушателей, например `inputListeners` указанный ниже:

```javascript
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>`: все те же атрибуты и слушатели будут работать без указания модификатора `.native`.
