В React вы можете передавать функции как свойства от родительского к дочернему компоненту. Затем вызов функции передается обратно от дочернего к родительскому, облегчая взаимодействие родительско-дочернего компонента. Это также можно сделать в Vue.js, используя следующий код:

<template>
  <Child :callback="doSomething" />
</template>

<script>
  export default {
    name: 'Parent',

    methods: {
      doSomething() {
        //
      }
    }
  }
</script>

А в дочернем компоненте вы получаете функцию как опору:

<template>
  <a @click="execute">Execute action</a>
</template>

<script>
  export default {
    props: {
      callback: {
        type: Function
      }
    },

    methods: {
      execute() {
        // ... do something here

        if (this.callback) {
          this.callback()
        }
      }
    }
  }
</script>

Пользовательские события Vue.js в качестве альтернативы

Хотя это сработает отлично, в Vue это в основном считается антипаттерном. Передавая функции в качестве свойств, вы связываете оба родительских дочерних компонента вместе с помощью двусторонней привязки данных. В приведенном выше примере дочерний элемент теперь должен знать о контексте свойства функции от своего родителя. Каждый раз, когда запускается execute, он должен проверять и выполнять переданную функцию callback.

По мере повторного использования этого дочернего компонента вы начинаете получать разные callback функции, передаваемые от разных родителей. По мере того, как приложение увеличивается в размерах и к нему присоединяются другие разработчики, они будут смотреть на код дочернего компонента и должны выяснить, какая callback функция является опорой и откуда она взялась.

Вместо этого Vue.js имеет систему настраиваемых событий, которая выполняет то же самое:

# Parent
<template>
  <Cat @onHappy="doSomething" />
</template>

<script>
  export default {
    name: 'Parent',

    methods: {
      doSomething() {
        //
      }
    }
  }
</script>

# Child Cat component
<script>
  export default {
    methods: {
      eats() {
        this.$emit('onHappy')
      }
    }
  }
</script>

Каждый раз, когда вызывается метод eats в компоненте Cat, он генерирует событие onHappy. Затем родитель может прослушивать событие onHappy и вызывать соответствующую функцию. Поскольку данные передаются только в одном направлении, отладка также значительно упрощается.

Случай для передачи функций как реквизита

Одним из преимуществ передачи функций в качестве реквизита является то, что это делает код намного чище и DRYer. Вместо того, чтобы генерировать и прослушивать события, вы передаете функцию и вызываете ее из дочернего элемента. Хотя в большинстве случаев это не очень хорошая идея, если у вас есть два компонента, которые в любом случае необходимо соединить вместе, а дочерний компонент не используется повторно в других сценариях, это может быть хорошим подходом для рассмотрения. С учетом сказанного, события должны быть главным подходом большую часть времени, и использовать это следует с максимальной осторожностью.

Этот пост был впервые написан в моем личном блоге, где вы можете найти больше сообщений, связанных с Javascript и Vue.js. Не стесняйтесь обращаться ко мне напрямую через LinkedIn или Twitter.