Vue.js – Как я вызываю метод в компоненте извне компонента в Vue 2

Spread the love

Перевод: Jannick Holm Vue.js — How I call a method in a component from outside the component in Vue 2

Иногда нам приходится делать вызов метода в компоненте вне этого компонента. Но как именно это сделать? Существует несколько способов, но какой из них лучший?

В этой статье я попытаюсь ответить на этот вопрос, показать, какой мне нравится больше, и привести несколько примеров кода, показывающих, как вы можете реализовать некоторые из моих любимых методов в своем приложении Vue.

И так, приступим.

1. Использование шины событий Event Bus

Один из способов сделать это – использовать шину событий (Event Bus). Шину событий можно использовать в большинстве сценариев: от одного компонента к другому ( sibling-to-sibling ), от двоюродного компонента к двоюродному компоненту ( cousin-to-cousin ), от родительского компонента к дочернему( parent-to-child ), от дочернего компонента к родительскому ( child-to-parent ). Что касается шины событий, я бы порекомендовал вам использовать ее в случае вызова метода в сценарии sibling-to-sibling или cousin-to-cousin . Почему? Потому что я считаю, что есть другие более удобные способы для других сценариев.

Что такое event bus?

По сути, шина событий – это экземпляр Vue.js, который может генерировать события в одном компоненте, а затем ожидать (прослушивать) и реагировать на генерируемое событие в другом компоненте.

Есть два способа реализовать шину событий:

1. Реализация шины событий как свойства экземпляра

Свойство экземпляра – это свойство (или переменная), которое вы хотите сделать доступным глобальным для всех ваших компонентов, не загрязняя глобальную область видимости.

Хорошо, это звучит действительно круто, но как мне это реализовать в моем приложении? Отличный вопрос, на самом деле это довольно просто:

import Vue from 'vue';

Vue.prototype.$eventBus = new Vue();

И затем вы можете получить к нему доступ в любом месте вашего приложения следующим через переменную: this.$eventBus

2. Реализация шины событий как модуля ES6.

Другой способ реализации шины событий – в виде модуля ES6. Поначалу это может показаться пугающим, но это на самом деле не так уж сложно и может быть реализовано всего несколькими строками кода.

Во-первых, нам нужно создать модуль ES6. Для этого сделаем следующее:

  1. Начните с создания в вашем проекте нового файла с именем event-bus.js.
  2. Затем добавьте в тот же файл следующий код:
import Vue from 'vue';
const EventBus = new Vue();

export default EventBus;

Как вы уже могли заметить, это очень похоже на ранее используемую переменную экземпляра Vue. Тут мы создаем переменную, а затем экспортируем ее, чтобы использовать ее в приложении.

И таким образом мы создали модуль ES6.

Теперь все, что нам нужно сделать, это импортировать его в компоненты, в которых мы хотим его использовать, следующим образом

<script>
import EventBus from './event-bus.js'

export default {
  ...
}

</script>

Когда мы реализовали шину событий в нашем приложении, мы можем затем создать событие в одном из наших компонентов следующим образом:

<script>

export default {
  methods: {
    callMethodInChildComponent() {

      //As an instance property
      this.$eventBus.$emit("callMethodInChild");

      //As an ES6 module.
      EventBus.$emit("callMethodInChild");

    },
  },
};

</script>

Затем в другом компоненте мы подключаемся к прослушиванию события, и затем выполняем соотвествующий метод:

<script>

export default {
  mounted() {

    //As an instance property
    this.$eventBus.$on("callMethodInChild", () => {
      this.methodInChild();
    });

    //As an ES6 module
    EventBus.$on("callMethodInChild", () => {
      this.methodInChild();
    });
  },
  methods: {
    methodInChild() {
      //Execute code
    },
  },
};

</script>

2. Использование $refs

Использование свойства $refs – отличный и простой способ вызова метода компонентов из родительского компонента, поэтому для ссылки на вышеупомянутые сценарии это будет сценарий «родитель-потомок».

Что такое свойство $refs и как его использовать?

Свойство $refs используется для ссылки на элементы DOM в шаблонах экземпляра Vue.

Чтобы использовать свойство $refs, присвойте ссылочный идентификатор дочернему компоненту, на который вы хотите ссылаться, с помощью атрибута ref. Например:

<template>

  <child-component ref="childComponent"></child-component>

</template>

Теперь мы можем получить доступ к методам дочерних компонентов, а затем вызвать метод непосредственно из родительского компонента следующим образом:

<script>

export default {
  methods: {
    callMethodInChildComponent() {
      this.$refs.childComponent.methodInChild();
    },
  },
};

</script>

3.Старый добрый $emit

Еще один способ вызова метода компонентов вне компонента это использовать свойство $emit.

Сценарий использования свойства $emit – это когда вы хотите вызвать метод в родительском компоненте из дочернего компонента, а также то, что я называю сценарием от дочернего к родительскому.

Что такое свойство $emit и как его использовать?

Свойство $emit используется для генерации события из нашего дочернего компонента, и запуска настраиваемого события в родительском компоненте. Свойство $emit, в отличие props и event names не обеспечивает автоматического преобразования регистра. Вместо этого имя генерируемого события должно точно соответствовать имени, используемому для прослушивания этого события. Например, если генерируется имя события camelCased, такое как «updateItem», прослушиваемая версия «update-item» не будет иметь никакого эффекта.

Эмитирование события в дочернем компоненте

<script>

export default {
  methods: {
    callMethodInParentComponent() {
      this.$emit("callMethodInParent");
    },
  },
};

</script>

Прослушивание события в родительском компоненте:

<template>

  <child-component v-on:callMethodInParent="callMethodInParent">
  </child-component>

</template>

Заключение

Итак, теперь, когда я показал вам некоторые из моих любимых способов вызова метода компонентов вне компонента, вы все равно можете задать один вопрос. Какой выбрать? И это вполне понятно, потому что я на самом деле не ответил на вопрос, и вот почему: нет единого правильного способа сделать это, поскольку некоторые из упомянутых выше методов работают только в определенных сценариях, и поэтому не существет лучшей практики. Выбор зависит от того, какое отношение имеет ваш компонент к другому компоненту, из которого вы хотите вызвать метод, и, конечно, от того, что вы предпочитаете или что уже используется в проекте, над которым вы работаете.

Я надеюсь, что эта статья была для вас полезной или, возможно, эта статья приблизила вас к решению задачи выбора варианта для вызова метода компонентов вне текущего компонента в вашем проекте.

Была ли вам полезна эта статья?
[9 / 4.6]

Spread the love
Подписаться
Уведомление о
guest
3 Комментарий
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Нариман
Нариман
2 лет назад

Как вызывать понятно, а вот как передать параметры например?
Для примера можно взять последний случай когда из потомка вызываем метод родителя

Сергей
Сергей
2 лет назад
Reply to  Нариман

Когда эмитите в дочернем компоненте, вторым значением передавайте параметр (объект параметров)

this.$emit("call-method-in-parent", yourValue);

А в родительском компоненте, во время обработки эмита, вызывайте существующий метод, в котором указываете в скобках имя принимаемого параметра

<child-component v-on:call-method-in-parent="yourMethodInParent">  </child-component>
 methods: {   
   yourMethodInParent(yourValueFromChild) { } 
 }
Антон
Антон
2 лет назад

C методом $emit все почти так, как написано, но есть одно но. Кастомное событие не всплывает из дочернего компонента к родительскому. Поэтому вместо $emit я использую dispatchEvent c указанием опции всплытия:

this.$el.dispatchEvent(new CustomEvent(‘show-not-available’, { bubbles: true }))