我在我正在使用的网络应用中创建了很多表单,我正在使用Vue,所以我一直在尝试创建一个我可以使用的通用输入组件始终。我使用的是Bootstrap网格,因此我的想法是我应该能够传递组件的多个列,标签,名称和属性以用作v模型。我想,我有点到达那里,但我遇到了变异道具的问题 - [Vue警告]:避免直接改变道具,因为只要父组件重新渲染,该值就会被覆盖。而是根据prop的值使用数据或计算属性。支持变异:"模型" (在组件中找到)。 这是模板(简化形式):
<template id="field">
<div v-bind:class="colsClass">
<div class='form-group form-group-sm'>
<label v-bind:for="name">{{labelText}}</label>
<input v-bind:id='name' ref="input" class='form-control' v-bind:name='name' v-model='model'/>
</div>
</div>
这是(再次简化)JS:
Vue.component('field', {
template: '#field',
props: ['cols','label','group','name','model'],
computed:{
colsClass:function(){
return "col-xs-"+this.cols
}
,
labelText:function(){
if(this.label) {
return this.label
} else {
return _.startCase(this.name);
}
}
}
});
这是在另一个&#39;编辑产品中使用的。组件,像这样:
<field :cols="8" name="name" :model="product.name"></field>
这会显示OK,但是当我编辑字段的值时会抛出错误(或更准确地说,警告)。那么我做错了什么?
答案 0 :(得分:1)
正如警告所示,你不应该直接编辑你传递的道具。
而是将其用作原始值并在其输入上设置单独的值 - 您可以将其传递给v模型。如果您需要父项具有当前值,那么还要传递一个支柱,允许您更新父项的参数,即
输入组件
# script
props: [
'origValue',
'valueChange',
],
data: {
inputValue: '',
...
},
mounted () {
this.inputValue = this.origValue
},
watch: {
inputValue () {
this.valueChange(this.inputValue)
},
...
},
...
# template
<input type="text" v-model="inputValue">
<强>父强>
# script
data () {
return {
fieldValue: 'foo',
...
},
},
methods: {
updateField (value) {
this.fieldValue = value
},
...
},
...
# template
<field :value-change="updateField" :orig-value="fieldValue"></field>
答案 1 :(得分:1)
实际上,我所采用的解决方案比上面提到的解决方案简单得多,实际上非常简单,取自https://forum-archive.vuejs.org/topic/4468/trying-to-understand-v-model-on-custom-components/9。
我不想要'模型'道具,我有一个“值”,所以JS改为:
Vue.component('field', {
template: '#field',
props: ['cols','label','group','name','value'],
computed:{
colsClass:function(){
return "col-xs-"+this.cols
}
,
labelText:function(){
if(this.label) {
return this.label
} else {
return _.startCase(this.name);
}
}
}
});
模板变为:
<div class='form-group form-group-sm'>
<label :for="name">{{labelText}}</label>
<input :id='name' :name='name' class='form-control' :value="value" @input="$emit('input', $event.target.value)"/>
</div>
</div>
我这样使用它:
<field :cols="8" name="name" v-model="product.name"></field>
不同之处在于我实际上并没有尝试传递模型支撑,我只是传递一个值,并且正在侦听对该值的更改。它似乎工作得很好,干净,简单。我的下一个挑战是将一组任意属性传递给输入,但这是另一个问题的主题。