在我的数据对象中,我需要将对象推送到一个名为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"
},
...
]
谁能就如何实现这一目标提供建议?
行不通。我得到一个
TypeError: _vm.editions[n] is undefined
.
editions
最初是一个空数组,因此editions[n]
对所有n
都undefined
。Vue 本质上是这样做的:
const editions = []
const n = 1
console.log(editions[n]) // => undefined
奇怪的是,如果我尝试这样做:
v-model="editions[n]"
...它有效
当您在v-model
中使用editions[n]
时,您实际上是在索引n
处使用新值创建数组项。Vue 正在做类似的事情:
const editions = []
const n = 2
editions[n] = 'foo'
console.log(editions) // => [ undefined, undefined, "foo" ]
要解决根本问题,请使用长度等于total_number_of_editions
的对象数组初始化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
可以动态更改,请对变量使用观察程序,并根据新计数更新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>