javascript VueJS -如何使单选按钮在id与某个值匹配时被选中

jrcvhitl  于 2023-01-24  发布在  Java
关注(0)|答案(1)|浏览(154)

我在一个数组中有对象(产品)。每个产品都有自己的评级,评级是来自数据库的数字。我在产品本身上显示每个产品的四舍五入平均评级。

{{ Math.round(Object.values(product.rating)[0]) }}

我想在人们用来给产品评分的星(单选按钮)中显示平均值。如果我单击给产品评分,则应检查与当前评分匹配的星数。对于单个产品,我可以只使用v-model,但如果列表中有一堆产品,并且每个产品都有不同的评分,我该怎么办?
每个单选按钮的值是ID和value属性。如何将单选按钮的ID或值与产品的当前等级相匹配?
没有this,所以我尝试这样做,但显然不起作用:

<div class="rating">
  <input
    type="radio"
    value="5"
    id="5"
    :checked="
    this.value ==
    Math.round(Object.values(product.rating)[0])
    "
    @change="rateproduct"
    /><label for="5">☆</label>
  <input
    type="radio"
    value="4"
    id="4"
    @change="rateproduct"
    :checked="
    this.value ==
    Math.round(Object.values(product.rating)[0])
    "
    /><label for="4">☆</label>
  <input
    type="radio"
    value="3"
    id="3"
    @change="rateproduct"
    :checked="
    this.value ==
    Math.round(Object.values(product.rating)[0])
    "
    /><label for="3">☆</label>
  <input
    type="radio"
    value="2"
    id="2"
    @change="rateproduct"
    :checked="
    this.value ==
    Math.round(Object.values(product.rating)[0])
    "
    /><label for="2">☆</label>
  <input
    type="radio"
    value="1"
    id="1"
    @change="rateproduct"
    :checked="
    this.value ==
    Math.round(Object.values(product.rating)[0])
    "
    /><label for="1">☆</label>
</div>

我尝试这样做,但它也不工作:

<input
  type="radio"
  value="5"
  id="5"
  :checked="
  Math.round(Object.values(post.rating)[0])
  ? 'checked'
  : ''
  "
  @change="ratePost"
  /><label for="5">☆</label>
</input>
rdrgkggo

rdrgkggo1#

一个可能的解决方案是:

Vue SFCPlayground链接

<template>
    <fieldset>
        <legend>Average Star Rating</legend>
        <div class="radios">
            <div class="radioGroup" v-for="index in MAX_VALUE" :key="index">
                <input 
                    type="radio" 
                    name="stars" 
                    :value="index" 
                    v-model="starValue" 
                    @click.prevent=""
                />
                <label>{{ index }} {{ starText(index) }}</label>
            </div>
        </div>
        <div>
            Average Rating: {{  roundedAverageValue }}
        </div>
    </fieldset>
    <fieldset>
        <legend>Individual Item Ratings</legend>
        <div v-for="(slider, index) in sliderValues" :key="index" >
            <label for="slider.name" class="sliderLabel">{{ slider.name }}</label>
            <input 
                type="range" 
                name="starSlider" 
                :min="MIN_VALUE" 
                :max="MAX_VALUE" 
                v-model="slider.value"
            >
            Value: {{ slider.value }}
        </div>
        <div>
            Average: {{ averageValue }}
        </div>
    </fieldset>

</template>

<script setup>
import { ref, watch, computed } from 'vue';

const MIN_VALUE = 1;
const MAX_VALUE = 5;

const starValue = ref(1);
const sliderValues = ref([
    { 
        value: MIN_VALUE,
        name: 'Item 1',
     },
     { 
        value: MIN_VALUE,
        name: 'Item 2',
     },
     { 
        value: MIN_VALUE,
        name: 'Item 3',
     },
     { 
        value: MIN_VALUE,
        name: 'Item 4',
     },
]);

const starText = (index) => {
    return index > 1 ? 'stars' : 'star';
}

const averageValue = computed(() => {
    let sum = 0;
    sliderValues.value.forEach((sv) => {
        sum += parseInt(sv.value);
    })
    return sum / sliderValues.value.length;
});

const roundedAverageValue = computed(() => {
    return Math.round(averageValue.value);
});

watch(roundedAverageValue, (newValue) => {
    starValue.value = newValue;
})
</script>

<style scoped>
fieldset {
  margin: 20px 70px;
  text-align: center;
}

.radioGroup {
  display: inline-block;
  text-align: center;
  margin: 10px;
}

.radioGroup label {
    display: block;
}

.sliderLabel {
    margin-right: 8px;
}
</style>

说明:
这将使用v-创建无线电输入,从1到5:v-for="index in 5"。每个无线电的值是for循环的int索引。所有无线电的模型都是相同的,starValue
然后,我使用对象数组来创建我的滑块,使用计算属性来获取平均值,并使用计算属性上的监视器来更改无线电的模型值(因为在计算属性中有副作用是不好的做法)。

相关问题