What could be causing my Vue code to behave differently than anticipated?

There are a pair of components within the div. When both components are rendered together, clicking the button switches properly. However, when only one component is rendered, the switch behaves abnormally.

Below is the code snippet:

Base.vue

<template>
  <div :id="id">{{msg}}</div>
</template>

<script lang='ts'>
import { Component, Prop } from "vue-property-decorator";
import Vue from "vue";

@Component
export default class Base extends Vue {
  id!: string;
  msg = "this is Base";
}
</script>

child.vue (no template)

<script lang='ts'>
import Base from "@/components/Base.vue";
import { Prop, Component } from "vue-property-decorator";
@Component
export default class extends Base {
  @Prop({ default: "helloWorld" })
  childId!: string;
  constructor() {
    super();
    this.id = this.childId;
    this.msg = "this is Child " + this.childId;
  }
}
</script>

App.vue (displays these components)

<template>
  <div id="app">
    <Child v-show="!show" childId="child1" style="color:#f00;"/>
    <button @click="click">change</button>
    <Child v-show="show" childId="child2" style="color:#f0f;"/>
  </div>
</template>

<script lang="ts">
import Vue from "vue";
import Child from "@/components/Child.vue";
import Component from "vue-class-component";

@Component({
  components:{
    Child,
  }
})
export default class App extends Vue {
  show= false;
  click() {
    this.show = !this.show;
  }
}
</script>

After clicking the button, the expected result is displayed.

If all instances of v-show in the App.vue file above are changed to v-if, the result becomes confusing upon clicking the button.

Subsequent to clicking the button, the unexpected result is shown instead of child2. This raises the question as to why this occurs.

Answer №1

When you click for the first time, you are actually creating the show-property that was missing because the data() method was not set up correctly.

I won't delve into the specific reasons why this happened, but it seems like there may have been some unexpected boolean conversions and the property might not be reactive since it wasn't included in the data object. In any case, simply create it as shown below and everything should function as intended:

export default class App extends Vue {
  data(){ 
     return {
       show: false
     }
  },
  click() {
    this.show = !this.show;
  }
}

Answer №2

Thank you so much!

After experimenting with different keys for each Child component, I successfully resolved this issue.

<Child v-if="!show" childId="child1" key="goodbye1" style="color:#00f;" />
<Child v-if="show" childId="child2" key="goodbye2" style="color:#0ff;" />

In my opinion, Vue's diff algorithm is the reason behind considering these two components as identical.

Answer №3

When utilizing the v-if directive, it will utilize the same instance of the Child component. The value of this.msg will only be set once in the constructor. The value of msg will not update when the childId props change, hence the need for the Watch property. It is important to use Watch to ensure that when the childId changes, the msg is updated accordingly.

Child.vue

<script lang='ts'>
import Base from "@/components/Base.vue";
import { Prop, Component, Watch } from "vue-property-decorator";
@Component
export default class extends Base {
  @Prop({ default: "helloWorld" })
  childId!: string;
  @Watch('childId')
  onChildIdChanged(val: any) {this.msg = "this is Child " + val}
  constructor() {
    super();
    this.id = this.childId;
    this.msg = "this is Child " + this.childId;
  }
}
</script>

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

The anchor tag is failing to register when placed inside a dynamically created table cell

I'm attempting to place an anchor tag within a cell of an HTML table. Here is the code I am using, but for some reason, the tag is not being identified and no hyperlink is displayed in that cell. Is there an issue with the syntax? $("#tranTbodyI ...

populating a multi-dimensional array using a "for" loop in Javascript

It appears that JavaScript is attempting to optimize code, causing unexpected behavior when filling a multidimensional array (largeArr) with changing values from a one-dimensional array (smallArr) within a loop. Take the following code for example: largeA ...

Updating button appearance when clicked using Vue.js and Tailwind CSS

As part of my learning journey, I have expanded this code to enhance my frontend skills. While I am aware that the code can be significantly shortened, I am focused on learning and broadening my experience in frontend development. The code below functions ...

The switch statement is not functioning properly when the button is pressed

I am trying to trigger an alert inside a switch statement when I click a button, but for some reason, it is not working. Even if I simply have an alert in the previous function, there is no output on my website. What could be causing this issue? Here is ...

Navigating Paths in Real-time with Javascript - Node.js

When working with PHP, dynamic routing can be achieved by defining classes and methods like: class Route { public function homePage () { echo 'You are on the home page' } public function otherPage () { echo 'You are on so ...

Unlocking the potential of nested conditional types in TypeScript

The source of the autogenerated type below stems from a GraphQL query: export type OfferQuery = { __typename?: 'Query' } & { offer: Types.Maybe< { __typename?: 'Offer' } & Pick<Types.Offer, 'id' | 'nam ...

What is the best way to automatically hide the Materialize CSS mobile navbar?

Recently, I completed a website called Link. Using only Materialize CSS, Vanilla JS, and plain CSS, I developed a single-page application that effectively hides and reveals different sections based on event listeners. Everything functions smoothly except ...

What are the benefits of using "var self = this" for synchronizing between a class and events?

Consider this straightforward code example (it's in AngularJS for simplicity, but the scenario is common in JavaScript): angular.module('app',[]). directive('myDir', function(){ this.state = {a:1, b:2}; return { l ...

Develop a personalized event that is compatible with all types of selectors

If I have a simple script that changes the background color of an element when clicked: $(".foo").on("change.color", function() { $(this).css("background-color", "red"); }); $(".foo").click(function() { $(this).trigger("change.color"); }); Currently ...

Stop the spread - Touch to choose - React with Material Design

I am currently utilizing ReactJS along with the library @material-ui/core. In my code, I am seeking to halt event propagation on Click. Here is the snippet: <NumPad.Number onChange={val => { this.setPrice(val) } }> <TextField ...

Sending enums as arguments to a function

Is there a way to create a function that can work with any enum and function that accepts it as an argument? Consider the following scenario: enum Enum1 { VALUE1 = "value1" } enum Enum2 { VALUE2 = "value2" } const func1 = (e: Enum1) => e; const f ...

The selected attribute does not function properly with the <option> tag in Angular

Currently, I am faced with a challenge involving dropdowns and select2. My task is to edit a product, which includes selecting a category that corresponds to the product. However, when I open the modal, the selected group/category is not displayed in the d ...

How to disable items in Vuetify's v-select without having to modify the object

After searching extensively, I have only come across information in the official documentation indicating that v-select's items can be disabled by setting the object's disable property to true as shown below: {text: 'text1', disabled: t ...

Issue: Unable to locate a differ that supports the object '[object Object]' of type 'object'. NgFor can only bind to Iterables like Arrays

I have successfully pulled data from the jsonplaceholder fake API and now I am attempting to bind it using Angular 2 {{}} syntax. However, I encountered an error that states: "Error: Cannot find a differ supporting object '[object Object]' of typ ...

Create an input field with a dynamic and exclusive identifier using the DataTables plugin

I am having trouble creating unique IDs for each input field based on the number of rows Here is the code snippet: $(document).ready(function() { var oTable = $('#jsontable').dataTable(); //Initialize the datatable $.ajax({ url ...

Does the PHP include function act as an HTTP request?

After coming across an article highlighting the negative impact of using excessive HTTP requests on server speed, I started wondering about the performance implications of PHP includes. Specifically, I'm curious if sending 4 AJAX requests compared to ...

What is the best way to send the entire image to an API route in Next.js so that I can save it using FS and then upload it to Cloudinary?

I have a form here that utilizes React Hook Form. I'm wondering what I need to pass to the API endpoint via fetch in order to write an image to disk using fs, retrieve its location, and then send that location to Cloudinary. In the body of the fetch ...

Nonconforming Typescript argument specification

I've been struggling to pass this TypeScript array to a function. Despite trying multiple parameter types in an attempt to get it to compile, none of them have worked so far. Here is the array in question: var driverTally = [ { dr ...

Optimal Approach for Redirecting Authorization

I'm currently working on setting up an authorization feature for my Angular application. Here is the detailed process I am following: First, I generate a state and code in the front end. Upon clicking the login button, the application redirects to /a ...

The issue of saving Rails input from an Angular2 front end has been causing some trouble

Currently, I am in the process of developing a front-end application using Angular 2 that retrieves data from a Rails 5 API. This specific application serves as a network inventory tool. One particular feature of this app is an Asset-form in Angular2 whic ...