我开始玩vuejs(2.0)。 我构建了一个包含一个组件的简单页面。 该页面有一个带有数据的Vue实例。 在那个页面上,我注册并将组件添加到html中。 组件有一个输入[type=text]。我希望该值反映在父实例(主Vue实例)上。
如何正确地更新组件的父数据? 从父对象传递绑定道具是不好的,会向控制台抛出一些警告。他们的文件里有一些东西,但不管用。
我开始玩vuejs(2.0)。 我构建了一个包含一个组件的简单页面。 该页面有一个带有数据的Vue实例。 在那个页面上,我注册并将组件添加到html中。 组件有一个输入[type=text]。我希望该值反映在父实例(主Vue实例)上。
如何正确地更新组件的父数据? 从父对象传递绑定道具是不好的,会向控制台抛出一些警告。他们的文件里有一些东西,但不管用。
当前回答
我不知道为什么,但我刚刚成功地更新了使用数据作为对象的父数据,:set & computed
Parent.vue
<!-- check inventory status - component -->
<CheckInventory :inventory="inventory"></CheckInventory>
data() {
return {
inventory: {
status: null
},
}
},
Child.vue
<div :set="checkInventory">
props: ['inventory'],
computed: {
checkInventory() {
this.inventory.status = "Out of stock";
return this.inventory.status;
},
}
其他回答
更简单的方法是使用这个。$emit
Father.vue
<template>
<div>
<h1>{{ message }}</h1>
<child v-on:listenerChild="listenerChild"/>
</div>
</template>
<script>
import Child from "./Child";
export default {
name: "Father",
data() {
return {
message: "Where are you, my Child?"
};
},
components: {
Child
},
methods: {
listenerChild(reply) {
this.message = reply;
}
}
};
</script>
Child.vue
<template>
<div>
<button @click="replyDaddy">Reply Daddy</button>
</div>
</template>
<script>
export default {
name: "Child",
methods: {
replyDaddy() {
this.$emit("listenerChild", "I'm here my Daddy!");
}
}
};
</script>
完整示例:https://codesandbox.io/s/update-parent-property-ufj4b
我同意上述事件发射和v模型的答案。但是,我认为我应该发布我所发现的关于具有多个表单元素的组件,这些元素想要发射回它们的父元素,因为这似乎是谷歌返回的第一批文章之一。
我知道这个问题指定了单个输入,但这似乎是最接近的匹配,并且可以为使用类似vue组件的人节省一些时间。此外,还没有人提到.sync修饰符。
据我所知,v模型解决方案只适合一个输入返回到它们的父。我花了一些时间寻找它,但Vue(2.3.0)文档确实展示了如何将发送到组件中的多个道具同步回父组件(当然是通过emit)。
它被恰当地称为.sync修饰符。
以下是文档的内容:
在某些情况下,我们可能需要对道具进行“双向绑定”。 不幸的是,真正的双向绑定会产生维护问题, 的源可以使父组件发生变异 这种突变在父母和孩子身上都很明显。 这就是为什么我们建议以模式发出事件的原因 更新:myPropName。例如,在一个假设的组件中 标题道具,我们可以传达分配新值的意图 :
this.$emit('update:title', newTitle)
然后家长就可以听了 并更新本地数据属性(如果需要的话)。为 例子:
<text-document
v-bind:title="doc.title"
v-on:update:title="doc.title = $event"
></text-document>
为了方便起见,我们用.sync修饰符提供了这种模式的简写:
<text-document v-bind:title.sync="doc.title"></text-document>
你也可以通过一个对象同时同步多个对象。在这里查看文档
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文档
他的例子将告诉你如何通过提交按钮将输入值传递给父节点。
首先将eventBus定义为新的Vue。
//main.js
import Vue from 'vue';
export const eventBus = new Vue();
Pass your input value via Emit.
//Sender Page
import { eventBus } from "../main";
methods: {
//passing data via eventbus
resetSegmentbtn: function(InputValue) {
eventBus.$emit("resetAllSegment", InputValue);
}
}
//Receiver Page
import { eventBus } from "../main";
created() {
eventBus.$on("resetAllSegment", data => {
console.log(data);//fetching data
});
}
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