vuejs обновляет родительские данные из дочернего компонента



Я начинаю играть с vuejs (2.0).
Я создал простую страницу с одним компонентом в нем.
На странице есть один экземпляр Vue с данными.
На этой странице Я зарегистрировался и добавил компонент в html.
Компонент имеет один input[type=text]. Я хочу, чтобы это значение отражалось на родительском (основном экземпляре Vue).



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

735   4  

4 ответов:

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

в вашем конкретном случае вы можете использовать пользовательский компонент с v-model. Это специальный синтаксис, который допускает что-то близкое к двусторонней привязке, но на самом деле является сокращением для архитектуры, управляемой событиями, описанной выше. Вы можете прочитать об этом здесь - > https://vuejs.org/v2/guide/components.html#Form-Input-Components-using-Custom-Events.

вот простой пример:

Vue.component('child', {
  template: '#child',
  
  //The child has a prop named 'value'. v-model will automatically bind to this prop
  props: ['value'],
  methods: {
    updateValue: function (value) {
      this.$emit('input', value);
    }
  }
});

new Vue({
  el: '#app',
  data: {
    parentValue: 'hello'
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>

<div id="app">
  <p>Parent value: {{parentValue}}</p>
  <child v-model="parentValue"></child>
</div>

<template id="child">
   <input type="text" v-bind:value="value" v-on:input="updateValue($event.target.value)">
</template>

в документах говорится, что

<custom-input v-bind:value="something" v-on:input="something = arguments[0]"></custom-input>

эквивалентно

<custom-input v-model="something"></custom-input>

вот почему опора на ребенка должна быть названа value, и почему ребенок должен $испускать событие с именем input.

С документация:

В Vue.js, отношение родительского и дочернего компонентов можно суммировать как реквизит вниз, события вверх. Родитель передает данные вниз к ребенку через props, и ребенок отправляет сообщения к родителю через события. Давайте посмотрим, как они работают дальше.

enter image description here

как передать реквизит

Ниже приведен код для передачи реквизита ребенку элемент:

<div>
  <input v-model="parentMsg">
  <br>
  <child v-bind:my-message="parentMsg"></child>
</div>

как испустить событие

HTML:

<div id="counter-event-example">
  <p>{{ total }}</p>
  <button-counter v-on:increment="incrementTotal"></button-counter>
  <button-counter v-on:increment="incrementTotal"></button-counter>
</div>

JS:

Vue.component('button-counter', {
  template: '<button v-on:click="increment">{{ counter }}</button>',
  data: function () {
    return {
      counter: 0
    }
  },
  methods: {
    increment: function () {
      this.counter += 1
      this.$emit('increment')
    }
  },
})
new Vue({
  el: '#counter-event-example',
  data: {
    total: 0
  },
  methods: {
    incrementTotal: function () {
      this.total += 1
    }
  }
})

также можно передать реквизит как объект или массив. В этом случае данные будут иметь двустороннюю привязку:

(это отмечено в конце темы:https://vuejs.org/v2/guide/components.html#One-Way-Data-Flow)

Vue.component('child', {
  template: '#child',
  props: {post: Object},
  methods: {
    updateValue: function () {
      this.$emit('changed');
    }
  }
});

new Vue({
  el: '#app',
  data: {
    post: {msg: 'hello'},
    changed: false
  },
  methods: {
    saveChanges() {
        this.changed = true;
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>

<div id="app">
  <p>Parent value: {{post.msg}}</p>
  <p v-if="changed == true">Parent msg: Data been changed - received signal from child!</p>
  <child :post="post" v-on:changed="saveChanges"></child>
</div>

<template id="child">
   <input type="text" v-model="post.msg" v-on:input="updateValue()">
</template>

в дочернем компоненте: this.$emit.('eventname', this.variable)

в Родительском компоненте:

<component @eventname="updateparent"></component>

methods: {
    updateparent(variable) {
        this.parentvariable = variable
    }
}

Comments

    Ничего не найдено.