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

Can builtins like DOM globals be explicitly imported?

The present situation includes the utilization of rollup (as well as iife parameters), but I am hesitant about whether it is solely related to rollup or typescript. My objective is to achieve something similar to this: import { document } from "[wherever ...

The given 'FC<ComponentType>' type argument cannot be assigned to the 'ForwardRefRenderFunction<unknown, ComponentType>' parameter type

Currently, I am using react in conjunction with typescript. Within my project, there are two components - one serving as the child and the other as the parent. I am passing a ref to my child component, and within that same child component, I am binding my ...

How do I correctly submit a Vue.js application to GitHub?

After attempting to upload my files to Github, I received an error message stating that the files were too large. As a workaround, I uploaded only the content of the dist folder after building for production. Although this method worked, it is not very p ...

Leverage the power of function overloading in TypeScript for efficient code

How can function overloading be reused effectively in TypeScript? Consider a scenario where a function is overloaded: function apply(value: number): number; function apply(value: string): string; function apply(value: any): any { return value; } No ...

Error: Unable to locate bundle.js when attempting to refresh the page with a specific ID in the URL

I encountered an issue where I tried redirecting a user to their profile page to display the profile information corresponding to it. Let's say we have http://localhost:8080/user/1 as an example. Upon redirecting the user using the navbar link, the pa ...

Converting constants into JavaScript code

I've been diving into typescript recently and came across a simple code snippet that defines a constant variable and logs it to the console. const versionNuber : number = 1.3; console.log(versionNuber); Upon running the tsc command on the file, I no ...

Is it the same item in one situation, but a completely different item in another?

I am currently investigating the behavior of objects in JavaScript, particularly when it comes to copying one object onto another. It seems that sometimes they behave as if they are the same object, where modifying one also modifies the other. Many resourc ...

Achieving VueJS reactivity by initializing a variable within the mounted function

I am facing an issue with a dynamic component that builds multiple select elements. Here is the template code: <template> <div> <b-field v-for="(key,index) in allSelects" :key="index" :label=" ...

What is the best way to handle alias components in next.js when using ts-jest?

When working with TypeScript, Next.js, and Jest, I wanted to simplify my imports by using aliases in my tsconfig file instead of long relative paths like "../../..". It worked fine until I introduced Jest, which caused configuration issues. This is a snip ...

Error: The npm-link library encountered an invalid hook call

Problem Description: I am working on developing a package named eformless. To set up the package, I utilized CRA to create a directory named sandbox where I linked the package. However, I keep encountering an error when attempting to launch the sand ...

Learn how to utilize Vue 3 to access properties that have been passed down from a parent component, even if they

Hey there, hope everything is going well. I'm familiar with react.js, but when I gave vue a try, things felt a bit different. In react, it's easy to access props passed from the parent in the child component without much hassle. However, in vue, ...

Using Angular: How to set the index value from a dropdown to a local variable after a button is clicked

Can someone please provide guidance on how to assign the index value (i = index) to EmployeeIndex: any; after a button click event? Your suggestions are greatly appreciated. Here is my code: HTML <select class="form-control" [(ngModel)]="EmployeeNam ...

Can someone explain how to create a Function type in Typescript that enforces specific parameters?

Encountering an issue with combineReducers not being strict enough raises uncertainty about how to approach it: interface Action { type: any; } type Reducer<S> = (state: S, action: Action) => S; const reducer: Reducer<string> = (state: ...

unable to transfer Vuex store information to the graph

Currently, I am facing an issue with passing my vuex store data into my apexcharts graph. Despite my efforts, it seems like the data is not being displayed correctly. Can anyone provide guidance on what I might be doing wrong? My main objective is to updat ...

Distribute among an array of specific types

I am trying to achieve this behavior using Typescript: type animals = 'cat' | 'dog' let selectedAnimals: animals[] = ['cat'] selectedAnimals = [ // <- Type 'string[]' is not assignable to type 'animals[]&ap ...

Tips for hiding a sidebar by clicking away from it in JavaScript

My angular application for small devices has a working sidebar toggling feature, but I want the sidebar to close or hide when clicking anywhere on the page (i.e body). .component.html <nav class="sidebar sidebar-offcanvas active" id="sid ...

Enhance your AJAX calls with jQuery by confidently specifying the data type of successful responses using TypeScript

In our development process, we implement TypeScript for type hinting in our JavaScript code. Type hinting is utilized for Ajax calls as well to define the response data format within the success callback. This exemplifies how it could be structured: inter ...

Encountering issues when trying to build a Nestjs app with node-crc (rust cargo) in Docker

I am encountering an issue with building my Nest.js app using Docker due to a dependency called "node-crc" version "2.0.13" that fails during the docker build process. Here is my Dockerfile: FROM node:17.3.1-alpine RUN curl https://sh.rustup.rs -sSf | sh ...

Search timeout restriction

I have a function that makes a request to the server to retrieve data. Here is the code for it: export default class StatusChecker { constructor() { if (gon.search && gon.search.searched) { this.final_load(); } else { this.make_req ...

Attempting to create a function that can accept two out of three different types of arguments

I am trying to create a function that only accepts one of three different types type A = 'a' type B = 'b' type C = 'c' The function should accept either type A, C, or both B and C, but not all three types. This is what I hav ...