我开始玩vuejs(2.0)。我构建了一个包含一个组件的简单页面。该页面具有一个带有数据的Vue实例。在该页面上,我注册了该组件并将其添加到html中。该组件有一个input[type=text]
。我希望该值反映在父对象(主Vue实例)上。
如何正确更新组件的父数据?从父级传递绑定的道具不好,并且会向控制台发出一些警告。他们的文档中有内容,但是没有用。
我开始玩vuejs(2.0)。我构建了一个包含一个组件的简单页面。该页面具有一个带有数据的Vue实例。在该页面上,我注册了该组件并将其添加到html中。该组件有一个input[type=text]
。我希望该值反映在父对象(主Vue实例)上。
如何正确更新组件的父数据?从父级传递绑定的道具不好,并且会向控制台发出一些警告。他们的文档中有内容,但是没有用。
Answers:
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>
这就是为什么需要将子项上的prop命名为value的原因,以及子项需要$ emit发出名为的事件的原因input
。
undefined
直到第一次更改。看到我评论过的这个小提琴props: ['value']
。注意初始值是如何undefined
,而不是hello
:jsfiddle.net/asemahle/8Lrkfxj6。第一次更改后,Vue会为组件动态添加一个值道具,因此它可以工作。
从文档中:
在Vue.js中,父子组件关系可以概括为道具下降,事件上升。父级通过道具将数据传递给子级,而子级则通过事件向父级发送消息。让我们看看它们接下来如何工作。
以下是将prop传递给子元素的代码:
<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
}
}
})
在子组件中:
this.$emit('eventname', this.variable)
在父组件中:
<component @eventname="updateparent"></component>
methods: {
updateparent(variable) {
this.parentvariable = variable
}
}
子组件
使用this.$emit('event_name')
发送事件到母部件。
父组件
为了在父组件中监听该事件,我们执行v-on:event_name
了一个ex. handleChange
要在该事件上执行的方法()
完成:)
我同意上述情况的事件发出和v模型答案。但是,我以为我会发布我发现的有关具有多个表单元素的组件的信息,这些组件想要发回给它们的父对象,因为这似乎是google返回的第一篇文章之一。
我知道这个问题指定了单个输入,但是这似乎是最接近的匹配,并且可以通过类似的vue组件为人们节省一些时间。另外,还没有人提到.sync
修饰符。
据我所知,该v-model
解决方案仅适用于返回其父级的一个输入。我花了一些时间寻找它,但Vue(2.3.0)文档确实显示了如何将发送到组件中的多个道具同步回父对象(当然是通过发出)。
它被适当地称为.sync
修饰符。
这里是什么文件说:
在某些情况下,我们可能需要对道具进行“双向绑定”。不幸的是,真正的双向绑定可能会造成维护问题,因为子组件可以使父项发生变异,而在父项和子项中均不明显该变异的来源。
因此,我们建议您以的模式发出事件
update:myPropName
。例如,在带有title
prop 的假设组件中 ,我们可以通过以下方式传达分配新值的意图:
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>
使用更简单的方法 this.$emit
父亲
<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>
小孩
<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
也可以将prop作为对象或数组传递。在这种情况下,数据将被双向绑定:
(这在主题末尾注明: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>
正确的方法是处理$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
}
}
});
1)子组件:您可以在子组件中像这样使用:this.formValue将一些数据发送到父组件
this.$emit('send',this.formValue)
2)Parrent Compnenet:并且在parrent组件标签中接收如下发送变量:这是用于接收父组件标签中的子组件数据的代码
@send="newformValue"
我不知道为什么,但我只是成功更新父数据使用的数据为研究对象,:set
&computed
亲子
<!-- check inventory status - component -->
<CheckInventory :inventory="inventory"></CheckInventory>
data() {
return {
inventory: {
status: null
},
}
},
小孩
<div :set="checkInventory">
props: ['inventory'],
computed: {
checkInventory() {
this.inventory.status = "Out of stock";
return this.inventory.status;
},
}
他的示例将告诉您如何在“提交”按钮上将输入值传递给父对象。
首先将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
});
}