Gal*_*Ziv 106 javascript vue.js vue-component
我开始玩vuejs(2.0).我构建了一个包含一个组件的简单页面.该页面有一个带有数据的Vue实例.在那个页面上,我注册并将组件添加到html.该组件有一个input[type=text]
.我希望该值反映在父(主Vue实例)上.
如何正确更新组件的父数据?从父级传递绑定的prop并不好,并向控制台发出一些警告.他们的文档中有一些东西,但它不起作用.
ase*_*hle 139
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'
}
});
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)
文档说明了这一点
<custom-input v-bind:value="something" v-on:input="something = arguments[0]"></custom-input>
Run Code Online (Sandbox Code Playgroud)
相当于
<custom-input v-model="something"></custom-input>
Run Code Online (Sandbox Code Playgroud)
这就是为什么孩子的道具需要被命名为值,以及为什么孩子需要$发出一个名为的事件input
.
Sau*_*abh 103
从文档:
在Vue.js中,父子组件关系可以概括为道具向下,事件向上.父母通过道具将数据传递给孩子,孩子通过事件向父母发送消息.让我们看看他们下一步如何运作.
以下是将props传递给子元素的代码:
<div>
<input v-model="parentMsg">
<br>
<child v-bind:my-message="parentMsg"></child>
</div>
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
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
}
}
})
Run Code Online (Sandbox Code Playgroud)
Sar*_*oev 47
在子组件中:
__CODE__
在父组件中:
this.$emit('eventname', this.variable)
Run Code Online (Sandbox Code Playgroud)
Dar*_*ich 12
更简单的方法是使用 this.$emit
父亲.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>
Run Code Online (Sandbox Code Playgroud)
儿童.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>
Run Code Online (Sandbox Code Playgroud)
我的完整示例:https : //codesandbox.io/s/update-parent-property-ufj4b
小智 10
子组件
使用this.$emit('event_name')
发送事件到母部件。
父组件
为了在父组件中监听该事件,我们执行v-on:event_name
了一个ex. handleChange
要在该事件上执行的方法()
完成:)
在父组件中 -->
Run Code Online (Sandbox Code Playgroud)data : function(){ return { siteEntered : false, }; },
在子组件中 -->
this.$parent.$data.siteEntered = true;
也可以将 props 作为 Object 或 Array 传递。在这种情况下,数据将被双向绑定:
(这在主题末尾注明: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;
}
}
});
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)
小智 6
我同意上述情况的事件发出和v模型答案。但是,我以为我会发布有关具有多个表单元素的组件的信息,这些组件想要发回给它们的父对象,因为这似乎是google返回的第一篇文章之一。
我知道这个问题指定了单个输入,但是这似乎是最接近的匹配,并且可以通过类似的vue组件为人们节省一些时间。另外,还没有人提到.sync
修饰符。
据我所知,该v-model
解决方案仅适用于一个返回其父级的输入。我花了一些时间寻找它,但是Vue(2.3.0)文档确实显示了如何将发送到组件中的多个道具同步回父对象(当然是通过发出)。
它被适当地称为.sync
修饰符。
这里是什么文件说:
在某些情况下,我们可能需要对道具进行“双向绑定”。不幸的是,真正的双向绑定会产生维护问题,因为子组件可以使父项发生变异,而在父项和子项中均不明显该变异的来源。
因此,我们建议您以的模式发出事件
update:myPropName
。例如,在带有title
prop 的假设组件中 ,我们可以通过以下方式传达分配新值的意图:
this.$emit('update:title', newTitle)
Run Code Online (Sandbox Code Playgroud)
然后,如果需要,父级可以侦听该事件并更新本地数据属性。例如:
<text-document
v-bind:title="doc.title"
v-on:update:title="doc.title = $event"
></text-document>
Run Code Online (Sandbox Code Playgroud)
为了方便起见,我们使用.sync修饰符为该模式提供了一个简写形式:
<text-document v-bind:title.sync="doc.title"></text-document>
Run Code Online (Sandbox Code Playgroud)
2021 年答案 - Vue 2.3+
简短回答:只需.sync
在父级中添加修饰符并将数据作为 props 传递给子级:
// 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" />
Run Code Online (Sandbox Code Playgroud)
嵌套子组件: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)
}
}
}
Run Code Online (Sandbox Code Playgroud)
长话短说:子组件的更改实际上正在 $emit 并更新formData.members[]
父组件。
资料来源:Mauro Perez,媒体
归档时间: |
|
查看次数: |
106272 次 |
最近记录: |