vue绑定父子组件
Posted
技术标签:
【中文标题】vue绑定父子组件【英文标题】:Vue binding parent and child components 【发布时间】:2018-07-03 22:34:30 【问题描述】:如何在 Vue.js 中将父模型绑定到子模型?
下面的这些代码可以正常工作。如果我手动填写输入,则子模型将其值返回给父模型。
但问题是,如果来自父级的 AJAX 请求的数据集,输入不会自动填充。
谁能帮我解决这个问题?
Form.vue
<template>
<form-input v-model="o.name" :fieldModel="o.name" @listenChanges="o.name = $event"/>
<form-input v-model="o.address" :fieldModel="o.address" @listenChanges="o.address = $event"/>
</template>
<script>
import FormInput from '../share/FormInput.vue'
export default
data ()
return
o:
name: '',
address: ''
,
components: 'form-input': FormInput ,
created: function()
axios.get('http://api.example.com')
.then(response =>
this.o.name = response.data.name
this.o.address = response.data.address
)
.catch(e => console.log(e) )
</script>
FormInput.vue
<template>
<input type="text" v-model='fieldModelValue' @input="forceUpper($event, fieldModel)">
</template>
<script>
export default
props: ['fieldModel'],
data()
return
fieldModelValue: ''
,
mounted: function()
this.fieldModelValue = this.fieldModel;
,
methods:
forceUpper(e, m)
const start = e.target.selectionStart;
e.target.value = e.target.value.toUpperCase();
this.fieldModelValue = e.target.value.toUpperCase();
this.$emit('listenChanges', this.fieldModelValue)
</script>
【问题讨论】:
使用v-bind
而不是v-model
在父模板中,绑定 Props=fieldModel。 如果您利用v-model
in components,事情会变得更简单。
如果您将v-model
放在组件上,该组件应采用名为value
的道具,并应发出input
事件以触发其更新。
我喜欢创建一个computed
来隐藏事件发射,并允许我在我的组件中只使用v-model
computed
。
new Vue(
el: '#app',
data:
o:
name: '',
address: ''
,
components:
'form-input':
template: '#form-input',
props: ['value'],
computed:
fieldModelValue:
get()
return this.value;
,
set(newValue)
this.$emit('input', newValue.toUpperCase());
,
// Simulate axios call
created: function()
setTimeout(() =>
this.o.name = 'the name';
this.o.address = 'and address';
, 500);
);
<script src="//unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">
Name (o.name)
<form-input v-model="o.name"></form-input>
Address (o.address)
<form-input v-model="o.address"></form-input>
</div>
<template id="form-input">
<input type="text" v-model='fieldModelValue'>
</template>
【讨论】:
非常感谢,您的解释帮助我摆脱了this Vue warning,而不会丢失数据同步,终于!【参考方案2】:mounted()
挂钩阻止来自父级的后续更新。
移除挂载并将 v-model 更改为 'fieldModel'
<template>
<input type="text" :value='fieldModel' @input="forceUpper($event, fieldModel)">
</template>
<script>
export default
props: ['fieldModel'],
data()
return
fieldModelValue: ''
,
// mounted: function()
// this.fieldModelValue = this.fieldModel;
// ,
methods:
forceUpper(e, m)
const start = e.target.selectionStart;
e.target.value = e.target.value.toUpperCase();
this.fieldModelValue = e.target.value.toUpperCase();
this.$emit('listenChanges', this.fieldModelValue)
</script>
演示 CodeSandbox
【讨论】:
不要使用v-model
,使用value
。 v-model
是双向的,你想要单向绑定。
如果你在处理返回值,v-model不是,所以它没有做双向绑定。
我在这里评论你的代码,特别是这一行:v-model='fieldModel' @input="forceUpper($event, fieldModel)"
它应该是:value
而不是v-model
,因为你正在分别处理input
事件。跨度>
你的两个答案都达到了目标。顺便说一句,RichardMatsen 的回答给我警告说 避免直接改变道具,因为只要父组件重新渲染,该值就会被覆盖。相反,请使用基于道具值的数据或计算属性。。所以我选择了罗伊的答案。
很公平,他有更全面的答案。以上是关于vue绑定父子组件的主要内容,如果未能解决你的问题,请参考以下文章