Updating the DOM after moving an array item using Vue's `splice` method seems to be causing some issues

Attempting to shift a specific item in an array, located at position x, to position

2</code. Although the code below successfully accomplishes this task of relocating the item, Vue fails to update the <code>DOM
.

This is the snippet of code being utilized:

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>

There is uncertainty if this issue relates to this note in the documentation:

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).

Despite .splice() being a mutation method, the presence of this shouldn't be a concern. What could potentially be the mistake in implementation here?

Answer №1

An area where issues may arise is your selection of the key:

<layer v-for="(layer, index) in layers" :key="index" :info="layer" :offset="index"></layer>

Initially, the keys for the <layer> components will be 0, 1, 2, and 3, corresponding to Layer 1 through Layer 4 respectively.

If you then move the layer from position 0 to position 2, the order will change to Layer 2, Layer 3, Layer 1, Layer 4. However, the keys are based on the index, so Layer 2 will now have a key of 0.

During re-rendering, Vue uses these keys to match up the components. Therefore, the <layer> with a key of 0 that used to represent

Layer 1</code will now correspond to <code>Layer 2
.

This situation can cause issues with stateful components. While the first three components will have their info props updated, it may not affect other internal states like those stored in data properties which will retain their original values.

A potential solution would be to use a more suitable value for the key. The question does not provide guidance on what this value might be in your case. In some instances, adding an extra property to each array item may be necessary to create a suitable key value.

The crucial aspect is to ensure keys are unique and linked to the array items. If the layer's name serves as a unique identifier, you could utilize that, e.g., :key="layer.name".

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Searching and updating an element within an array while also inserting a new key in JavaScript

My goal is to add a key to an Object of Array as isActive: true. I then need to locate the object in the actual array with the same label as that of selectedFilterList and replace it in this.bindingData, or add isActive: false if it doesn't exist. if ...

How can I access the value from useEffect in a function component in React?

I have been attempting to retrieve an element using useEffect in React, here's a simplified example demonstrating the issue: import React from 'react'; const App: React.FC = () => { React.useEffect(() => { const resizeElement: ...

YUI: Personalizing the message displayed in the browser when cancelling a window close event

I am working on a YUI application that requires me to notify the user before closing the window in certain situations. To achieve this, I have implemented a function to capture the window close event: onWindowClose: function(e) { if (...) ...

Utilizing AngularJS filter method to populate data

Just beginning my journey with Angular js, I've got this snippet of code that is responsible for binding data to the div element, app.filter("myfilter", function () { return function (data, catName) { if (angular.isArray(data) && angular ...

How to apply a single pipe to filter columns in Angular 2 with an array of values

I need to sort through an array of objects using multiple array string values. Here is an example of how my array of objects looks like: [{ "name": "FULLY MAINTAINED MARUTI SUZUKI SWIFT VDI 2008", "model": "Swift" }, { "name": "maruti suzuki ...

Looking to dissect JSON output containing the object labeled as "@attributes"?

Using JQuery AJAX, I made an HTTP request to a PHP back-end in order to retrieve an XML string parsed into JSON using the json_encode() function. Some of the XML elements contain attributes which are represented as @attributes in the output. However, when ...

Transforming CSV files into JSON format using d3.js

I'm encountering an issue when attempting to convert CSV to JSON. The following is the snippet of code I am using for the conversion: d3.csv("http://localhost:8080/Sample/flight.csv", function(flights) { //alert(flights); ...

The process of binding two variables in the same select element

Here is the code snippet that I am working with: <div class="form-group "> <label for="field_type"><b>Type</b></label> <div class="input-icon right"> <select required class="form-control" ...

JavaScript's async function has the capability to halt execution on its own accord

Presented here is a JavaScript async function designed to populate a sudoku board with numbers, essentially solving the puzzle. To enhance the user experience and showcase the recursion and backtracking algorithm in action, a sleeper function is utilized b ...

"Vue JS: Transmitting data from child components to parent components

https://i.sstatic.net/pjVn9.png Hello everyone, I am seeking guidance on how to pass data from my NewDeal component to the DealsTable component in Vue. Being a newcomer to Vue, I am unsure of the best approach. My NewDeal component has two parent componen ...

Is there a way for me to determine when a user has signed in for the first time?

Issue at Hand I am facing an obstacle in detecting when a user initially connects to Google on my app using Firebase. The method I am currently utilizing is auth.signInWithPopup(googleProvider);. To address this query, I delved into the documentation and ...

What is the best way to calculate the average across a cell array containing arrays?

I am currently working with a cell array c that consists of equal-sized arrays, where the dimensions are defined as size(c{n}) = [ m l ... ]. My goal is to find a way to calculate the mean values (averaged across the cell array index n) for all elements ...

Guide to building a personalized autocomplete feature in vue js

Presently, I am using the buefy autocomplete feature, but it is causing a few problems. In the DepartmentDetail.vue file <template slot-scope="props"> <div class="container is-fluid"> <b-loading :is-full-page=" ...

It appears that the SELECT clause within my postgres ARRAY() function is not generating the desired array syntax

Currently, I am constructing an array based on a select clause within my WHERE condition. SELECT m.* FROM users AS u INNER JOIN microposts m ON u.id=m.user_id INNER JOIN taggings t ON m.id=t.taggable_id INNER JOIN tags t2 ON t2.id=t.tag_id WHERE ARRA ...

Executing asynchronous methods in a Playwright implementation: A guide on constructor assignment

My current implementation uses a Page Object Model to handle browser specification. However, I encountered an issue where assigning a new context from the browser and then assigning it to the page does not work as expected due to the asynchronous nature of ...

Using a script to properly close HTML tags

It seems like a straightforward task, but I'm not sure where to start looking for the solution. What I'm trying to accomplish is this. I have a script that scans for the strings [gallery]. When it finds [gallery], it replaces the tag with an ima ...

My goal is to generate a series of data arrays using a loop and assign them names based on a list of variables

In my project, I am working on importing multiple time-series variables for various countries using an API function. I am aiming to create a dedicated array for each country to store the data, with the array name being the respective country's 3-lette ...

Executing Cypress tests on Windows Subsystem for Linux (WSL

Encountering errors while attempting to run Cypress on WSL with Ubuntu: $ cypress run [29023:1018/155130.159647:ERROR:bus.cc(392)] Failed to connect to the bus: Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory [29023:1 ...

Angular - Issue: Unable to locate 'classlist.js'

require('classlist.js'); While building the project using Angular CLI, an error appeared in the console. I ran the command "npm install --save classlist.js" within the project directory. Error: Module not found: Can't resolve 'classl ...

Which specific page initiates the post request?

Seeking help with my post request that originates from a specific page on my website: reqdata = 'text=' + mytext; $.ajax({ type: "POST", url: "/request.php", data: reqdata, cache: false, success: function(html) { alert(html) } ...