vue实现星星评分
实现星星评分的基本思路
在Vue中实现星星评分功能,可以通过组件化的方式完成。核心逻辑包括渲染星星图标、处理用户交互以及动态更新评分状态。
创建星星评分组件
创建一个名为StarRating.vue的组件文件,用于封装星星评分的逻辑和UI。
<template>
<div class="star-rating">
<span
v-for="star in maxStars"
:key="star"
@click="setRating(star)"
@mouseover="hoverRating(star)"
@mouseleave="resetRating"
>
<span :class="['star', { 'filled': star <= currentRating }]">★</span>
</span>
<p v-if="showRating">当前评分: {{ currentRating }} / {{ maxStars }}</p>
</div>
</template>
<script>
export default {
props: {
maxStars: {
type: Number,
default: 5
},
initialRating: {
type: Number,
default: 0
},
showRating: {
type: Boolean,
default: true
}
},
data() {
return {
currentRating: this.initialRating,
tempRating: 0
};
},
methods: {
setRating(star) {
this.currentRating = star;
this.$emit('rating-selected', star);
},
hoverRating(star) {
this.tempRating = this.currentRating;
this.currentRating = star;
},
resetRating() {
this.currentRating = this.tempRating;
}
}
};
</script>
<style scoped>
.star-rating {
font-size: 24px;
cursor: pointer;
}
.star {
color: #ccc;
}
.filled {
color: gold;
}
</style>
使用星星评分组件
在父组件中引入并使用StarRating组件,处理评分结果。
<template>
<div>
<h2>评价我们的服务</h2>
<StarRating
:max-stars="5"
:initial-rating="3"
@rating-selected="handleRating"
/>
</div>
</template>
<script>
import StarRating from './StarRating.vue';
export default {
components: {
StarRating
},
methods: {
handleRating(rating) {
console.log('用户评分:', rating);
// 可以在这里处理评分数据,如提交到服务器
}
}
};
</script>
自定义星星样式
如果需要使用自定义图标代替默认的星形字符,可以通过引入字体图标库(如Font Awesome)来实现。
<template>
<span :class="['star-icon', { 'filled': star <= currentRating }]">
<i class="fas fa-star"></i>
</span>
</template>
<style scoped>
.star-icon i {
color: #ccc;
}
.star-icon.filled i {
color: gold;
}
</style>
实现半星评分
若要支持半星评分功能,需要修改评分逻辑和渲染方式。
<template>
<div class="star-rating">
<span
v-for="star in starsArray"
:key="star.index"
@click="setRating(star.value)"
@mouseover="hoverRating(star.value)"
@mouseleave="resetRating"
>
<span class="star-container">
<span class="star-background">★</span>
<span
class="star-foreground"
:style="{ width: star.fill + '%' }"
>★</span>
</span>
</span>
</div>
</template>
<script>
export default {
props: {
maxStars: {
type: Number,
default: 5
},
increment: {
type: Number,
default: 0.5
}
},
computed: {
starsArray() {
const stars = [];
for (let i = 1; i <= this.maxStars; i++) {
stars.push({
index: i,
value: i,
fill: this.getStarFill(i)
});
}
return stars;
}
},
methods: {
getStarFill(starValue) {
if (this.currentRating >= starValue) {
return 100;
}
if (this.currentRating > starValue - 1) {
return (this.currentRating - (starValue - 1)) * 100;
}
return 0;
}
}
};
</script>
<style scoped>
.star-container {
position: relative;
display: inline-block;
font-size: 24px;
}
.star-background {
color: #ccc;
}
.star-foreground {
position: absolute;
left: 0;
top: 0;
width: 0;
overflow: hidden;
color: gold;
}
</style>
注意事项
- 组件应保持良好的可复用性,通过props接收配置参数
- 事件处理应通过emit与父组件通信
- 样式可以使用CSS预处理器增强可维护性
- 对于复杂场景,可以考虑使用第三方评分库如vue-star-rating






