How can I ensure that my Vue components do not interfere with each other's data when they are

Scenario

Consider the following vue component:

<template>
  <div>
    <slot>{{ title }}</slot>
    <ul>
      <li v-for="label in labels" :key="label">
        <input
          type="checkbox"
          v-model="checked"
          :label="label"
          :id="label"
          :value="label"
        />
        <label :for="label">{{ label }}</label>
      </li>
    </ul>
  </div>
</template>

<script>
import Component from "vue-class-component";
import Vue from "vue";

@Component({
  props: {
    labels: {
      type: Array,
    },
    title: {
      type: String,
    },
  },
  watch: {
    checked: [
      {
        handler: "updateParent",
      },
    ],
  },
})
export default class CheckboxList extends Vue {
  checked = [];

  updateParent() {
    this.$emit("update", this.checked);
  }
}
</script>

This component will display a list of checkboxes based on the labels prop passed down from the parent.

When both components are included on the same page, with a toggle using v-if like so:

<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png" width="10%" />
    <hr />
    <button type="button" @click="state = 'numbers'">
      Show number checklist
    </button>
    <button type="button" @click="state = 'letters'">
      Show letter checklist
    </button>

    <CheckboxList
      v-if="state === 'numbers'"
      title="numbers"
      :labels="numbers"
      @update="checkedNumbers = $event"
    ></CheckboxList>
    <CheckboxList
      v-if="state === 'letters'"
      title="letters"
      :labels="letters"
      @update="checkedLetters = $event"
    ></CheckboxList>

    <div>
      <span>Checked letters:</span> {{ checkedLetters }}
      <span>Checked numbers:</span> {{ checkedNumbers }}
    </div>
  </div>
</template>

<script>
import Vue from "vue";
import HelloWorld from "./components/HelloWorld";
import CheckboxList from "./CheckboxList.vue";
import Component from "vue-class-component";

@Component({
  components: {
    CheckboxList,
  },
})
export default class App extends Vue {
  numbers = [1, 2, 3, 4, 5];
  letters = ["a", "b", "c", "d"];
  state = "numbers";

  checkedLetters = [];
  checkedNumbers = [];</pre>

The above setup will result in the demonstrated UI:

https://i.sstatic.net/HabXM.png

Why does toggling between the two components (with v-if) and checking the boxes lead to mixed-up data, as seen in this behavior? https://i.sstatic.net/x9DOA.gif

A functional example is available here: https://codesandbox.io/s/epic-resonance-plwvi?file=/src/App.vue

Answer №1

Vue is designed to optimize its performance by reusing components within its directives like v-if or v-for as the default behavior.

You can find more information about this in their documentation.

If you want to ensure Vue treats these components as separate entities, even if they seem similar, consider adding a unique key prop:

<CheckboxList
  key="numbers"
  v-if="state === 'numbers'"
  title="numbers"
  :labels="numbers"
  @update="checkedNumbers = $event"
  ></CheckboxList>
  <CheckboxList
   key="letters"
   v-if="state === 'letters'"
   title="letters"
   :labels="letters"
   @update="checkedLetters = $event"
   ></CheckboxList>

Keep in mind that adding a 'key' prop is only necessary when dealing with conditional rendering or looping through components:

<!-- 
     Since both are rendered at the same time, 
     they will be considered separate components 
     and won't require a 'key' prop to distinguish between them 
-->
 <CheckboxList
  title="numbers"
  :labels="numbers"
  @update="checkedNumbers = $event"
  ></CheckboxList>
  <CheckboxList
   title="letters"
   :labels="letters"
   @update="checkedLetters = $event"
   ></CheckboxList>

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

Unusual characteristics of decision-making

Here is a snippet of my JavaScript code: function getSelectedText(){ if(window.getSelection){ select = window.getSelection().getRangeAt(0); var st_span = select.startContainer.parentNode.getAttribute("id").split("_") ...

What signals to Angular that $httpBackend is substituting $http during the testing of AngularJS?

My factory, called myFactory, has a dependency on $http. When writing tests for this, I needed to mock this dependency. After some research, I discovered that I could accomplish this using $httpBackend. Implementing the code below successfully achieved t ...

Is there a way to transfer the chosen maximum and minimum price values to a JavaScript function within a select tag in HTML?

I have a search form that includes select options with two values. However, I want to have two select options for both the Max and Min price values. <input type="hidden" id="budget_min" name="filter_budget_min" value="0" /> <select onchange="upda ...

What could be causing the server to return an empty response to an ajax HTTP POST request?

Attempting to make a POST request using ajax in the following manner: $.ajax({ type: "POST", url: 'http://192.168.1.140/', data: "{}", dataType: "json", ...

Guidelines for utilizing React to select parameters in an Axios request

As a newcomer to ReactJs, I am working with a Product table on MySQL. I have successfully developed a dynamic table in the front-end using ReactJS along with MySQL and NodeJs on the backend. The dynamic table consists of four columns: Product, Quantity, Pr ...

The variable X has been defined, but it's never actually utilized. Despite declaring it, I have not accessed its

I have encountered warnings in VSCode while using certain properties in my Angular component. The warnings state: '_id' is declared but its value is never read.ts(6133) (property) ItemEditComponent._id: number | undefined '_isModeEdit' ...

How can I ensure that only the relevant form values are submitted in Vue2?

I currently have a form page that serves the purpose of both creating and updating data. The form fields are structured as follows; view image details here content: (...) i18n: (...) image: (...) name: (...) orderIndex: (...) position: (...) I am able t ...

Uploading multiple images with base64 using Laravel and Vue.js: A comprehensive guide

When attempting to upload multiple images in base64 format, I noticed that only the second image gets uploaded. Is there a simpler way to upload images using laravel and VueJS instead of using base 64? Here is an example of the VueJS method: updateIMG(e) ...

How can you utilize multiple files to set environment variables in Node.js?

My project has two different environments for development and production production.js var config = { production: { session: { key: 'the.express.session.id', secret: 'something.super.secret' }, ...

Is there a way to bypass the default layout on app router in Next.js and implement our own custom page layout

Utilizing a default layout in layout.jsx, I passed all my other pages as children through props. In the page router, we typically configure the router path to specify which layout to use. However, in this new system, I am facing challenges with coding it. ...

Creating a function in AngularJS to select all checkboxes

I recently started working with Angular and I implemented a select all checkbox that checks all the boxes using ng-model/ng-checked. <th> <input type="checkbox" id="selectAll" ng-model="selectAll"/> </th> <th ...

Ways to develop a dynamic HTML TransferBox featuring a custom attribute

I am in need of developing a customized transferbox using HTML, JavaScript, and JQuery. The user should be able to select from a list of options and associate them with attributes. This selection process should involve transferring the selected options be ...

Tips for managing lag caused by large raw image re-renders in a React application

When trying to change the background position of a user-uploaded background image that is in raw Data URI format using CSS, I noticed that re-rendering becomes slow if the image size exceeds 1mb. This issue does not occur with smaller images. Is there a ...

Having trouble with page reload when implementing Angular Ui Router in Html5 mode with AngularJS?

Within my Angular app, I have implemented Angular UI Router and made use of HTML5 mode to eliminate the "#" from my URLs by utilizing the $locationProvider in the configuration. angular.module('myApp', ['ui.router']) .config(function( ...

Incorporate a progress bar into the Material-UI table design

I have the following example of a Material-UI table: import React from "react"; import clsx from "clsx"; import { createStyles, lighten, makeStyles, Theme } from "@material-ui/core/styles"; import Table from "@mat ...

What could be causing my JavaScript loop to only display the final value?

Story Behind the Game In my latest project, I am delving into the world of creating a captivating 2D side-scrolling game using HTML and JavaScript. To ensure smooth gameplay, I have opted to incorporate ES6 for efficient management of all game objects. C ...

Creating duplicates of a division and updating the identifiers of each element within the duplicated divisions

In the midst of a django project, a specific requirement is to add a button on the HTML page that, when clicked, duplicates a specific div and attaches it to the bottom of the page. The desired outcome is illustrated in the following image: View Screenshot ...

My task is to troubleshoot the Vue function in order to locate soccer players based on their club

I am trying to filter players by club. Whenever I select a club from the dropdown menu, all players from the league are displayed instead of just the players from the selected club: <template> <div> <div class="topnav">< ...

Do I need to use a particular approach to call a vuex action from a vue component?

Whenever I try to call a Vuex action in my Vue file, the code crashes and disrupts the functionality of the site. I've simplified it down to the basics (just trying to console.log a string from within the action when a button tied to that action is cl ...

Transfer the data stored in the ts variable to a JavaScript file

Is it possible to utilize the content of a ts variable in a js file? I find myself at a loss realizing I am unsure of how to achieve this. Please provide any simple implementation suggestions if available. In my ts file, there is a printedOption that I w ...