I am trying to move one item in an array, at position x to position 2. The below code works and moves the item to the new position. However, vue doesn't update the DOM.
This is the code that I am using:
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>
I am not sure if this relates to this note in the docs or not:
When you modify an Array by directly setting an index (e.g. arr[0] = val) or modifying its length property. Similarly, Vue.js cannot pickup these changes. Always modify arrays by using an Array instance method, or replacing it entirely. Vue provides a convenience method arr.$set(index, value) which is syntax sugar for arr.splice(index, 1, value).
Supposedly .splice() is a mutation method, so I don't think that it should matter. What am I doing wrong here?
layersis not reactive. Is it defined in yourdata?@ProvideReactive() public layers: any[] = [ { name: 'Layer 1' }, { name: 'Layer 2' }, { name: 'Layer 3' }, { name: 'Layer 4' } ]this.splice(offset, 1)the item gets removed and theDOMupdates the item list but not the textkeyattribute within thev-for. Difficult to say without seeing the template code. You might want to try dumping out the layer name using{{ name }}within yourv-for. I suspect you're using stateful components that aren't reacting to the changes but a{{ name }}should show the latest value.