在我的数据对象中,我需要将对象推入名为editions
的数组中。
data() {
return {
editions: []
}
}
为此,我将根据一些预定的字段名称动态创建一个表单。这是问题所在。我无法让v模型进行合作。我期待做这样的事情:
<div v-for="n in parseInt(total_number_of_editions)">
<div v-for="field in edition_fields">
<input :type="field.type" v-model="editions[n][field.name]" />
</div>
</div>
但这不起作用。我得到一个TypeError: _vm.editions[n] is undefined
。奇怪的是,如果我尝试执行以下操作:v-model="editions[n]"
...可以,但是我没有属性名称。所以我不知道如何editions[n]
是不确定的。这就是我要在数据对象中最终得到的结果:
editions: [
{
name: "sample name",
status: "good"
},
...
]
有人可以建议如何实现这一目标吗?
答案 0 :(得分:0)
但这不起作用。我得到一个
TypeError: _vm.editions[n] is undefined
。
editions
最初是一个空数组,因此对于所有editions[n]
,undefined
是n
。 Vue本质上就是这样做的:
const editions = []
const n = 1
console.log(editions[n]) // => undefined
奇怪的是,如果我尝试使用此方法:
v-model="editions[n]"
...有效
在editions[n]
中使用v-model
时,实际上是在索引n
处创建具有新值的数组项。 Vue正在做类似的事情:
const editions = []
const n = 2
editions[n] = 'foo'
console.log(editions) // => [ undefined, undefined, "foo" ]
要解决根本问题,请使用长度等于editions
的对象数组初始化total_number_of_editions
:
const newObjArray = n => Array(n) // create empty array of `n` items
.fill({}) // fill the empty holes
.map(x => ({...x})) // map the holes into new objects
this.editions = newObjArray(this.total_number_of_editions)
如果total_number_of_editions
可以动态更改,请在变量上使用watcher,然后根据新计数更新editions
。
const newObjArray = n => Array(n).fill({}).map(x => ({...x}))
new Vue({
el: '#app',
data() {
const edition_fields = [
{ type: 'number', name: 'status' },
{ type: 'text', name: 'name' },
];
return {
total_number_of_editions: 5,
editions: [],
edition_fields
}
},
watch: {
total_number_of_editions: {
handler(total_number_of_editions) {
const count = parseInt(total_number_of_editions)
if (count === this.editions.length) {
// ignore
} else if (count < this.editions.length) {
this.editions.splice(count)
} else {
const newCount = count - this.editions.length
this.editions.push(...newObjArray(newCount))
}
},
immediate: true,
}
}
})
<script src="https://unpkg.com/vue@2.6.10/dist/vue.min.js"></script>
<div id="app">
<label>Number of editions
<input type="number" min=0 v-model="total_number_of_editions">
</label>
<div><pre>total_number_of_editions={{total_number_of_editions}}
editions={{editions}}</pre></div>
<fieldset v-for="n in parseInt(total_number_of_editions)" :key="n">
<div v-for="field in edition_fields" :key="field.name+n">
<label>{{field.name}}{{n-1}}
<input :type="field.type" v-if="editions[n-1]" v-model="editions[n-1][field.name]" />
</label>
</div>
</fieldset>
</div>