我开始玩vuejs(2.0)。 我构建了一个包含一个组件的简单页面。 该页面有一个带有数据的Vue实例。 在那个页面上,我注册并将组件添加到html中。 组件有一个输入[type=text]。我希望该值反映在父实例(主Vue实例)上。
如何正确地更新组件的父数据? 从父对象传递绑定道具是不好的,会向控制台抛出一些警告。他们的文件里有一些东西,但不管用。
我开始玩vuejs(2.0)。 我构建了一个包含一个组件的简单页面。 该页面有一个带有数据的Vue实例。 在那个页面上,我注册并将组件添加到html中。 组件有一个输入[type=text]。我希望该值反映在父实例(主Vue实例)上。
如何正确地更新组件的父数据? 从父对象传递绑定道具是不好的,会向控制台抛出一些警告。他们的文件里有一些东西,但不管用。
当前回答
介绍
我正在寻找在vue3中从父母发送数据给孩子(并返回)(我知道这个问题是关于ve2的,但当时在SO上没有关于vue3的参考)。
下面是工作的样板结果,纯粹的“html + js”,没有打包器,模块,等等,我解释说。
注:
插入子线 <component-a:foo="bar" @newfooevent="bar = $event"></component-a> '
我绑定父母。酒吧给孩子。Foo使用速记:Foo ="bar",与v-bind: Foo ="bar"相同。它通过道具将数据从父节点传递给子节点。 警告:事件监听器应该只放在子组件标签中! 这就是@newfooevent="bar = $event"部分。 你不能在<div id="app">或父类中的任何地方捕获信号。 不过,这是父进程的部分,在这里您可以访问所有父进程的数据,并从子进程的信号中提取数据来处理它。
You can create app, and define component after it (the app.component("component-a", ...) part. Caveat: there are no need in forward declaration of components, e.g. functions in C/C++. You can create app which uses the component, and define the component afterwards. I lost a lot of time looking for the way to declare it somehow - no need. Here you can find a nice example of the v-model usage, and the code I used to sort things out: https://javascript.plainenglish.io/vue-3-custom-events-d2f310fe34c9
这个例子
<!DOCTYPE html> <html lang="en"> <head> <title>App</title> <meta charset="utf-8" /> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="app"> <component-a :foo="bar" @newfooevent="bar = $event"></component-a> <p>Parent copy of `bar`: {{ bar }}</p> <button @click="bar=''">Clear</button> </div> <script> const app = Vue.createApp({ data() { return { bar: "bar start value" }; } }); app.component("component-a", { props: { foo: String }, template: ` <input type="text" :value="foo" @input="$emit('newfooevent', $event.target.value)"> ` }); app.mount("#app"); </script> </body> </html>
其他回答
正确的方法是$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
}
}
});
在父组件中——>
数据:function(){ 返回{ siteEntered: false, }; },
在子组件中——>
这个。父母。美元数据。siteEntered = true;
子组件
使用这个。$emit('event_name')向父组件发送一个事件。
父组件
为了在父组件中监听该事件,我们执行v-on:event_name,并在该事件发生时执行一个方法(例如handleChange)
:完成)
更简单的方法是使用这个。$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
双向绑定在Vue 2.0中已弃用,转而使用事件驱动的体系结构。一般来说,孩子不应该改变它的道具。相反,它应该$emit事件并让父进程响应这些事件。
在您的特定情况下,您可以使用带有v-model的自定义组件。这是一种特殊的语法,它允许一些接近双向绑定的东西,但实际上是上面描述的事件驱动体系结构的简写。你可以在这里阅读-> https://v2.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,以及为什么子对象需要$emit一个名为input的事件。