The reactivity of arrays in Vue components' props is limited

I've got an array with component data that I'm attempting to render using v-for

<div :style="style" class="editor-component" v-for="(component, index) in components">
    <Component
       :is="component.name"
       v-bind="component.options"
       :key="createKey(component, index)"
       :style="component.style ? component.style : {}"
    />
</div>

Here's the issue:

When a component option has an array with just 1 element, like

tabs: [{tab}]

everything works fine. However, when there are 2 or more elements in the tabs array, like this

tabs: [{tab},{tab}]

The component doesn't detect changes in the second tab.

So, I came up with a solution using dynamic keys

createKey(component, index) {
   return JSON.stringify(component) + index
}

But this causes the component to re-render after each change and resets its state to default.

UPDATE: I encountered a similar problem on Reactive Nested V-For's using Vue/Vuex, but unfortunately it doesn't have a definitive answer :(

Answer №1

Glad to offer assistance

One suggestion is to include a key, or a new key, in the "editor-component" Div so that when any change occurs within that div, both components inside it will be re-rendered. You may also find helpful information in the final section of this article on force re-rendering:

To address the issue of tabs resetting each time, I recommend reading through this article: Vuex state on page refresh and multiple tabs

Considering implementing Vuex or a similar solution for maintaining persisted state may also be beneficial.

Answer №2

Big shoutout to @Sweet Chilly Philly, I'm getting closer to solving the problem

        generateUniqueKey(component, index) {
            let count = this.calculateOptionsLength(component.options);
            console.log(component.name, count);
            return `component_${index}_length_${count}`;
        }

        calculateOptionsLength(options) {
            let count = 0;

            for(let key in options) {
                if(options.hasOwnProperty(key)) {
                    let option = options[key];
                    if(Array.isArray(option)) {
                        count += option.length;
                    }
                    if(option && (Array.isArray(option) || isObj(option))) {
                        count += this.calculateOptionsLength(option)
                    }
                }
            }
            return count;
        }
        ...
<div :style="style" class="editor-component" v-for="(component, index) in components">
         <Component
                        :is="component.name"
                       v-bind="component.options"
                        :key="generateUniqueKey(component, index)"
                        :style="component.style ? component.style : {}"
               />
</div>

I'm calculating the length of arrays in the options object and generating a unique key. This way, the component only re-renders when an element is added to the array. However, the issue with b-tab(bootstrap-vue) still persists

Answer №3

<div :style="style" class="editor-component" v-for="(component, index) in components">
<Component
   :is="component.name"
   v-bind="component.options"
   :key="component.name"
   :style="component.style ? component.style : {}"
/>

It is advisable to use the component name as a key since it should be unique.

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

Encountering the issue of receiving "undefined" when utilizing the http .get() method for the first time in Angular 2

When working in Angular, I am attempting to extract data from an endpoint. Below is the service code: export class VideosService { result; constructor(private http: Http, public router: Router) { } getVideos() { this.http.get('http://local ...

Leveraging Vue.js's computed properties to access and manipulate elements within an

I have a simple template that displays text from a wysiwyg editor using two-way data binding, as shown below: <template> <div> <quill-editor v-model="debounceText" :options="editorOptionProTemplate" > </qu ...

Using Vue to append elements that are not part of the loop

While looping over a table row, I realized that each of the table rows should be accompanied by another table row containing additional data from the loop. Unfortunately, I am struggling to insert <tr class="data-spacer"></tr> <tr& ...

Having trouble generating a Vue project using vue/cli?

I am currently developing a vuex application using Vue CLI. Unfortunately, the CLI gets stuck during metadata fetching (<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="eb88838480828f8a99abd9c5dac5dd">[email protected]</a& ...

Using Vue.js to manage connected data for a multi-select dropdown

Here is the code snippet: <li> <select v-model="selectYear" id="search-year" class="w-100 text-center mb-1" name="year" > <option v-for="year in years" v-bind:value="year.value"> {{ year.text }} </optio ...

Determining if data from two separate lists in Vue.js matches in order to display in the template

I need to compare two sets of data - one fetched from the server and the other being default data. Data retrieved from the server: [ { "id": 7, "day": "14 April 2017", "time_list": [ { "id": 25, "time": "11:00 AM", ...

Next.js 14 useEffect firing twice upon page load

Having an issue with a client component in next js that is calling an API twice at page load using useEffect. Here's the code for the client component: 'use client'; import { useState, useEffect } from 'react'; import { useInView ...

Error encountered while exporting TypeScript module

While I am working with Angular, TypeScript, and Gulp, my module system is CommonJS. However, I encountered an error when trying to import a module into my main.ts file: Error: Cannot find external module 'modules.ts'. Here is the snippet from ...

Delve into the depths of Vue2's $emit command to gain a deeper comprehension

I'm curious about how Vue2's $emit function actually works. According to its API documentation(https://v2.vuejs.org/v2/api/#vm-emit), it states: Trigger an event on the current instance. Any additional arguments will be passed into the listene ...

Accessing enum values in a view with Typescript and AngularJS version 1.5

Recently started working with Angular 1.5 and Typescript I have a service that returns data in an array format called devices.headerEntries: [{name:id,value:45} ,{name:Mode,value:1},{name:State,value:2},{name:serialnum,value:123434} I created a componen ...

Solving Circular Dependencies in React with TypeScript by using smart importing techniques

I've set up a union type in the parent component export type Students = "fresher" | "secondYear" | 'finalYear' | 'postGrad'; A circular dependency is causing issues, and the most obvious solution is to define ...

Error message "Exceeded the maximum call stack size" encountered during Vue-router authentication

I am currently in the process of developing a dashboard using Vue, Vuex, and Quasar. However, I have encountered an authentication error that is preventing me from progressing. Additionally, I need assistance in ensuring that when a user is already logged ...

Is there a way to prevent QtLinguist from opening every time Visual Studio tries to display a TypeScript file?

Ever since I installed Qt tools for Visual Studio, my Ctrl+click on a class name triggers Qt Linguist: https://i.stack.imgur.com/USAH1.png This hinders me from checking type definitions, even though Visual Studio has already parsed them. The type informa ...

Type guard does not narrow down the union type

Explore the following code snippet: type UnionType = 'foo' | 'bar' | 'baz' const obj = { foo: 'huh', bar: 'hmm' } function func(input: UnionType) { if(input in obj) { input } } In ...

Having trouble with assigning an error message in Formik validation using TypeScript

Currently, I am in the process of constructing a user input form in React & TypeScript using Formik. The form requires the user to input a name, email, and password. The input handling is functioning properly, but now I aim to implement validation functio ...

select items using a dropdown menu in an Angular application

Let me describe a scenario where I am facing an issue. I have created an HTML table with certain elements and a drop-down list Click here for image illustration When the user selects in, only records with type in should be displayed Another image refere ...

Vue watchers capturing original value prior to any updates

When working with Vue.js, we can easily access the value after modification within watchers using the following syntax: watch: function(valueAfterModification){ // ...... } But what about getting the value before it's modified? PS: The official ...

In Angular/Typescript, dynamically add a class to a `td` element when it is clicked. Toggle the class on and off

My problem arises when trying to individually control the arrow icons for each column in my COVID-19 data table. By using Angular methods, I aim to show ascending and descending arrows upon sorting but run into the challenge of changing arrows across all c ...

Angular 6 - Build a dynamic single page housing various applications within

I am faced with the task of developing multiple applications using Angular 6. Each application will have its own set of components, services, and more. However, there is also a need for shared services, components, directives, and other elements that will ...

Angular - Acquire reference to the <audio> element

Is there a way to access the methods of an audio tag within my component in order to implement play and pause functions based on click events? The current method I tried does not allow me to access the play() function. How can I correctly approach this? ...