在使用deleteData()
从同时用于创建动态组件的对象数组中删除元素后,我无法应付正确的渲染。
该元素已正确删除,但是它的行为就像组件不知道应该刷新一样,而Vue不知道数据已更改。
在chrome Vue扩展名中,删除了正确的元素,但是DOM中的Vue删除了最后一个element()
Vue:
<template>
<b-container>
<SectionSelector :AddSection="AddSection"/>
<component v-for="(section, index) in sections"
:key="index"
:is="section.type"
:sectionIndex="index"
:sectionData="section[index]"
:deleteData="deleteData"
@sectionDataEmit="sectionDataEmit"/>
</b-container>
</template>
<script>
import SectionSelector from './components/SectionSelector.vue';
import FullText from './components/sections/FullText.vue';
import FullImage from './components/sections/FullImage.vue';
import ImageRightTextLeft from './components/sections/ImageRightTextLeft.vue';
import ImageLeftTextRight from './components/sections/ImageLeftTextRight.vue';
import Vue from 'vue'
export default {
data() {
return {
sections: []
}
},
methods: {
AddSection(sectionData) {
this.sections.push(sectionData);
},
updateSection(sectionIndex, sectionData) {
Vue.set(this.sections, sectionIndex, sectionData);
},
sectionDataEmit(emitData) {
Vue.set(this.sections, emitData.position, emitData.content);
},
deleteData(index) {
// eslint-disable-next-line
console.log(index)
this.$delete(this.sections, index);
}
},
components: {
SectionSelector,
FullText,
FullImage,
ImageRightTextLeft,
ImageLeftTextRight
}
}
</script>
组件:
<template>
<b-row>
<h3>Full text {{ sectionIndex+1 }}</h3>
<b-button variant="danger"
@click="deleteButton(sectionIndex)">delete</b-button>
<b-textarea :value="sectionData"
@input="sectionDataEmit" />
</b-row>
</template>
<script>
export default {
props: ['sectionIndex', 'sectionData', 'deleteData'],
methods: {
sectionDataEmit(value) {
let emitData = {
position: this.sectionIndex,
content: {
type: 'FullText',
fields: {
text: value
}
}
}
this.$emit('sectionDataEmit', emitData)
},
deleteButton(index) {
this.deleteData(index)
}
}
}
</script>
答案 0 :(得分:0)
由于您要呈现状态组件列表,而不是简单/简单的DOM节点,因此键作为真正独特的属性变得至关重要。使用索引作为键属性值不能保证唯一性。您可以详细了解here。
Vue.js在内部使用虚拟DOM(VDOM)来有效呈现UI。因此,当阵列发生变化时,Vue.js使用VDOM更新DOM。 VDOM不了解Vue.js组件或其状态。因此,VDOM可能会为组件分配错误的DOM元素。这是 key 属性帮助Vue.js跟踪组件及其DOM元素的地方。
index
属性用于key
会发生什么?想象一下,您已经使用索引作为键属性。现在,您最初在阵列中有五个项目要渲染。对于每个项目,它实例化一个组件实例。因此,五个DOM元素和五个组件
现在,假设您使用拼接方法删除了第三项:
array.splice(2, 1);
完成上述操作后,数组长度从5变为4。对于vue.js,它是第4个索引,即第五项不见了。索引2仍然存在并且从未消失;因此,其关联的 component2 仍然有效。因此,它去掉了由 index 4 引用的 component4 (因为该数组不再存在索引4)。简而言之,它会破坏错误的组件。
对于每个id
,您应该有一个唯一的密钥sectionData
,以便在列表中唯一标识自己。想象一下,如果您必须对sections
数组进行排序,那么即使在排序后,该唯一ID仍应相同(对 id 使用 index 会在重新排序后更改其ID事情就被VDOM搞砸了。