【发布时间】:2018-12-06 13:26:38
【问题描述】:
我有一个包含嵌套对象的数据结构,我想将其绑定到子组件,并且我希望这些组件直接编辑数据结构,以便我可以从一个地方将其全部保存。结构有点像
job = {
id: 1,
uuid: 'a-unique-value',
content_blocks: [
{
id: 5,
uuid: 'some-unique-value',
block_type: 'text',
body: { en: { content: 'Hello' }, fr: { content: 'Bonjour' } }
},
{
id: 9,
uuid: 'some-other-unique-value',
block_type: 'text',
body: { en: { content: 'How are you?' }, fr: { content: 'Comment ça va?' } }
},
]
}
所以,我像这样实例化我的子组件
<div v-for="block in job.content_blocks" :key="block.uuid">
<component :data="block" :is="contentTypeToComponentName(block.block_type)" />
</div>
(contentTypeToComponentName 从text 变为TextContentBlock,这是组件的名称)
TextContentBlock 是这样的
export default {
props: {
data: {
type: Object,
required: true
}
},
created: function() {
if (!this.data.body) {
this.data.body = {
it: { content: "" },
en: { content: "" }
}
}
}
}
created() 函数负责添加添加新 content_blocks 的组件未知的缺失的特定于块的数据,当我想通过特殊按钮动态添加块时,就像这样
addBlock: function(block_type) {
this.job.content_blocks = [...this.job.content_blocks, {
block_type: block_type,
uuid: magic_uuidv4_generator(),
order: this.job.content_blocks.length === 0 ? 1 : _.last(this.job.content_blocks).order + 1
}]
}
TextContentBlock 的模板是
<b-tab v-for="l in ['fr', 'en']" :key="`${data.uuid}-${l}`">
<template slot="title">
{{ l.toUpperCase() }} <span class="missing" v-show="!data.body[l] || data.body[l] == ''">(missing)</span>
</template>
<b-form-textarea v-model="data.body[l].content" rows="6" />
<div class="small mt-3">
<code>{{ { block_type: data.block_type, uuid: data.uuid, order: data.order } }}</code>
</div>
</b-tab>
现在,当我从 API 加载数据时,我可以正确编辑和保存这些块的内容——考虑到 props 应该是不可变的,这很奇怪。
但是,当我添加新块时,上面的 textarea 不允许我编辑任何内容。我在其中输入内容,它只是将其删除(或者,我认为,它用“先前”或“初始”值替换它)。从 API 提取内容时(例如,在页面加载时)不会发生这种情况。
无论如何,这让我发现了不可变性,然后我像这样创建了 data 道具的本地副本
data: function() {
return {
block_data: this.data
}
}
并将每个data 调整为block_data,但我得到与以前相同的行为。
我到底错过了什么?
【问题讨论】:
-
能否提供stackoverflow.com/help/mcve。该示例在当前形式下不是很有用。
-
你检查过 Vue 开发工具发生了什么?
-
您提供的乱码。但您的代码似乎修改了
props=data的值。试试data: function() { return { block_data: Object.assign({}, this.data) } },addBlock的输出是什么?似乎没有创建 property=body。 -
Andrey:我做到了,整个数据结构得到了正确构造的对象。
-
@Morpheu5 检查了答案中的演示,如果解决了您的问题,请告诉我。
标签: javascript vue.js vue-component