How can a parent component update a child component's prop value in VUE?

I'm facing an issue with managing dynamic props in Vue with TypeScript. Below is my parent component:

<script setup lang="ts">
const friends = [
  {
    id: "emanuel",
    name: "Emanuella e",
    phone: "08788",
    email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="1a7f777b746f7f76767b5a7d777b73..."",
    isFavorite: true,
  },
  {
    id: "denta",
    name: "Denta W",
    phone: "08789",
    email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="1d797873697c5d7a707c74...:"",
    isFavorite: false,
  },
];

function toggleFavorite(friendId:any){
  console.log(friendId);
  const identifiedFriend= friends.find(friend=>friend.id === friendId);
  if(identifiedFriend!=undefined){
    identifiedFriend.isFavorite=!identifiedFriend.isFavorite
  }
  console.log(identifiedFriend);
}
</script>

<template>
  <section>
    <header><h1>Test Friends</h1></header>
    <ul>
      <friend-container
        v-for="friend in friends"
        :id="friend.id"
        :key="friend.id"
        :name="friend.name"
        :phone="friend.phone"
        :email="friend.email"
        :isFavorite="friend.isFavorite"
        @toggle-favorite="toggleFavorite"
      >
      </friend-container>
    </ul>
  </section>
</template>

Below is my child component:

<template>
  <li>
    <h2>{{ name }} {{ isFavorite ? "(Favorite)" : "" }}</h2>
    <button @click="toggleFavorite">Toggle Favorite</button>
    <button @click="toggleDetails">Show details</button>
  
    <ul v-if="detailAreVisible">
      <li><strong>Phone: </strong>{{ phone }}</li>
      <li><strong>email: </strong>{{ email }}</li>
    </ul>
  </li>
</template>

<script setup lang="ts">

import { ref} from 'vue';

const detailAreVisible=ref(false);

const props = defineProps<{
  id: { type: String; required: true };
  name: { type: String; required: true };
  phone: { type: String; required: true };
  email: { type: String; required: true };
  isFavorite: Boolean
}>();

const emit=defineEmits<{
    (e: 'toggle-favorite', value: any): void
}>()
function toggleDetails(){
    detailAreVisible.value=!detailAreVisible.value
}

function toggleFavorite(){
    emit("toggle-favorite",props.id);
  
}
</script>

I have updated the props data in the parent component using emit event handling. However, the isFavorite value in my child component still cannot be changed. Did I miss something or how should I handle it? Sorry, I'm new to Vue.

Answer №1

To ensure that the state of friends is responsive to changes, it is recommended to declare it with the reactive function in Vue. Additionally, for a more concise code, consider using only v-bind with multiple attributes since the property names match the keys in the state:

<script setup lang="ts">
import {reactive} from 'vue'

const friends = reactive([
  {
    id: "emanuel",
    name: "Emanuella e",
    phone: "08788",
    email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f1949c909f84949d9d90b1969c90989ddf929e9c">[email protected]</a>",
    isFavorite: true,
  },
  {
    id: "denta",
    name: "Denta W",
    phone: "08789",
    email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d9bdbcb7adb899beb4b8b0b5f7bab6b4">[email protected]</a>",
    isFavorite: false,
  },
]);

function toggleFavorite(friendId:any){
  console.log(friendId);
  const identifiedFriend= friends.find(friend=>friend.id === friendId);
  if(identifiedFriend != undefined){
    identifiedFriend.isFavorite = !identifiedFriend.isFavorite
  }
  console.log(identifiedFriend);
}
</script>

<template>
  <section>
    <header><h1>Test Friends</h1></header>
    <ul>
      <friend-container
        v-for="friend in friends"
        :key="friend.id"
         v-bind="friend"
        @toggle-favorite="toggleFavorite"
      >
      </friend-container>
    </ul>
  </section>
</template>


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

I'm having trouble locating the Nuxtjs logs on our production server. Can someone

An unexpected error popped up when I switched to online prod mode. https://i.stack.imgur.com/GI0Y8.png Can anyone point me in the direction of the logs for Nuxt.js in production? I tried looking through the documentation but couldn't find any menti ...

Implementing dynamic option selection in Vue using JavaScript and v-model

Is there a way to manage the chosen value in a v-modeled select tag using vue.js? I created a jsFiddle demonstration, but unfortunately, it is not functioning correctly. This leads to my inquiry: vm.$set('selected', '1') // does not wo ...

Does tns preview offer support for Vuex?

Since integrating Vuex into my NativeScript-Vue mobile app, I have encountered an issue where tns preview fails to resolve modules that rely on Vuex. Interestingly, the application functions properly when using tns run or tns build. This problem is prese ...

defining initial state values for a React class component using TypeScript

Here is the current state of the component: class Feed extends Component<FeedProps, FeedState> { constructor(props) { super(props); this.state = { isEditing: false, posts: [], totalPosts: 0, editPost: null, sta ...

Can we determine the data type of a value within a class instance by utilizing a function to retrieve it?

Is it feasible to create a function that maintains typing and functions in the same way as this: class Example { someNumber:number = 1; someString:string = "test"; } const example = new Example(); const value = example.someNumber; // typ ...

Vue js: Stop Sorting array items; only display the resulting array

I recently came across a tutorial on voting for a Mayoral Candidate. The tutorial includes a sort function that determines the winner based on votes. However, I noticed that the sort function also rearranges the candidate list in real time, which is not id ...

What steps can I take to troubleshoot and repair my accordion feature within an Angular project?

As a newcomer to Angular, I recently attempted to create an accordion component but encountered unexpected behavior. Here is the HTML code for my attempt: <div class="faq-item-container"> <h1 class="mt-1 mb-5"><strong>Frequently A ...

What is the best way to bring two useStyles files into a single TypeScript file?

I am having an issue with finding a declaration file for the module 'react-combine-styles' even after I installed it using npm install @types/react-combine-styles. import React, { useState } from "react"; import useStyles from "./u ...

Refining strings to enum keys in TypeScript

Is there a method to refine a string to match an enum key in TypeScript without needing to re-cast it? enum SupportedShapes { circle = 'circle', triangle = 'triangle', square = 'square', } declare const square: string; ...

Encountering the error "tsx is not defined" during a Jest test in a React/TypeScript project

I'm currently working on implementing Jest tests within a React project that has enforced TypeScript settings. In a simple test.tsx file located in the test folder, I have the following code: import React from 'react'; describe('Test& ...

Is it possible to lengthen a function in TypeScript?

I am part of a team responsible for maintaining a unique JavaScript library that generates spy functions. These spy functions are designed to allow users to monitor how a function is called, primarily used in the context of unit testing. Our library creat ...

The wildcard syntax for importing statements in Angular 2

I created multiple classes in a single file with the following structure file: myclasses.ts export class Class1 {....} export class Class2 {....} export class Class3 {....} Now I am attempting to import all of them using a wildcard like this import {*} ...

Inference in Typescript - Detecting unknown key in an object

I am struggling to implement type inference from a props object that is passed to a component and then used in a render function. While I can retrieve the keys of the object correctly, all types are being interpreted as unknown. I need some assistance in f ...

In JavaScript, what do we call the paradigm where a variable equals a variable equals a function? Let's take

Feeling a bit overloaded at the moment, so forgive me if this question seems too simple. I managed to accidentally write some code in Jest for testing a Vue application that actually works: const updateMethod = wrapper.vm.updateMethod = jest.fn() expect(u ...

Looking to implement the v-model with a bootstrap-vue b-form-radio on a webpage? Here's how you can

bootstrap-vue When the server side sends me the N categories for radio button groups in JSON format, users will be prompted to rate each category as a priority - high, medium, or low. I need to dynamically generate radio button groups for each category to ...

cycle through options of radio buttons

How can I display items of radio buttons, with the values of these items coming from a backend api? <div class="input-group col-md-9 input-group-sm"> <label>gender</label> </div> <!-- TO CORRECT ...

Manipulating the length of an array based on a specified range using Vue.js

I'm currently working on a client's range filtering feature using Vue.js. The filter involves an input element with the type range to adjust the total number of clients displayed. I have successfully linked the value of the input to the **clients ...

Utilize the identical function value within a Vue template

In my template, I am encountering a recurring situation where I need to retrieve a value from a function. This function takes parameters from the template (such as the index of a v-for loop) and returns a result that is then displayed on the template. The ...

Experimenting with Vue in conjunction with a web component

I am facing an issue with astrouxds web components in my application. During testing, I am receiving a warning that needs to be resolved. Additionally, I need help on how to properly assert a value in the web component. console.error node_modules/vue/dis ...

Add a class individually for each element when the mouse enters the event

How can I apply the (.fill) class to each child element when hovering over them individually? I tried writing this code in TypeScript and added a mouseenter event, but upon opening the file, the .fill class is already applied to all elements. Why is this ...