当前位置: 首页 > article >正文

vue3实现星星打分组件

1、整颗星全打

<template>
  <div class="star-rating">
    <span
      v-for="index in 5"
      :key="index"
      class="star"
      :class="{ active: index <= (hoverIndex || rating) }"
      @click="setRating(index)"
      @mousemove="hoverIndex = index"
      @mouseleave="hoverIndex = null"
    >
      ★
    </span>
  </div>
</template>

<script setup>
import { ref } from "vue";

const rating = ref(0); // 当前评分值(0-5)
const hoverIndex = ref(null); // 鼠标悬停时的星星索引

// 设置评分值
const setRating = (index) => {
  rating.value = index;
  console.log("rating set:", index, "hoverIndex:", hoverIndex.value);
};

// 观测下两个值的变化
watch([rating, hoverIndex], ([newRating, newHoverIndex]) => {
  console.log("new rating:", newRating, "new hoverIndex:", newHoverIndex);
});
</script>

<style scoped>
.star-rating {
  display: inline-flex;
  font-size: 24px;
  color: #ccc;
}

.star {
  cursor: pointer;
  margin: 0 2px;
  transition: color 0.2s;
}

.star.active {
  color: gold;
}

.star:hover {
  color: gold;
}
</style>

2、可以打半颗星

<template>
    <div class="star-rating">
      <span
        v-for="index in 5"
        :key="index"
        class="star-container"
        @click="setRating($event,index)"
        @mousemove="handleHover($event,index)"
        @mouseleave="hoverRating = null"
      >
        <span class="star-background">★</span>
        <span
          class="star-foreground"
          :style="getStarStyle(index)"
        >★</span>
      </span>
    </div>
  </template>
  
  <script setup>
  import { ref, computed } from 'vue';
  
  const rating = ref(0); // 当前评分值(0-10)
  const hoverRating = ref(null); // 鼠标悬停时的评分值
  
  // 设置评分
  const setRating = (event,index) => {
    const clickX = event.offsetX; // 获取点击位置相对于星星的横坐标
    const starWidth = event.target.offsetWidth; // 获取星星的宽度
    const isHalf = clickX < starWidth / 2; // 判断是否点击了左半边
    rating.value = (index - 1) * 2 + (isHalf ? 1 : 2); // 计算评分值
  };
  
  // 处理鼠标悬停
  const handleHover = (event,index) => {
    const hoverX = event.offsetX; // 获取悬停位置相对于星星的横坐标
    const starWidth = event.target.offsetWidth; // 获取星星的宽度
    const isHalf = hoverX < starWidth / 2; // 判断是否悬停在左半边
    hoverRating.value = (index - 1) * 2 + (isHalf ? 1 : 2); // 计算悬停评分值
  };
  
  // 获取星星前景的样式
  const getStarStyle = (index) => {
    const currentRating = hoverRating.value || rating.value; // 当前显示的评分值
    const starValue = (index - 1) * 2; // 当前星星的起始分值
    let width = '0%';
  
    if (currentRating >= starValue + 2) {
      width = '100%'; // 整颗星
    } else if (currentRating >= starValue + 1) {
      width = '50%'; // 半颗星
    }
  
    return { width };
  };

  // 观测下两个值的变化
watch([rating, hoverRating], ([newRating, newHoverRating]) => {
  console.log("half new rating:", newRating, "new hoverRating:", newHoverRating);
});
  </script>
  
  <style scoped>
  .star-rating {
    display: inline-flex;
    font-size: 24px;
    color: #ccc;
  }
  
  .star-container {
    position: relative;
    cursor: pointer;
    margin: 0 2px;
  }
  
  .star-background,
  .star-foreground {
    display: inline-block;
    font-size: inherit;
  }
  
  .star-background {
    color: #ccc; /* 未选中的星星颜色 */
  }
  
  .star-foreground {
    position: absolute;
    top: 0;
    left: 0;
    color: gold; /* 选中的星星颜色 */
    overflow: hidden;
    white-space: nowrap;
  }
  </style>

css部分解析:

1. .star-rating
  • display: inline-flex;:

    • 将容器设置为弹性盒子布局,使星星水平排列。

  • font-size: 24px;:

    • 设置星星的大小为 24px。

  • color: #ccc;:

    • 设置默认的星星颜色为灰色(未选中状态)。

2. .star-container
  • position: relative;:

    • 设置相对定位,为子元素(.star-foreground)的绝对定位提供参考。

  • cursor: pointer;:

    • 将鼠标指针设置为手型,表示星星是可点击的。

  • margin: 0 2px;:

    • 设置星星之间的间距为 2px。

3. .star-background 和 .star-foreground

这两层 span 用于实现半星效果:

  • .star-background:

    • 显示未选中的星星(灰色)。

    • color: #ccc;:

      • 设置背景星星的颜色为灰色。

  • .star-foreground:

    • 显示选中的星星(金色)。

    • position: absolute;:

      • 设置为绝对定位,覆盖在 .star-background 之上。

    • top: 0; left: 0;:

      • 将前景星星定位到容器的左上角。

    • color: gold;:

      • 设置前景星星的颜色为金色。

    • overflow: hidden;:

      • 隐藏超出容器范围的内容,用于实现半星效果。

    • white-space: nowrap;:

      • 防止文本换行,确保星星显示为单行。

半星效果是通过控制 .star-foreground 的宽度来实现的:

  • 如果星星是半星,设置 .star-foreground 的宽度为 50%,只显示左半边。

  • 如果星星是整星,设置 .star-foreground 的宽度为 100%,显示完整的星星。


http://www.kler.cn/a/585678.html

相关文章:

  • Java 集合框架大师课:集合框架的暗黑料理(六)
  • 数据结构(三)——链表
  • 流水线(Pipeline)
  • Linux 进程的创建、终止、等待与程序替换函数 保姆级讲解
  • KICK第五课:Mac 系统下安装 Xcode 或 Clang
  • C++初阶——类和对象(一)
  • 3DS模拟器使用(pc+安卓)+金手指+存档互传
  • visual studio编译fortran
  • Springboot项目发送请求
  • 什么是提示词工程,有哪些开源项目
  • Android Studio执行Run操作报Couldn‘t terminate previous instance of app错误
  • (动态规划 区间dp/dfs 最长回文子序列)leetcode 516
  • MATLAB R2024b 安装教程
  • 深入理解 ALSA 声卡驱动:从理论到实践,解决嵌入式 Linux 声卡无声问题
  • 基于Asp.net的医院病历管理系统
  • 射频相关概念
  • MySQL | MySQL表的增删改查(CRUD)
  • 使用 Swiss Table 如何实现更快的 Go map
  • 大模型高效优化技术全景解析:微调、量化、剪枝、梯度裁剪与蒸馏
  • chmod用法