从子组件 Vue 更新父模型
Posted
技术标签:
【中文标题】从子组件 Vue 更新父模型【英文标题】:Update parent model from child component Vue 【发布时间】:2017-05-30 12:02:39 【问题描述】:我有一个非常小的应用程序,它有一个捐赠表格。该表单将引导用户完成填写信息的步骤。我有一个主要组件,它是表单包装器和包含所有表单数据(模型)的主 Vue 实例。所有子组件都是捐赠过程中的步骤。每个子组件都有要填写的输入字段,这些字段将更新父模型,以便我在提交表单时拥有父模型中的所有表单数据。以下是组件的组合方式:
<donation-form></donation-form> // Main/Parent component
donation-form
组件内部:
<template>
<form action="/" id="give">
<div id="inner-form-wrapper" :class="sliderClass">
<step1></step1>
<step2></step2>
<step3></step3>
</div>
<nav-buttons></nav-buttons>
</form>
</template>
现在,我正在从每个子组件中的输入中设置数据,然后我有一个 watch
方法来监视要更新的字段,然后我通过这样做将它们推送到 $root
。 .
watch:
amount()
this.$root.donation.amount = this.amount;
问题是我的步骤之一是我有很多字段,而且我似乎正在编写一些重复的代码。另外,我确信这不是最好的方法。
我尝试将数据作为prop
传递给我的子组件,但似乎我无法更改子组件中的道具。
除了为我的子组件中的每个值添加监视之外,还有什么更好的方法来更新根实例,甚至是父实例?
更多示例
这是我的step2.vue
文件-step2 vue file
这是我的donation-form.vue
文件-donation-form vue file
【问题讨论】:
【参考方案1】:我个人更喜欢在处理表单时使用通用函数来更新父级,而不是为每个子级编写一个方法。为了说明——有点浓缩——像这样在父级中:
<template lang="pug">
child-component(:field="form.name" fieldname="name" @update="sync")
</template>
<script>
export default
methods:
sync: function(args)
this.form[args.field] = args.value
</script>
在子组件中:
<template lang="pug">
input(@input="refresh($event.target.value)")
</template>
<script>
export default
props: ['field', 'fieldname'],
methods:
refresh: function(value)
this.$emit('update', 'value': value, 'field': this.fieldname);
</script>
【讨论】:
很好的例子,你在父元素中不用vuex?【参考方案2】:您可以使用custom events 发回数据。
要使用自定义事件,您的数据应该在父组件中,并作为道具传递给子组件:
<step1 :someValue="value" />
现在你想从孩子那里接收更新的数据,所以给它添加一个事件:
<step1 :someValue="value" @update="onStep1Update" />
您的子组件将发出事件并将数据作为参数传递:
this.$emit('update', newData)
父组件:
methods:
onStep1Update (newData)
this.value = newData
这是一个带有自定义事件的简单示例:http://codepen.io/CodinCat/pen/QdKKBa?editors=1010
如果所有的step1、step2和step3都包含大量的字段和数据,你可以将这些数据封装在子组件中(如果父组件不关心这些行数据)。
所以每个孩子都有自己的数据并与<input />
绑定
<input v-model="data1" />
<input v-model="data2" />
但同样,您将通过事件将结果数据发回。
const result = this.data1 * 10 + this.data2 * 5
this.$emit('update', result)
(同样,如果您的应用程序变得越来越复杂,vuex 将是解决方案。
【讨论】:
谢谢!这就是我需要做的。非常感谢。 我在上面的 codepen 中看到输出中恰好有一个“输入”,即使应用程序声明应该有 2 个(子 v1 和子 v2)。你能解释一下为什么会这样吗?谢谢 @Catalin 哎呀,子元素没有正确关闭。我已经修复了 codepen,谢谢。<child />
不起作用。应该是<child></child>
【参考方案3】:
对于您的情况,您可以使用 v-model,如下所示:
<form action="/" id="give">
<div id="inner-form-wrapper" :class="sliderClass">
<step1 v-model="step1Var"></step1>
<step2 v-model="step2Var"></step2>
<step3 v-model="step3Var"></step3>
</div>
<nav-buttons></nav-buttons>
</form>
v-model 本质上是用于更新用户输入事件数据的语法糖。
<input v-model="something">
只是语法糖:
<input v-bind:value="something" v-on:input="something = $event.target.value">
您可以在子组件中传递一个 prop : value
,并在更改输入字段调用后更改 step1Var
变量。
this.$emit('input', opt)
您可以查看answer,您可以在其中看到此类组件的实现,其中变量通过 v-model 传递。
【讨论】:
以上是关于从子组件 Vue 更新父模型的主要内容,如果未能解决你的问题,请参考以下文章