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.