If there are multiple instances of the component, it may not function properly

I have implemented a Vue component as shown below:

<script setup lang="ts">
  import { PropType } from "nuxt/dist/app/compat/capi";
  interface Star {
    id: string;
    value: number;
  }

  const stars: Star[] = [
    { id: "star5", value: 5 },
    { id: "star4.5", value: 4.5 },
    { id: "star4", value: 4 },
    { id: "star3.5", value: 3.5 },
    { id: "star3", value: 3 },
    { id: "star2.5", value: 2.5 },
    { id: "star2", value: 2 },
    { id: "star1.5", value: 1.5 },
    { id: "star1", value: 1 },
    { id: "star0.5", value: 0.5 },
  ];

  const props = defineProps({
    ratingValue: {
      type: Number as PropType<number>,
    },
    starColor: {
      type: String as PropType<string>,
    },
  });

  const emit = defineEmits(["ratingChange"]);
  const selectedRating = ref<number | undefined>(undefined);

  const roundedRating = computed(() => {
    if (props.ratingValue !== undefined) {
      return Math.round(props.ratingValue * 2) / 2;
    } else {
      return selectedRating.value !== undefined
        ? Math.round(selectedRating.value * 2) / 2
        : undefined;
    }
  });

  const onRatingChange = (value: number) => {
    if (props.ratingValue === undefined) {
      selectedRating.value = value;
      emit("ratingChange", selectedRating.value);
    }
  };
</script>

<template>
  <div class="center">
    <div :class="['rating', { disable: props.ratingValue !== undefined }]">
      <template v-for="star in stars" :key="star.id">
        <input
          :id="star.id"
          v-model="roundedRating"
          :disabled="props.ratingValue !== undefined"
          type="radio"
          name="'rating'"
          :value="star.value"
          @input="onRatingChange(star.value)"
        />
        <label :for="star.id" :class="star.value % 1 === 0 ? 'full full-star' : 'half'"></label>
      </template>
    </div>
    <div class="rating-number">{{ props.ratingValue }}</div>
  </div>
</template>

When this component is used only once on the page, it functions correctly. However, when there are multiple instances of it, some issues arise.

For example, if you specify ratingValue, the number on the right is displayed, but the stars should only be painted in the last instance of the component.

<StarRating ratingValue="1" />
<StarRating ratingValue="4" />

I have tried to debug it, and I suspect the issue lies with selectedRating, but I have been unsuccessful in resolving it.

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

Answer №1

To ensure your name attributes are unique, consider implementing the following method:

JavaScript:

import { ref } from 'vue';

const uniqueId = ref(Date.now() + Math.random().toString(36).substr(2, 9));

HTML Template:

<input
  :id="star.id"
  v-model="roundedRating"
  :disabled="props.ratingValue !== undefined"
  type="radio"
  :name="`rating-${uniqueId}`"
  :value="star.value"
  @input="onRatingChange(star.value)"
/>

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

Retrieve the value of a property in a JavaScript object by specifying a dynamic key for the property

As I work on my current project, I find myself immersed in a world of SVG animations. The challenge lies in triggering these animations as the user scrolls down to view the SVGs. To address this, I took the approach of creating functions for each Snap.SVG ...

Mocking a third-party callback function in Jest for method implementation

Utilizing Nest + Cognito for user authentication in an application, I have a method within my Authentication service that requires testing/mocking: async cognitoRegister(userPool: CognitoUserPool, { name, password, email }: AuthRegisterInput): ...

Learn the method of conditionally resetting the state count using React hooks

When a user submits the form, the handleSubmit function runs to count the number of li elements with class names containing "show" within the search results div. It adds up these counts using setStoreCount(prevCount => prevCount + 1) and updates the UI ...

``Is there a way to retrieve the value of a Vue object with the help of Selenium WebDriver?

My HTML code snippet is as follows: <div data-v-58fe9fbf="" data-v-5de8f7f2="" class="copy-button" id="cta_get_link"> <input data-v-58fe9fbf="" type="text" readonly="readonly" c ...

quickest method for attaching a click listener to dynamically added elements in the document object model

When adding multiple elements to the DOM, how can we ensure that these elements also have a click handler attached to them? For instance, if there is a click handler on all elements with the "canvas-section" class, and new "canvas-section" elements are con ...

Removing characters from a string with regular expressions

I need to eliminate instances of << any words #_ from the given text. stringVal = "<<Start words#_ I <<love#_ kind <<man>>, <<john#_ <<kind man>> is really <<great>> <<end words#_ "; The d ...

The distortion of Blender animation becomes apparent once it is imported into three.js

I've been working on a project where I'm incorporating animations into a scene using a combination of blender and three.js. It took me several hours of trial and error to finally get the model and animation successfully imported into three.js. I ...

Update the array by incorporating a new object that corresponds to a provided list with a unique key-value pair

When selecting objects from a list using a checkbox, I want to make the selection recognizable by adding a new key-value pair to the selected objects with the label of the selected value. This is what I have tried: var checkCheckboxOnOff = [{"fieldName": ...

Date parsing error thrown by jQuery datepicker plugin

What could be causing the InvalidDate exception when attempting to parse the date using $.datepicker.parseDate("mm/yy","02/2008");? ...

Enhance v-file-input with validation

How can I make sure that a file has been chosen using v-file-input and ValidationProvider from vee-validate? Check out the code below: <v-flex> <ValidationProvider rules="required" v-slot="{ errors }"> <v-file-inpu ...

Observing a profound watch object results in an ESLint warning

I am working with an object called date and I want to monitor any changes that occur within this object. However, I keep receiving a warning message stating: Unexpected unnamed method 'date.fontsize' func-names. How can I resolve this issue? He ...

What is the best way to change the "MuiPaper-elevation1" attribute in a Card element within Material-UI?

My Card component in HTML looks like this: <div class="MuiPaper-root MuiCard-root makeStyles-Card-5 MuiPaper-elevation1 MuiPaper-rounded"> I want to change MuiPaper-elevation1 to MuiPaper-elevation0 to remove the shadow. I attempted: ...

Jquery Enhancement for Navigation

Recently, I have implemented a header and footer navigation on my website. The header navigation consists of 1 UL (unordered list), while the footer navigation comprises 5 ULs. My goal is to align the first child of each UL in the footer navigation with th ...

What is the best way to modify a single item within a v-for loop in Vue.js 3?

I am attempting to achieve the following: <tr v-for="item in items" :key='item'> <td v-for="field in fields" :key='field'> {{ item[field.toLowerCase()] }} </td> </tr> It seems that ...

Is it possible to configure Nginx to provide HTTPS on port 10000 and implement Basic Auth for an Express app?

My Linux NodeJS/Express application is designed to serve a text file located at http://example.com/secret.txt. I am looking to restrict access to this file only over HTTPS on port 10000 with Basic Auth security measures in place. It's important to no ...

"Key challenges arise when attempting to execute the node app.js script through the terminal due to various middleware compatibility

I'm a beginner with node.js and I've encountered an issue while trying to run my node app.js file after incorporating a new file named projects.js which contains the following JS code: exports.viewProject = function(req, res){ res.render(" ...

What steps are involved in setting up a search results page for example.com/s/keyword?

app.js app.get('/results',showResult) var express = require('express') var n = req.query.query; mysql_crawl.query('SELECT prod_name, full_price FROM `xxx` WHERE MATCH(data_index) AGAINST("'+n+'")', function(error, p ...

Can you guide me on how to export a named function using module.exports?

I have a script file for my discord bot that includes a specific command and a function with parsing logic that I want to reuse in my main index.js // File: ./commands/scrumPrompt.js // The function const extractDeets = function (f, scrum) { let items ...

Retrieve TypeScript object after successful login with Firebase

I'm struggling with the code snippet below: login = (email: string, senha: string): { nome: string, genero: string, foto: string;} => { this.fireAuth.signInWithEmailAndPassword(email, senha).then(res => { firebase.database().ref(&ap ...

Is Node.js functioning properly, but how can I incorporate it into a web browser?

I have a SQL Server table that I want to display in a web browser using the DataTables jQuery plugin. The code below works well for outputting data in the command line, but I need it to be displayed in the browser, possibly in JSON format. I am utilizing ...