Перевод: Jannick Holm Vue.js — How I call a method in a component from outside the component in Vue 2
Иногда нам приходится делать вызов метода в компоненте вне этого компонента. Но как именно это сделать? Существует несколько способов, но какой из них лучший?
В этой статье я попытаюсь ответить на этот вопрос, показать, какой мне нравится больше, и привести несколько примеров кода, показывающих, как вы можете реализовать некоторые из моих любимых методов в своем приложении Vue.
И так, приступим.
Один из способов сделать это — использовать шину событий (Event Bus). Шину событий можно использовать в большинстве сценариев: от одного компонента к другому ( sibling-to-sibling ), от двоюродного компонента к двоюродному компоненту ( cousin-to-cousin ), от родительского компонента к дочернему( parent-to-child ), от дочернего компонента к родительскому ( child-to-parent ). Что касается шины событий, я бы порекомендовал вам использовать ее в случае вызова метода в сценарии sibling-to-sibling или cousin-to-cousin . Почему? Потому что я считаю, что есть другие более удобные способы для других сценариев.
По сути, шина событий — это экземпляр Vue.js, который может генерировать события в одном компоненте, а затем ожидать (прослушивать) и реагировать на генерируемое событие в другом компоненте.
Есть два способа реализовать шину событий:
Свойство экземпляра — это свойство (или переменная), которое вы хотите сделать доступным глобальным для всех ваших компонентов, не загрязняя глобальную область видимости.
Хорошо, это звучит действительно круто, но как мне это реализовать в моем приложении? Отличный вопрос, на самом деле это довольно просто:
import Vue from 'vue'; Vue.prototype.$eventBus = new Vue();
И затем вы можете получить к нему доступ в любом месте вашего приложения следующим через переменную: this.$eventBus
Другой способ реализации шины событий — в виде модуля ES6. Поначалу это может показаться пугающим, но это на самом деле не так уж сложно и может быть реализовано всего несколькими строками кода.
Во-первых, нам нужно создать модуль ES6. Для этого сделаем следующее:
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>
Использование свойства $refs — отличный и простой способ вызова метода компонентов из родительского компонента, поэтому для ссылки на вышеупомянутые сценарии это будет сценарий «родитель-потомок».
Свойство $refs используется для ссылки на элементы DOM в шаблонах экземпляра Vue.
Чтобы использовать свойство $refs, присвойте ссылочный идентификатор дочернему компоненту, на который вы хотите ссылаться, с помощью атрибута ref. Например:
<template> <child-component ref="childComponent"></child-component> </template>
Теперь мы можем получить доступ к методам дочерних компонентов, а затем вызвать метод непосредственно из родительского компонента следующим образом:
<script> export default { methods: { callMethodInChildComponent() { this.$refs.childComponent.methodInChild(); }, }, }; </script>
Еще один способ вызова метода компонентов вне компонента это использовать свойство $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>
Итак, теперь, когда я показал вам некоторые из моих любимых способов вызова метода компонентов вне компонента, вы все равно можете задать один вопрос. Какой выбрать? И это вполне понятно, потому что я на самом деле не ответил на вопрос, и вот почему: нет единого правильного способа сделать это, поскольку некоторые из упомянутых выше методов работают только в определенных сценариях, и поэтому не существет лучшей практики. Выбор зависит от того, какое отношение имеет ваш компонент к другому компоненту, из которого вы хотите вызвать метод, и, конечно, от того, что вы предпочитаете или что уже используется в проекте, над которым вы работаете.
Я надеюсь, что эта статья была для вас полезной или, возможно, эта статья приблизила вас к решению задачи выбора варианта для вызова метода компонентов вне текущего компонента в вашем проекте.
Краткий перевод: https://vuejs.org/guide/components/v-model.html Основное использование v-model используется для реализации двусторонней привязки в компоненте. Начиная с Vue…
Сегодня мы рады объявить о выпуске Vue 3.4 «🏀 Slam Dunk»! Этот выпуск включает в…
Vue.js — это универсальный и адаптируемый фреймворк. Благодаря своей отличительной архитектуре и системе реактивности Vue…
Недавно, у меня истек сертификат и пришлось заказывать новый и затем устанавливать на хостинг с…
Каким бы ни было ваше мнение о JavaScript, но всем известно, что работа с датами…
Все, кто следит за последними событиями в мире адаптивного дизайна, согласятся, что введение контейнерных запросов…
View Comments
Как вызывать понятно, а вот как передать параметры например?
Для примера можно взять последний случай когда из потомка вызываем метод родителя
Когда эмитите в дочернем компоненте, вторым значением передавайте параметр (объект параметров)
А в родительском компоненте, во время обработки эмита, вызывайте существующий метод, в котором указываете в скобках имя принимаемого параметра
C методом $emit все почти так, как написано, но есть одно но. Кастомное событие не всплывает из дочернего компонента к родительскому. Поэтому вместо $emit я использую dispatchEvent c указанием опции всплытия:
this.$el.dispatchEvent(new CustomEvent('show-not-available', { bubbles: true }))