Vue拼接(将数组项移动到数组中的另一个位置)不更新DOM
Posted
技术标签:
【中文标题】Vue拼接(将数组项移动到数组中的另一个位置)不更新DOM【英文标题】:Vue splice (Move array item to another location in array) not updating the DOM 【发布时间】:2020-03-15 15:16:22 【问题描述】:我正在尝试将数组中的一项移动到位置x
到位置2
。下面的代码工作并将项目移动到新位置。但是,vue 不会更新DOM
。
这是我正在使用的代码:
export default class LayersPanel extends Vue
@ProvideReactive() public layers: any[] = [
name: 'Layer 1' , name: 'Layer 2' , name: 'Layer 3' , name: 'Layer 4'
]
public onDragDrop(evt: DragEvent)
let offset = parseInt(evt.dataTransfer.getData('text/plain'))
this.layers.splice(2, 0, this.layers.splice(offset, 1)[0])
<template>
<div class="layers-panel" @dragover="onDragOver" @drop="onDragDrop">
<layer v-for="(layer, index) in layers" :key="index" :info="layer" :offset="index"></layer>
</div>
</template>
我不确定这是否与this note in the docs 有关:
当您通过直接设置索引(例如 arr[0] = val)或修改其长度属性来修改数组时。同样,Vue.js 也无法获取这些更改。始终使用 Array 实例方法或完全替换它来修改数组。 Vue 提供了一个方便的方法 arr.$set(index, value),它是 arr.splice(index, 1, value) 的语法糖。
据说.splice()
是一种变异方法,所以我认为这无关紧要。我在这里做错了什么?
【问题讨论】:
layers
很可能没有反应。它是否在您的data
中定义?
我正在使用带有装饰器的打字稿:@ProvideReactive() public layers: any[] = [ name: 'Layer 1' , name: 'Layer 2' , name: 'Layer 3' , name: 'Layer 4' ]
这听起来像是v-for
中的key
属性的问题。不看模板代码很难说。您可能想尝试在您的v-for
中使用 name
转储层名称。我怀疑您使用的有状态组件对更改没有反应,但 name
应该显示最新值。
【参考方案1】:
问题的来源可能是您选择的key
:
<layer v-for="(layer, index) in layers" :key="index" :info="layer" :offset="index"></layer>
最初<layer>
组件将具有键0
、1
、2
和3
,分别对应于层Layer 1
到Layer 4
。
如果您随后将位置 0 的图层移动到位置 2,那么您现在将按照 Layer 2
、Layer 3
、Layer 1
、Layer 4
的顺序拥有它们。但是,键是由索引决定的,所以 Layer 2
现在的键值为 0
。
当 Vue 在重新渲染后尝试配对组件时,它会使用键。所以<layer>
和key
的0
过去对应于Layer 1
,但现在它将对应于Layer 2
。
这不一定是个问题。 Layer 4
很简单:它没有移动,所以它不会改变。其他三个已经移动,但他们的 info
属性应该会相应更新。
这就是有状态组件的问题所在。虽然前三个组件的 info
属性会更新,但不一定会对任何其他内部状态产生任何影响,例如 data
属性所持有的状态.这些仍将保留原始 info
值的值。
这里的解决方案通常是为key
使用更合适的值。从问题中不清楚您的情况可能是什么值。在某些情况下,您可能需要在每个数组项中添加一个额外的属性,以便为其提供合适的属性。
重要的是键是不同的并且与数组项相关联。如果图层的 name
是唯一标识符,那么您可以使用它,例如:key="layer.name"
.
【讨论】:
好吧,酷!什么时候适合使用索引作为键? @GetOffMyLawnkey
需要唯一标识从一次渲染到下一次渲染的等效 VNode(转换为组件和元素)。等效组件将被更新,而没有合适等效组件的组件将被相应地销毁或创建。理解这一点非常重要:根据我的经验,大多数使用 Vue 的开发人员不知道 key
做了什么,并试图通过像 'never use index' 这样的过度简化来蒙混过关。如果您了解 key
的作用,那么确定特定的值选择是否合适应该相对容易。以上是关于Vue拼接(将数组项移动到数组中的另一个位置)不更新DOM的主要内容,如果未能解决你的问题,请参考以下文章