likes
comments
collection
share

五星评分的效果是怎么实现的

作者站长头像
站长
· 阅读数 91

前言

如今外卖平台、电商平台乃至日常的生活中,五星评价已经成为用户反馈产品和服务质量的常用方式。这种评分方式不仅能让用户快速给出评价,同时也让其他用户可以更直观地感受到产品的受欢迎程度,这篇文章我将带你实现一个五星评价的小demo。

技术栈

  • HTML:展示星星图标
  • CSS:样式
  • JS与vue:实现页面动态交互与数据传输

实现过程

功能:

在鼠标移到第几颗星星上时就亮几颗星星,点击后便保持这个状态,只是单纯移开就恢复上一次的星星数量。

原理:

让实星覆盖空星,即用★把☆盖住。

文件结构:

五星评分的效果是怎么实现的

App.vue:

五星评分的效果是怎么实现的

概述:

在script中定义响应式的score(星星的数量),update方法(用于更新星星的数量),然后将它们两个传给Rate1.vue,我们要遵循组件间通信的原则,数据状态及修改归父组件管理。

Rate1.vue:

<template>
    <div :style="fontStyle">
        <div class="rate" @mouseout="mouseOut">
            <span @mouseover="mouseOver(num)" 
            v-for="num in 5" 
            :key="num">☆</span>
            <span class="hollow" :style="fontwidth">
                <span v-for="num in 5" 
                :key="num" @click="onRate(num)" 
                @mouseover="mouseOver(num)">★</span>
        </span>
        </div>
    </div>
</template>

<script setup>
import { defineProps, computed, defineEmits,ref } from 'vue'
// 组件自身的状态
let fontwidth = computed(() => `width:${width.value}em;`)
let props = defineProps({
    value: Number,
    theme: { type: String, default: 'orange' }
})
let width = ref(props.value)
let themeObj = {
    orange: '#fa541c',
    blue: '#40a9ff',
    green: '#73d13d',
    black: '#000',
    red: '#f5222d',
    yellow: '#ffaa00'
}
const fontStyle = computed(() => {
    return `color:${themeObj[props.theme]}`
})
let emits = defineEmits(["update-rate"])
const onRate = (num) => {
    emits("update-rate", num)
}
function mouseOver(i){  // 鼠标移到上面时动态改变星星数量
    width.value = i;
}
function mouseOut(){    // 鼠标移开时将星星保持先前的数量
    width.value = props.value
}

</script>
<style lang="css" scoped>
.rate{
    position: relative;
    display: inline-block;
}
.rate span {
    /* letter-spacing: 3px; */
    width:1em;
    display: inline-block;
}
.rate > span.hollow{
    position: absolute;
    display: inline-block;
    top:0;
    left:0;
    width: 0;
    height: 22px;
    overflow: hidden;   // 超出部分隐藏
}
</style>

举个例子:

为了让大家思路更加清晰,我们先把第65行这段十分重要的代码overflow: hidden注释,看看效果:

五星评分的效果是怎么实现的

当我们选择三颗星时,有两颗会出现在下面。

实现思路:

将空星星和实星定位在同一位置上,通过鼠标的操作更改实星星容器的宽度,让多余的星星被挤到下一行,然后给定只能放一行星星的容器高度,利用overflow: hidden将多余的星星隐藏。

为什么要用到defineEmits,而不是直接将update方法写到Rate1.vue中:

因为子组件与父组件之间的通信主要依赖于“props down, events up”的原则。这意味着子组件可以接收来自父组件的数据(通过 props),但不能直接修改这些数据。如果子组件需要改变父组件的状态,它应该通过触发自定义事件(使用 emits 选项)来通知父组件,然后由父组件决定是否以及如何改变其状态。

拓展:

细心的掘友会发现到其中有个themeObj包含着不同的颜色主题,它的作用就是让这个demo更好地复用,定义好多个主题,就比如某团代表黄色,饿了么代表蓝色,我们可以根据不同的开发要求来更换主题。

效果:

五星好评

五星评分的效果是怎么实现的

一般,我只能给到两星

五星评分的效果是怎么实现的

结语

这样我们就完成了一个五星评价的小demo,当然也有很多不同的实现方法,期待大家的分享。如果对代码哪里有疑问的话可以在评论区提出来,我都会进行解答。

转载自:https://juejin.cn/post/7389651543719166004
评论
请登录