ylj20011123 a289ea61b5 update
2025-09-12 18:08:40 +08:00

160 lines
3.0 KiB
Vue

<template>
<view class="star-rate">
<view
v-for="(item, index) in maxValue"
:key="index"
class="star-wrapper"
@click="handleClick(index + 1)"
>
<text class="star star-bg"></text>
<view class="star-fill" :style="getStarFillStyle(index + 1)">
<text class="star star-active"></text>
</view>
</view>
<text v-if="showText" class="score-text">{{ rating.toFixed(1) }}</text>
<!-- 调试信息 -->
<view class="debug-info">
<text>Rating: {{ rating }} / {{ maxValue }}</text>
</view>
</view>
</template>
<script>
export default {
name: 'StarRate',
props: {
value: {
type: [Number, String],
default: 0
},
max: {
type: [Number, String],
default: 5
},
allowHalf: {
type: Boolean,
default: true
},
disabled: {
type: Boolean,
default: false
},
readonly: {
type: Boolean,
default: true
},
showText: {
type: Boolean,
default: false
},
size: {
type: [Number, String],
default: 24
},
color: {
type: String,
default: '#FFD700'
},
disabledColor: {
type: String,
default: '#C0C4CC'
},
void: {
type: String,
default: '#C0C4CC'
}
},
computed: {
rating() {
let val = parseFloat(this.value) || 0
if (val > this.maxValue) val = this.maxValue
if (val < 0) val = 0
return val
},
maxValue() {
return parseInt(this.max) || 5
}
},
methods: {
getStarFillStyle(position) {
const rating = this.rating
let percentage = 0
if (rating >= position) {
// 当前星星应该完全点亮
percentage = 100
} else if (rating > position - 1) {
// 当前星星需要部分点亮(半星效果)
percentage = (rating - (position - 1)) * 100
} else {
// 当前星星不应该点亮
percentage = 0
}
return {
width: percentage + '%'
}
},
handleClick(score) {
if (this.readonly || this.disabled) return
let newScore = score
if (this.allowHalf && this.rating === score) {
newScore = score - 0.5
}
this.$emit('input', newScore)
this.$emit('change', newScore)
}
}
}
</script>
<style lang="less" scoped>
.star-rate {
display: flex;
align-items: center;
.star-wrapper {
position: relative;
margin-right: 4rpx;
display: inline-block;
.star {
font-size: 24rpx;
display: inline-block;
line-height: 1;
}
.star-bg {
color: #C0C4CC;
}
.star-fill {
position: absolute;
top: 0;
left: 0;
overflow: hidden;
.star-active {
color: #FFD700;
}
}
&:last-child {
margin-right: 0;
}
}
.score-text {
font-size: 20rpx;
color: #333;
margin-left: 10rpx;
}
.debug-info {
margin-top: 10rpx;
font-size: 18rpx;
color: #666;
}
}</style>