vue实现星级评分
实现星级评分的基本思路
在Vue中实现星级评分通常需要创建一个可交互的组件,允许用户点击或悬停选择评分。核心逻辑包括渲染星星图标、处理用户交互以及动态更新评分状态。
使用Font Awesome图标库
安装Font Awesome库可以方便地使用星星图标:
npm install @fortawesome/fontawesome-svg-core @fortawesome/free-solid-svg-icons @fortawesome/vue-fontawesome
基础组件代码示例
<template>
<div class="star-rating">
<span
v-for="star in maxStars"
:key="star"
@click="rate(star)"
@mouseover="hoverRating = star"
@mouseleave="hoverRating = 0"
>
<font-awesome-icon
:icon="['fas', star <= (hoverRating || currentRating) ? 'star' : 'star-o']"
:class="{ 'active': star <= (hoverRating || currentRating) }"
/>
</span>
<p v-if="showRating">当前评分: {{ currentRating }} / {{ maxStars }}</p>
</div>
</template>
<script>
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import { faStar, faStarO } from '@fortawesome/free-solid-svg-icons'
export default {
components: {
FontAwesomeIcon
},
data() {
return {
currentRating: 0,
hoverRating: 0,
maxStars: 5
}
},
methods: {
rate(star) {
this.currentRating = star
}
}
}
</script>
<style>
.star-rating {
font-size: 24px;
}
.star-rating span {
cursor: pointer;
margin-right: 5px;
}
.star-rating .active {
color: gold;
}
</style>
实现半星评分功能
如需实现半星评分,需要修改图标渲染逻辑:
<template>
<div class="star-rating">
<span
v-for="star in maxStars"
:key="star"
@click="rate(star)"
@mouseover="hoverRating = star"
@mouseleave="hoverRating = 0"
>
<font-awesome-icon
v-if="star <= Math.floor(currentRating)"
:icon="['fas', 'star']"
class="active"
/>
<font-awesome-icon
v-else-if="star - 0.5 <= currentRating"
:icon="['fas', 'star-half-alt']"
class="active"
/>
<font-awesome-icon
v-else
:icon="['fas', 'star']"
/>
</span>
</div>
</template>
使用SVG实现自定义星星
如需完全自定义星星样式,可以使用SVG:
<template>
<div class="star-rating">
<svg
v-for="star in maxStars"
:key="star"
@click="rate(star)"
@mouseover="hoverRating = star"
@mouseleave="hoverRating = 0"
width="24"
height="24"
viewBox="0 0 24 24"
>
<path
:d="star <= (hoverRating || currentRating) ? filledStarPath : emptyStarPath"
:fill="star <= (hoverRating || currentRating) ? 'gold' : 'gray'"
/>
</svg>
</div>
</template>
<script>
export default {
data() {
return {
filledStarPath: "M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z",
emptyStarPath: "M22 9.24l-7.19-.62L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21 12 17.27 18.18 21l-1.63-7.03L22 9.24zM12 15.4l-3.76 2.27 1-4.28-3.32-2.88 4.38-.38L12 6.1l1.71 4.04 4.38.38-3.32 2.88 1 4.28L12 15.4z"
}
}
}
</script>
组件属性扩展
为增加组件复用性,可以添加props:
props: {
rating: {
type: Number,
default: 0
},
maxStars: {
type: Number,
default: 5
},
editable: {
type: Boolean,
default: true
}
}
事件触发
通过$emit将评分变化通知父组件:
methods: {
rate(star) {
if (!this.editable) return
this.currentRating = star
this.$emit('rating-changed', star)
}
}





