我开始玩vuejs(2.0)。 我构建了一个包含一个组件的简单页面。 该页面有一个带有数据的Vue实例。 在那个页面上,我注册并将组件添加到html中。 组件有一个输入[type=text]。我希望该值反映在父实例(主Vue实例)上。

如何正确地更新组件的父数据? 从父对象传递绑定道具是不好的,会向控制台抛出一些警告。他们的文件里有一些东西,但不管用。


当前回答

在孩子身上

 <input
            type="number"
            class="form-control"
            id="phoneNumber"
            placeholder
            v-model="contact_number"
            v-on:input="(event) => this.$emit('phoneNumber', event.target.value)"
    />

data(){
    return {
      contact_number : this.contact_number_props
    }
  },
  props : ['contact_number_props']

在父

<contact-component v-on:phoneNumber="eventPhoneNumber" :contact_number_props="contact_number"></contact-component>


 methods : {
     eventPhoneNumber (value) {
      this.contact_number = value
    }

其他回答

从文档中可以看到:

在Vue.js中,父子组件关系可以概括为向下的道具,向上的事件。父进程通过道具向下传递数据给子进程,子进程通过事件向父进程发送消息。接下来让我们看看它们是如何工作的。

如何传递道具

下面是将道具传递给子元素的代码:

<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
    }
  }
})

2021 ANSWER - Vue 2.3+

简单回答:只需在父类中添加.sync修饰符,并将数据作为道具传递给子类:

    // PARENT:
    data () {
    return {
      formData: {
        members: [] //<- we wanna pass this one down to children and add/remove from the child component
      }
    }

   // PARENT TEMPLATE:
   <!-- ADD MEMBERS -->
  <add-members :members.sync="formData.members" />

嵌套子组件:AddMembers.vue

export default {
  name: 'AddMembers',
  props: ['members'],
  methods: {
    addMember () {
      this.members.push(new Member()) // <-- you can play and reactivity will work (in the parent)  
    },
    removeMember (index) {
      console.log('remove', index, this.members.length < 1)
      this.members.splice(index, 1)
    }
  }
}

说来话长:实际上,来自子组件的更改被$发出并更新formData。父类的成员[]。

来源:Mauro Perez at medium

正确的方法是$emit()主Vue实例侦听的子组件中的事件。

// Child.js
Vue.component('child', {
  methods: {
    notifyParent: function() {
      this.$emit('my-event', 42);
    }
  }
});

// Parent.js
Vue.component('parent', {
  template: '<child v-on:my-event="onEvent($event)"></child>',
  methods: {
    onEvent: function(ev) {
      v; // 42
    }
  }
});

也可以将道具作为对象或数组传递。在这种情况下,数据将是双向绑定的:

(这一点在主题的最后注明:https://v2.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>

在孩子身上

 <input
            type="number"
            class="form-control"
            id="phoneNumber"
            placeholder
            v-model="contact_number"
            v-on:input="(event) => this.$emit('phoneNumber', event.target.value)"
    />

data(){
    return {
      contact_number : this.contact_number_props
    }
  },
  props : ['contact_number_props']

在父

<contact-component v-on:phoneNumber="eventPhoneNumber" :contact_number_props="contact_number"></contact-component>


 methods : {
     eventPhoneNumber (value) {
      this.contact_number = value
    }