57 lines
895 B
Vue
57 lines
895 B
Vue
<script setup>
|
|
const props = defineProps({
|
|
value: {
|
|
type: Number,
|
|
default: 0,
|
|
},
|
|
readonly: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
size: {
|
|
type: String,
|
|
default: "36rpx",
|
|
},
|
|
});
|
|
|
|
const emit = defineEmits(["update:value"]);
|
|
|
|
const handleTap = (star) => {
|
|
if (props.readonly) return;
|
|
emit("update:value", star);
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<view class="rating-star" :class="{ interactive: !readonly }">
|
|
<text
|
|
v-for="i in 5"
|
|
:key="i"
|
|
class="star"
|
|
:class="{ filled: i <= value }"
|
|
:style="{ fontSize: size }"
|
|
@tap="handleTap(i)"
|
|
>{{ i <= value ? "★" : "☆" }}</text>
|
|
</view>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.rating-star {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.rating-star.interactive .star {
|
|
padding: 0 4rpx;
|
|
}
|
|
|
|
.star {
|
|
color: #d1d5db;
|
|
transition: color 0.15s;
|
|
}
|
|
|
|
.star.filled {
|
|
color: #f59e0b;
|
|
}
|
|
</style>
|