我开始玩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
    }

其他回答

在子组件中:

this.$emit('eventname', this.variable)

在父组件中:

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

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

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

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

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

当我们想要将数据传递给父组件以及当前子组件的另一个嵌套子组件时,使用data属性将非常有用,如下面的示例所示。

例子: 像这样从父组件调用子组件。

父组件:

<template>
  <TodoItem :todoParent="todo" />
</template>

<script>
export default {
  data() {
    return {
      todo: {
        id:1,
        task:'todo 1',
        completed:false
      }
    };
  }
}
</script>

子组件:

<template>
  <div class="todo-item" v-bind:class="{'is-completed':todo.completed}">
    <p>
      <input type="checkbox" @change="markCompleted" />
      {{todo.task}}
      <button class="del">x</button>
    </p>
  </div>
</template>

<script>
export default {
  name: "TodoItem",
  props: ["todoParent"],
  data() {
    return {
      todo: this.todoParent,
    };
  },
  methods: {
    markCompleted() {
      this.todo.completed = true
    },
  },
};
</script>

即使你可以将这个属性传递给嵌套的子组件,它也不会给出这个错误/警告。

当您只需要在父组件和子组件之间同步此属性时的其他用例。可以使用Vue中的同步修改器来实现。v型模型也很有用。在这个问题中还有许多其他的例子。

Example2:使用组件事件。 我们可以从子组件发出事件,如下所示。

父组件:

<template>
  <TodoItem :todo="todo" @markCompletedParent="markCompleted" />
</template>

<script>
export default {
  data() {
    return {
      todo: {
        id:1,
        task:'todo 1',
        completed:false
      }
    };
  },
  methods: {
    markCompleted() {
      this.todo.completed = true
    },
  }
}
</script>

子组件:

<template>
  <div class="todo-item" v-bind:class="{'is-completed':todo.completed}">
    <p>
      <input type="checkbox" @change="markCompleted" />
      {{todo.task}}
      <button class="del">x</button>
    </p>
  </div>
</template>

<script>
export default {
  name: "TodoItem",
  props: ["todo"],
  methods: {
    markCompleted() {
      this.$emit('markCompletedParent', true)
    },
  }
};
</script>

There is another way of communicating data change from child to parent which uses provide-inject method. Parent component "provides" data or method for the child component, and this data or method is then "injected" into child component - but it can also be used for triggering a method in parent and passing it a parameter. This approach can be especially useful when having a child component which happens to be embedded in multiple other components. Also, in a large project care must be taken not to lose overview of provide and inject usage.

父组件App.vue使用provider访问它的方法updateParentValue(如果提供了方法而不是数据,则以方法的形式提供)的例子:

<template>
  <h2>App.vue, parentValue is: <em>{{ parentValue }}</em></h2>
  <ChildComponent1 />
</template>

<script>
import ChildComponent1 from "./components/ChildComponent1.vue";

export default {
  data() {
    return {
      parentValue: "",
    };
  },
  components: {
    ChildComponent1,
  },
  provide() {
    return {
      updateParent: this.updateParentValue,
    };
  },
  methods: {
    updateParentValue($value) {
      this.parentValue = $value;
    },
  },
};
</script>

在本例中,组件Component4。vue在“底层”,也就是说,App.vue包含了Component1, Component1包含了Component2…直到Component4,它实际上使用inject来访问父方法,然后调用父方法并传递参数$value(这里只是一个随机数):

<template>
  <div>
    <h2>ChildComponent4.vue</h2>
    <button @click="updateParent(Math.random())">
      Update parent value in App.vue
    </button>
  </div>
</template>

<script>
export default {
  inject: ["updateParent"],
};
</script>

完整的例子可以在这里找到。 Vue.js文档