gpt4 book ai didi

vue.js - 复制操作后Vue组件的顺序不正确

转载 作者:搜寻专家 更新时间:2023-10-30 22:31:16 24 4
gpt4 key购买 nike

我有几个 Accordion (每个都是一个 Vue 组件),它们默认展开。还有一个“复制”功能,允许复制每个组件。

Vue.component("Accordion", {
template: "#accordion-template",

data: function () {
return {
open: true
}
},

methods: {
toggle: function () {
this.open = !this.open;
}
}
});


new Vue({
el: '#vue-root',
data: {
devices: [
{
name: "a", description: "first"
},
{
name: "b", description: "second"
},
{
name: "c", description: "third"
}
]
},

methods: {
copy: function (device) {
var index = this.devices.indexOf(device) + 1;
var copy = {
name: device.name + "_copy",
description: device.description + "_copy"
};

this.devices.splice(index, 0, copy);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.js"></script>
<div id="vue-root">
<div class="device" v-for="device in devices">
<accordion>
<div slot="acc-head">
<span>{{ device.name }}</span><br/>
<button @click="copy(device)">copy</button>
</div>
<div slot="acc-body">
{{ device.description }}
</div>
</accordion>
</div>
</div>

<script type="text/x-template" id="accordion-template">
<div>
<slot name="acc-head"></slot>
<button @click="toggle">Open: {{ open }}</button>
<div :class="open ? 'active' : 'hidden'">
<slot name="acc-body"></slot>
</div>
</div>
</script>

当所有 Accordion 折叠(换句话说'open:false')并且我尝试从列表中间复制一个 Accordion (例如b)时,我希望出现名为'name'_copy的新组件并且它必须默认展开。但取而代之的是,新组件具有与复制组件相同的所有属性值,并且列表中的最后一个组件被展开。

我该如何解决这个问题?

fiddle :https://jsfiddle.net/j3ydt1m7/

最佳答案

简答

在您的 v-for 中添加一个 key 循环:v-for="device in devices" :key="{something here}" .您的 key 必须是唯一的并且可以识别每台设备,即使在设备复制之后也是如此

代码

请检查:https://jsfiddle.net/Al_un/9cradxvp/ .出于调试目的,我更改了一些内容:

长答案

关于列表渲染

如果 v-for 中未提供 key 循环,Vue 不知道如何更新一个列表。来自 Vue documentation :

To give Vue a hint so that it can track each node’s identity, and thus reuse and reorder existing elements, you need to provide a unique key attribute for each item.

让我们考虑一下您的列表(我添加了一个元素)

[
{id: 1, name: "a"},
{id: 2, name: "b"},
{id: 3, name: "c"},
{id: 4, name: "d"},
]

现在,让我们复制节点“b”。没有:key="device.id" ,控制台输出为

4: d is mounted
3: c is updated
5: b_copy is updated

:key="device.id" ,控制台输出只有:

5: b_copy is mounted

基本上,没有键,有:

  • 两次更新:c变成 b_copy , d变成 c
  • 一个插入:d已创建

因此,每次进行复制时都会重新创建最后一个元素。作为open默认值为 true ,显然,dopen = true .

如果每个元素都有一个:key="device.id" , 然后只有元素 b_copy已创建

要检查这一点,请删除 :key="device.id"从我的 fiddle 中查看控制台中发生了什么

选择一个键

由于 key 必须唯一标识您的设备,因此您不应该使用索引作为 key ,因为每当您复制设备时数组中的设备索引都会发生变化

此外,首选 ID 字段,因为无法保证您的设备名称是唯一的。如果你用

初始化列表会怎么样
[
{ name: "a"},
{ name: "b"},
{ name: "a"}
]

从功能的角度来看,这是正确的。

关于vue.js - 复制操作后Vue组件的顺序不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55277559/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com