# Передаем данные из child в parent в Vue

08:09
poster
В этом видео мы с вами разберем, как можно передавать данные из child компоненты в parent.
Понравилось? Поделитесь с друзьями!
Понравилось?
Поделитесь с друзьями!
Комментарии
Текст видео

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

В Vue есть несколько способов сделать это. На данный момент у меня создан пустой проект webpack-simple из vue-cli и в нем есть только компонент App.

Давайте создадим этот дочерний компонент с логин формой. В ней должно быть два инпута, для логина и пароля и кнопка submit.

LoginForm.vue

<template>
  <div>
    <h3>Login form</h3>
    <div>
      <div>
        <label>Email:</label>
        <input type='text' />
      </div>
      <div>
        <label>Password:</label>
        <input type='password' />
      </div>
      <div>
        <button>Login</button>
      </div>
    </div>
  </div>
</template>

Также, мы должны импортировать наш компонент в App и добавить в локальные компоненты.

App.vue

import loginForm from './LoginForm.vue'

export default {
  ...
  components: {
    loginForm
  }
}

Теперь мы можем отрендерить нашу форму в шаблоне App.

App.vue

<loginForm />

Как мы видим, наша форма успешно отрендерилась в браузере.

Теперь давайте добавить v-model для инпутов.

LoginForm.vue

<input type='text' v-model='email' />
...
<input type='password' v-model='password' />

Мы также должны создать значения по умолчанию для email и password.

LoginForm.vue

data () {
  return {
    email: '',
    password: ''
  }
}

Теперь нам нужно навесить клик и создать метод, который будет вызываться.

LoginForm.vue

<button @click='login'>Login</button>
methods: {
  login () {
    console.log('login', this.email, this.password)
  }
}

Как мы видим в браузере, наш компонент успешно работает и мы получаем емейл и пароль внутри метода login.

Как же мы теперь можем передать эти данные в парент?

Первый способ, это с использованием this.$emit. emit построен на принципе publish/subscribe. Если вы не помните, что это за паттерн, то я оставлю ссылку на видео про этот паттерн в тексте видео. Идея заключается в том, что мы емитим что-то в чайл компоненте и случаем этот евент в парент компоненте.

LoginForm.vue

methods: {
  login () {
    this.$emit('login', {
      email: this.email,
      password: this.password
    })
  }
}

Здесь мы вызвали $emit функцию внутри логин метода. Первым аргументом мы передает имя евента. Это может быть любая строка. Вторым аргументом мы передаем данные, которые относятся к этому евенту. В нашем случае мы передаем емейл и пароль в обьекте.

Теперь мы можем слушать этот емит в нашем App компоненте. Мы должны добавит кастомный евент с таким же именем, с которым мы эмитили евент.

App.vue

<loginForm @login='onLogin' />

То есть, мы хотим вызвать метод onLogin, когда LoginForm заэмитила логин евент. И давайте добавим onLogin метод

App.vue

methods: {
  onLogin (data) {
    console.log('child component said login', data)
  }
}

Как вы видите, в onLogin мы получим первым параметром данные, которые мы передали в emitе. Если мы посмотрим в браузер, то все работает.

Итак еще раз, как это работает.

  1. login метод вызывается при клике в чайлде
  2. Мы эмитим login евент и пробрасываем туда наши данные
  3. В паренте мы случаем этот login евент на чайлде и вызываем onLogin, когда он происходит.

В этом случае наши child и parent компоненты абсолютно не связаны. Это конечно хорошо, но в этом и минус. Мы никогда не узнаем, у действительно ли парент слушает наш емит.

Есть также и другой способ передать данные из чайлда в парент. И это больше способ в стиле React и на мой взгляд он более наглядный, так как код легче дебажить. Мы можем просто передать в child компонент функцию из parent компонента и вызывать ее когда нам нужно.

Давайте изменим loginForm, чтобы мы могли передавать функцию.

App.vue

<loginForm :onLogin='onLogin' />

Не забывайте, что мы использовали v-bind, чтобы пробросить onLogin. Теперь мы должны добавить onLogin в props логин формы.

LoginForm.vue

export default {
  props: ['onLogin']
  ...
}

Теперь мы можем вместо эмита вызвать onLogin метод и получить такой же результат.

LoginForm.vue

login () {
  this.onLogin({
    email: this.email,
    password: this.password
  })
}

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

Если у вас возникли какие-то вопросы или комментарии, пишите их прямо под этим видео.

Только зарегистрированные пользователи могут оставлять комментарии.  Войдите, пожалуйста.
Moe Green
1 месяц назад назад
вау! первый раз вижу, как во Vue прокидывают метод из родительского компонента в дочерний, через props )) сейчас понемногу учу react и как раз познакомился на днях с таким способом там )
monsterlessons
1 месяц назад назад
На самом деле этим Vue и плох. Там есть много разных подходов и они не учат чему-то хорошему. Тот же Реакт пушит 1 подход. И это очень хорошо. А тут и pubsub, и прокидывание функций, и props validation какие-то обрезанные.