VueJS 动态数据 + V 模型



在我的数据对象中,我需要将对象推送到一个名为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]对所有nundefined。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>

最新更新