Vue3评分(Rate)

这篇具有很好参考价值的文章主要介绍了Vue3评分(Rate)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

可自定义设置以下属性: 

  • 是否允许再次点击后清除(allowClear),类型:boolean,默认 true

  • 是否允许半选(allowHalf),类型:boolean,默认 false

  • star 总数,类型:number,默认 5

  • 自定义字符(character),类型:string | slot ,默认 'star-filled',预置 'star-outlined' 'star-filled' 'heart-outlined' 'heart-filled' 四种svg图标

  • 字符时是字体高度,图标时是图片大小(size),类型:number,单位px,默认 20

  • 字符选中颜色(color),类型:string,默认 '#fadb14'

  • 字符间距(gap),类型:number,单位px,默认 8

  • 只读,无法进行交互(disabled),类型:boolean,默认 false

  • 前数,受控值 1,2,3...(v-model:value),类型:number,默认 0

效果如下图: 在线预览

Vue3评分(Rate)

①创建评分组件Rate.vue:

<script setup lang="ts">
import { ref, watch } from 'vue'
interface Props {
  allowClear?: boolean // 是否允许再次点击后清除
  allowHalf?: boolean // 是否允许半选
  count?: number // star 总数
  character?: string // 自定义字符,string | slot,预置 'star-outlined' 'star-filled' 'heart-outlined' 'heart-filled' 四种svg图标
  size?: number // 字符时是字体高度,图标时是图片大小
  color?: string // 字符选中颜色
  gap?: number // 字符间距
  disabled?: boolean // 只读,无法进行交互
  value?: number // v-model 当前数,受控值 1,2,3...
}
const props = withDefaults(defineProps<Props>(), {
  allowClear: true,
  allowHalf: false,
  count: 5,
  character: 'star-filled',
  size: 20,
  color: '#fadb14',
  gap: 8,
  disabled: false,
  value: 0
})
const activeValue = ref(props.value)
const tempValue = ref() // 清除时保存点击value
watch(
  () => props.value,
  (to) => {
    activeValue.value = to
  }
)
const emits = defineEmits(['update:value', 'change', 'hoverChange'])
function onClick (value: number) {
  tempValue.value = null
  if (value !== props.value) {
    emits('change', value) // 选择时的回调
    emits('update:value', value)
  } else {
    if (props.allowClear) {
      tempValue.value = value
      emits('change', 0)
      emits('update:value', 0)
    } else { // 不允许清除
      emits('change', value) // 选择时的回调
    }
  }
}
function onFirstEnter (value: number) {
  activeValue.value = value
  emits('hoverChange', value) // 鼠标经过时数值变化的回调
}
function onSecondEnter (value: number) {
  activeValue.value = value
  emits('hoverChange', value)
}
function resetTempValue () { // 重置点击value
  tempValue.value = null
}
function onLeave () {
  activeValue.value = props.value
}
function preventDefault (e: Event) {
  e.preventDefault()
}
</script>
<template>
  <div class="m-rate" :class="{'disabled': disabled}" :style="`--color: ${color};`" @mouseleave="onLeave">
    <div
      class="m-star"
      :style="`margin-right: ${n !== count ? gap:0}px;`"
      :class="{'u-star-half': allowHalf && activeValue >= n - 0.5 && activeValue < n, 'u-star-full': activeValue >= n, 'temp-gray': !allowHalf && tempValue === n}"
      @click="!allowHalf ? onClick(n):preventDefault($event)"
      v-for="n in count" :key="n">
      <div
        v-if="allowHalf"
        class="u-star-first"
        :class="{'temp-gray-first': tempValue === n - 0.5}"
        @click.stop="onClick(n - 0.5)"
        @mouseenter="onFirstEnter(n - 0.5)"
        @mouseleave="resetTempValue">
        <svg v-if="character === 'star-filled'" class="u-star" :style="`width: ${size}px;`" focusable="false" data-icon="star" aria-hidden="true" viewBox="64 64 896 896"><path d="M908.1 353.1l-253.9-36.9L540.7 86.1c-3.1-6.3-8.2-11.4-14.5-14.5-15.8-7.8-35-1.3-42.9 14.5L369.8 316.2l-253.9 36.9c-7 1-13.4 4.3-18.3 9.3a32.05 32.05 0 00.6 45.3l183.7 179.1-43.4 252.9a31.95 31.95 0 0046.4 33.7L512 754l227.1 119.4c6.2 3.3 13.4 4.4 20.3 3.2 17.4-3 29.1-19.5 26.1-36.9l-43.4-252.9 183.7-179.1c5-4.9 8.3-11.3 9.3-18.3 2.7-17.5-9.5-33.7-27-36.3z"></path></svg>
        <svg v-else-if="character === 'star-outlined'" class="u-star" :style="`width: ${size}px;`" focusable="false" data-icon="star" aria-hidden="true" viewBox="64 64 896 896"><path d="M908.1 353.1l-253.9-36.9L540.7 86.1c-3.1-6.3-8.2-11.4-14.5-14.5-15.8-7.8-35-1.3-42.9 14.5L369.8 316.2l-253.9 36.9c-7 1-13.4 4.3-18.3 9.3a32.05 32.05 0 00.6 45.3l183.7 179.1-43.4 252.9a31.95 31.95 0 0046.4 33.7L512 754l227.1 119.4c6.2 3.3 13.4 4.4 20.3 3.2 17.4-3 29.1-19.5 26.1-36.9l-43.4-252.9 183.7-179.1c5-4.9 8.3-11.3 9.3-18.3 2.7-17.5-9.5-33.7-27-36.3zM664.8 561.6l36.1 210.3L512 672.7 323.1 772l36.1-210.3-152.8-149L417.6 382 512 190.7 606.4 382l211.2 30.7-152.8 148.9z"></path></svg>
        <svg v-else-if="character === 'heart-filled'" class="u-star" :style="`width: ${size}px;`" focusable="false" data-icon="heart" aria-hidden="true" viewBox="64 64 896 896"><path d="M923 283.6a260.04 260.04 0 00-56.9-82.8 264.4 264.4 0 00-84-55.5A265.34 265.34 0 00679.7 125c-49.3 0-97.4 13.5-139.2 39-10 6.1-19.5 12.8-28.5 20.1-9-7.3-18.5-14-28.5-20.1-41.8-25.5-89.9-39-139.2-39-35.5 0-69.9 6.8-102.4 20.3-31.4 13-59.7 31.7-84 55.5a258.44 258.44 0 00-56.9 82.8c-13.9 32.3-21 66.6-21 101.9 0 33.3 6.8 68 20.3 103.3 11.3 29.5 27.5 60.1 48.2 91 32.8 48.9 77.9 99.9 133.9 151.6 92.8 85.7 184.7 144.9 188.6 147.3l23.7 15.2c10.5 6.7 24 6.7 34.5 0l23.7-15.2c3.9-2.5 95.7-61.6 188.6-147.3 56-51.7 101.1-102.7 133.9-151.6 20.7-30.9 37-61.5 48.2-91 13.5-35.3 20.3-70 20.3-103.3.1-35.3-7-69.6-20.9-101.9z"></path></svg>
        <svg v-else-if="character === 'heart-outlined'" class="u-star" :style="`width: ${size}px;`" focusable="false" data-icon="heart" aria-hidden="true" viewBox="64 64 896 896"><path d="M923 283.6a260.04 260.04 0 00-56.9-82.8 264.4 264.4 0 00-84-55.5A265.34 265.34 0 00679.7 125c-49.3 0-97.4 13.5-139.2 39-10 6.1-19.5 12.8-28.5 20.1-9-7.3-18.5-14-28.5-20.1-41.8-25.5-89.9-39-139.2-39-35.5 0-69.9 6.8-102.4 20.3-31.4 13-59.7 31.7-84 55.5a258.44 258.44 0 00-56.9 82.8c-13.9 32.3-21 66.6-21 101.9 0 33.3 6.8 68 20.3 103.3 11.3 29.5 27.5 60.1 48.2 91 32.8 48.9 77.9 99.9 133.9 151.6 92.8 85.7 184.7 144.9 188.6 147.3l23.7 15.2c10.5 6.7 24 6.7 34.5 0l23.7-15.2c3.9-2.5 95.7-61.6 188.6-147.3 56-51.7 101.1-102.7 133.9-151.6 20.7-30.9 37-61.5 48.2-91 13.5-35.3 20.3-70 20.3-103.3.1-35.3-7-69.6-20.9-101.9zM512 814.8S156 586.7 156 385.5C156 283.6 240.3 201 344.3 201c73.1 0 136.5 40.8 167.7 100.4C543.2 241.8 606.6 201 679.7 201c104 0 188.3 82.6 188.3 184.5 0 201.2-356 429.3-356 429.3z"></path></svg>
        <span v-else class="u-star" :style="`font-size: ${0.66*size}px; height: ${size}px;`">
          <slot name="character">{{ character }}</slot>
        </span>
      </div>
      <div
        class="u-star-second"
        :class="{'temp-gray-second': tempValue === n}"
        @click.stop="onClick(n)"
        @mouseenter="onSecondEnter(n)"
        @mouseleave="resetTempValue">
        <svg v-if="character === 'star-filled'" class="u-star" :style="`width: ${size}px;`" focusable="false" data-icon="star" aria-hidden="true" viewBox="64 64 896 896"><path d="M908.1 353.1l-253.9-36.9L540.7 86.1c-3.1-6.3-8.2-11.4-14.5-14.5-15.8-7.8-35-1.3-42.9 14.5L369.8 316.2l-253.9 36.9c-7 1-13.4 4.3-18.3 9.3a32.05 32.05 0 00.6 45.3l183.7 179.1-43.4 252.9a31.95 31.95 0 0046.4 33.7L512 754l227.1 119.4c6.2 3.3 13.4 4.4 20.3 3.2 17.4-3 29.1-19.5 26.1-36.9l-43.4-252.9 183.7-179.1c5-4.9 8.3-11.3 9.3-18.3 2.7-17.5-9.5-33.7-27-36.3z"></path></svg>
        <svg v-else-if="character === 'star-outlined'" class="u-star" :style="`width: ${size}px;`" focusable="false" data-icon="star" aria-hidden="true" viewBox="64 64 896 896"><path d="M908.1 353.1l-253.9-36.9L540.7 86.1c-3.1-6.3-8.2-11.4-14.5-14.5-15.8-7.8-35-1.3-42.9 14.5L369.8 316.2l-253.9 36.9c-7 1-13.4 4.3-18.3 9.3a32.05 32.05 0 00.6 45.3l183.7 179.1-43.4 252.9a31.95 31.95 0 0046.4 33.7L512 754l227.1 119.4c6.2 3.3 13.4 4.4 20.3 3.2 17.4-3 29.1-19.5 26.1-36.9l-43.4-252.9 183.7-179.1c5-4.9 8.3-11.3 9.3-18.3 2.7-17.5-9.5-33.7-27-36.3zM664.8 561.6l36.1 210.3L512 672.7 323.1 772l36.1-210.3-152.8-149L417.6 382 512 190.7 606.4 382l211.2 30.7-152.8 148.9z"></path></svg>
        <svg v-else-if="character === 'heart-filled'" class="u-star" :style="`width: ${size}px;`" focusable="false" data-icon="heart" aria-hidden="true" viewBox="64 64 896 896"><path d="M923 283.6a260.04 260.04 0 00-56.9-82.8 264.4 264.4 0 00-84-55.5A265.34 265.34 0 00679.7 125c-49.3 0-97.4 13.5-139.2 39-10 6.1-19.5 12.8-28.5 20.1-9-7.3-18.5-14-28.5-20.1-41.8-25.5-89.9-39-139.2-39-35.5 0-69.9 6.8-102.4 20.3-31.4 13-59.7 31.7-84 55.5a258.44 258.44 0 00-56.9 82.8c-13.9 32.3-21 66.6-21 101.9 0 33.3 6.8 68 20.3 103.3 11.3 29.5 27.5 60.1 48.2 91 32.8 48.9 77.9 99.9 133.9 151.6 92.8 85.7 184.7 144.9 188.6 147.3l23.7 15.2c10.5 6.7 24 6.7 34.5 0l23.7-15.2c3.9-2.5 95.7-61.6 188.6-147.3 56-51.7 101.1-102.7 133.9-151.6 20.7-30.9 37-61.5 48.2-91 13.5-35.3 20.3-70 20.3-103.3.1-35.3-7-69.6-20.9-101.9z"></path></svg>
        <svg v-else-if="character === 'heart-outlined'" class="u-star" :style="`width: ${size}px;`" focusable="false" data-icon="heart" aria-hidden="true" viewBox="64 64 896 896"><path d="M923 283.6a260.04 260.04 0 00-56.9-82.8 264.4 264.4 0 00-84-55.5A265.34 265.34 0 00679.7 125c-49.3 0-97.4 13.5-139.2 39-10 6.1-19.5 12.8-28.5 20.1-9-7.3-18.5-14-28.5-20.1-41.8-25.5-89.9-39-139.2-39-35.5 0-69.9 6.8-102.4 20.3-31.4 13-59.7 31.7-84 55.5a258.44 258.44 0 00-56.9 82.8c-13.9 32.3-21 66.6-21 101.9 0 33.3 6.8 68 20.3 103.3 11.3 29.5 27.5 60.1 48.2 91 32.8 48.9 77.9 99.9 133.9 151.6 92.8 85.7 184.7 144.9 188.6 147.3l23.7 15.2c10.5 6.7 24 6.7 34.5 0l23.7-15.2c3.9-2.5 95.7-61.6 188.6-147.3 56-51.7 101.1-102.7 133.9-151.6 20.7-30.9 37-61.5 48.2-91 13.5-35.3 20.3-70 20.3-103.3.1-35.3-7-69.6-20.9-101.9zM512 814.8S156 586.7 156 385.5C156 283.6 240.3 201 344.3 201c73.1 0 136.5 40.8 167.7 100.4C543.2 241.8 606.6 201 679.7 201c104 0 188.3 82.6 188.3 184.5 0 201.2-356 429.3-356 429.3z"></path></svg>
        <span v-else class="u-star" :style="`font-size: ${0.66*size}px; height: ${size}px;`">
          <slot name="character">{{ character }}</slot>
        </span>
      </div>
    </div>
  </div>
</template>
<style lang="less" scoped>
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
.m-rate {
  display: inline-block;
  .m-star {
    position: relative;
    display: inline-block;
    cursor: pointer;
    transition: transform 0.3s ease-in-out;
    &:hover {
      transform: scale(1.1);
    }
    .u-star {
      display: inline-flex;
      align-items: center;
      text-align: center;
      vertical-align: middle;
      fill: rgba(0, 0, 0, 0.06);
      color: rgba(0, 0, 0, 0.06);
      transition: all 0.3s;
    }
    .u-star-first {
      position: absolute;
      top: 0;
      width: 50%;
      height: 100%;
      opacity: 0;
      overflow: hidden;
      transition: all 0.3s;
      &:hover {
        opacity: 1;
        .u-star {
          fill: var(--color);
          color: var(--color);
        }
      }
    }
    .u-star-second {
      display: inline-block;
      &:hover {
        .u-star {
          fill: var(--color);
          color: var(--color);
        }
      }
    }
    .temp-gray-first {
      &:hover {
        opacity: 0;
        .u-star {
          fill: rgba(0, 0, 0, 0.06);
          color: rgba(0, 0, 0, 0.06);
        }
      }
    }
    .temp-gray-second {
      &:hover {
        .u-star {
          fill: rgba(0, 0, 0, 0.06);
          color: rgba(0, 0, 0, 0.06);
        }
      }
    }
  }
  .u-star-half {
    .u-star-first {
      opacity: 1;
      .u-star {
        fill: var(--color);
        color: var(--color);
      }
    }
  }
  .u-star-full {
    .u-star-second {
      .u-star {
        fill: var(--color);
        color: var(--color);
      }
    }
  }
}
.disabled {
  pointer-events: none;
}
</style>

 ②在要使用的页面引入:文章来源地址https://www.toymoban.com/news/detail-420833.html

<script setup lang="ts">
import { ref, watchEffect } from 'vue'

const value = ref(2.99)
watchEffect(() => {
  console.log('value:', value.value)
})
function onChange (value: number) {
  console.log('change value:', value)
}
function onHoverChange (value: number) {
  console.log('hover value:', value)
}
</script>
<template>
  <div>
    <h2 class="mb10">Rate 评分基本使用</h2>
    <Rate v-model:value="value"/>
    <h2 class="mt30 mb10">空心星型图标,高度30px (character: star-outlined & size: 30)</h2>
    <Rate character="star-outlined" :size="30" v-model:value="value"/>
    <h2 class="mt30 mb10">实心心型图标,高度30px (character: heart-filled & size: 30)</h2>
    <Rate character="heart-filled" :size="30" v-model:value="value"/>
    <h2 class="mt30 mb10">空心心型图标,高度30px (character: heart-outlined & size: 30)</h2>
    <Rate character="heart-outlined" :size="30" v-model:value="value"/>
    <h2 class="mt30 mb10">支持选中半星,选中颜色:#1677FF,高度30px (allowHalf: true & color: #1677FF & size: 30)</h2>
    <Rate allowHalf :size="30" color="#1677FF" v-model:value="value"/>
    <h2 class="mt30 mb10">使用中文文字: 好,高度36px (character: 好 & size: 36)</h2>
    <Rate
      allowHalf
      character="好"
      :size="36"
      v-model:value="value"
      @change="onChange"
      @hover-change="onHoverChange"/>
    <h2 class="mt30 mb10">使用英文字母: A (character: A & size: 48)</h2>
    <Rate
      allowHalf
      character="A"
      :size="48"
      v-model:value="value"
      @change="onChange"
      @hover-change="onHoverChange"/>
    <h2 class="mt30 mb10">Ant Design Vue 评分</h2>
    <a-rate v-model:value="value" allow-half />
  </div>
</template>

到了这里,关于Vue3评分(Rate)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • CKEditor5+vue3使用以及如何添加新工具栏,自定义设置字体fontFamily

    官网地址:https://ckeditor.com/ckeditor-5/online-builder/ 官网提供了以下几种模式,一般使用经典模式居多,具体差别可访问官网自己试一下。 基本的使用方法(经典模式),先别急着操作,看完再决定使用哪种方法。 代码 效果如图 以上基本的工具栏配置比较少,如果基本的满足你的

    2024年02月10日
    浏览(49)
  • Vue2和Vue3是Vue.js框架的两个主要版本,它们之间有以下区别

    性能优化:Vue3在内部进行了重写,采用了更高效的虚拟DOM算法,使得渲染速度更快,性能更好。 更小的体积:Vue3的体积比Vue2更小,这意味着更快的下载和加载速度。 Composition API:Vue3引入了Composition API,它是一种新的组合式API,可以更好地组织和重用组件逻辑,使得代码更

    2024年02月15日
    浏览(38)
  • Vue3浅谈:(二)Vue3计算属性

    目录 一、Vue3计算属性 1.Vue3计算属性基础使用 2.计算属性缓存和常规方法 3.可写计算属性 当我们需要针对一些数据进行一些逻辑运算时可以使用模板中的表达式如下: 但是如果在模板中写太多逻辑,会让模板变得臃肿,难以维护。因此我们可以使用计算属性 computed()  方法来

    2023年04月25日
    浏览(26)
  • 您想允许来自未知发布者的以下程序对此计算机进行更改码?

    问题 当开发的程序运行在客户的电脑上会弹出该提示框,对用户体验不好。 现象的原因与解决方案, 方法1: 一个是客户的电脑的【用户账户控制设置】权限设置【始终通知】太高(这个是win10) 可以设置为【从不通知】,就不会出现弹框了。但是这样对开发人员发布软件

    2024年02月04日
    浏览(64)
  • Vue3/ Vue3 计算属性computed函数 语法 与 介绍 、Vue3 Vue2computed计算属性 能不能传参 怎么传参

    语法: // 第一种语法get方法 (没有set) const 函数名 = computed(() = {   return  }) // 第二种语法 get set 方法 带有set参数 可以设置 const 函数名 = computed(() = { get() { return 结果 }, set( val ){  } }) 触发场景:  如果要访问计算属性 会自动执行 get 如果要修改计算属性 会自动执行 set 简介

    2024年02月02日
    浏览(40)
  • Vue3 第三节 计算属性,监视属性,生命周期

    1.computed计算属性 2.watch监视函数 3.watchEffect函数 4.Vue的生命周期函数 计算属性简写和完整写法 2.1 监视情况分类  情况① 监视ref定义的响应式数据: 第一个参数是监视的数据,第二个参数是一个回调函数 immediate:一上来就执行,放到第三个参数中 情况② 监视多个ref定义的响应

    2024年02月14日
    浏览(37)
  • 【Vue3基础】计算属性

    一、需求 二、代码 1、创建项目 2、App.vue文件中: 3、studyDemo.vue文件 用计算属性来处理逻辑,注意引用时不用加括号,写名称即可; 若放函数或者方法,引用时注意加括号。 重点区别: 计算属性: 计算属性值会基于其响应式依赖被缓存。一个计算属性仅会在其响应式依赖更新

    2024年02月16日
    浏览(32)
  • vue3-基本属性更新

    Vue3的基本属性: 组合式API(Composition API): 组合式API是Vue3最核心的特性之一,它允许开发者将逻辑相关的选项组合在一起,提高代码的可维护性和可读性。组合式API主要体现在setup函数中,setup函数是一个新的组件选项,用于在组件创建之前执行一些逻辑。 响应式系统重构

    2024年01月23日
    浏览(27)
  • 【Vue3】computed 计算属性

    computed 是计算属性,它会根据响应式数据的变化⾃动计算出新的值,并缓存结果,只有在计算属性所依赖的响应式数据发⽣改变时才会重新计算。 computed 适⽤于需要根据响应式数据计算得出结果的场景,例如根据商品的数量和单价计算商品的总价,或者根据选中的过滤条件过

    2024年02月15日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包