Rate评分组件,可自定义图标和颜色

Rate 评分组件

Rate评分组件,可自定义图标和颜色_第1张图片

使用方法

  • Rate组件需要放在components文件夹内
  • 目前Rate组件只支持iconfont的图标,需要自己到iconfont上查找图标,需要一个选中时的图标和一个未选中时的图标,找到之后,新建一个项目,放入到自己的项目当中,下载解压,将压缩包内以font开头的文件夹内的所有文件放到 assets\icon 文件内,再在 main.js 当中使用 import "./assets/icon/iconfont.css"; 导入图标
  • 这里提供了一个图标,懒得去找的,下载这个就可以,这也是demo当中,使用的图标 https://www.iconfont.cn/api/project/download.zip?spm=a313x.7781069.1998910419.d7543c303&pid=2264506&ctoken=6cmJ--jQ0PZVPNwotsXKE5X8

父组件

使用 Rate 组件的组件,即 Rate 组件的父组件

<template>
  <div class="container">
    <rate 
      :rateScore="rateValue" 
      checkedIcon="iconyishoucang" 
      unCheckedIcon="iconshoucang" 
      v-on:starChange="onStarChange"
      v-bind:rateTexts="rateTexts">
    rate>
  div>
template>

<script>
import Rate from "@/components/Rate" // 引入组件
export default {
  name: 'TestCom',
  components: {
    "rate": Rate // 注册组件
  },
  data(){
    return {
      rateValue: 3, // 默认选中的评分,范围 1 - 5,为0时,默认不选中任何星星
      rateTexts: ['不好', '有待改进', '一般', '基本满意', '非常满意'], // 评分组件显示的提示语,可选
    }
  },
  methods: {
    // 监听评分星星改变事件
    // data的范围为 1 - 5,代表5个评分等级
    onStarChange(data){
      // 拿到子组件传递过来的数据之后,在这里发送请求,传递数据给后端
      this.rateValue = data;
    }
  }
}
script>

<style lang="scss" scoped>
  // 这里是图标的颜色和字体大小,类名就是自己选择的图标的类名
  // 选中时的图标的样式
  /deep/ .iconyishoucang{
    color: #FFB800;
    font-size: 22px;
  }
  // 未选中时的图标的样式
  /deep/ .iconshoucang{
    color: #bbb;
    font-size: 22px;
  }
style>

Rate组件

Rate组件源码

<template>
  <div class="rateContainer">
    <div class="stars" @mouseout="outContainer">
      <span class="rateItem" v-for="(rate, index) in rateArr" :key="index" @mousemove="moveIn($event, rate, index)" @click="handleClick(rate, index)">
        <i class="iconfont textColor" v-bind:class="[rate.classStr]">i>
      span>
    div>
    <span class="rateText">{{rateText}}span>
  div>
template>

<script>
export default {
  name: 'Rate',
  props: {
    rateScore: { type: Number, required: true, default: 0 }, // 评分分数,默认为0,范围:1 - 5
    checkedIcon: { type: String, required: true, }, // 选中时,显示的图标
    unCheckedIcon: { type: String, required: true, }, // 未选中时,显示的图标
    rateTexts: { type: Array, default: () => { return [] } }, // 要显示的文字,数组类型
  },

  data(){
    return {
      rateArr: [
        { rateScore: 1, isChecked: false, classStr: "", rateText: '' },
        { rateScore: 2, isChecked: false, classStr: "", rateText: '' },
        { rateScore: 3, isChecked: false, classStr: "", rateText: '' },
        { rateScore: 4, isChecked: false, classStr: "", rateText: '' },
        { rateScore: 5, isChecked: false, classStr: "", rateText: '' },
      ],
      rateText: "", // 右边显示的文字
      childRateScore: this.rateScore
    }
  },
  created(){
    // 遍历评分数组,分配评分文字和默认选中
    this.rateArr.forEach((item, index) => {
      item.rateText = this.rateTexts[index] ? this.rateTexts[index] : '';
      if(item.rateScore == this.rateScore){
        for(let i=0; i<=index; i++){
          this.rateArr[i].isChecked = true;
          this.rateArr[i].classStr = this.checkedIcon;
        }
        this.rateText = item.rateText;
      }else{
        item.isChecked = false;
        item.classStr = this.unCheckedIcon;
      }
    });
  },
  methods: {
    moveIn(e, rate, index){
      // 所有的星星
      let rateItemDomList = document.querySelectorAll(".iconfont");
      // 鼠标移入当前星星,应该要检查当前星星的左边所有星星,如果没有被选中,就需要添加 checkedIcon
      for(let i=0; i<=index; i++){
        if(!this.rateArr[i].isChecked){
          rateItemDomList[i].classList.add(this.checkedIcon);
          rateItemDomList[i].classList.remove(this.unCheckedIcon);
        }
      }
      // 鼠标移入当前星星,右边所有的星星,如果没有被选中,就需要移除 unCheckedIcon
      for(let i=index+1; i<this.rateArr.length; i++){
        rateItemDomList[i].classList.remove(this.checkedIcon);
        rateItemDomList[i].classList.add(this.unCheckedIcon);
      }
      this.rateText = rate.rateText;
    },
    // 点击星星
    handleClick(rate, index){
      // 点击了当前星星后,当前星星以及当前星星的左边,都要被设置选中
      for(let i=0; i<=index; i++){
        this.rateArr[i].isChecked = true;
      }
      // 当前星星的右边,都要设置取消选中
      let rateItemDomList = document.querySelectorAll(".iconfont");
      for(let i=index+1; i<this.rateArr.length; i++){
        this.rateArr[i].isChecked = false;
        rateItemDomList[i].classList.add(this.unCheckedIcon);
        rateItemDomList[i].classList.remove(this.checkedIcon);
      }
      this.childRateScore = rate.rateScore;
      this.$emit("starChange", this.childRateScore);
    },
    // 鼠标移出了rateContainer,要移除选中了的星星以外所有星星的选中效果
    // 并且给已经选中了的星星设置选中
    outContainer(){
      let rateItemDomList = document.querySelectorAll(".iconfont");
      for(let i=0; i<rateItemDomList.length; i++){
        if(this.rateArr[i].isChecked){
          rateItemDomList[i].classList.add(this.checkedIcon);
          rateItemDomList[i].classList.remove(this.unCheckedIcon);
        }else{
          rateItemDomList[i].classList.remove(this.checkedIcon);
          rateItemDomList[i].classList.add(this.unCheckedIcon);
        }
      }
      this.rateText = this.rateTexts[this.childRateScore-1];
    }
  }
}
script>

<style lang="scss" scoped>
  .rateContainer{
    display: flex;
    align-items: center;
  }
  .rateItem{
    padding-right: 10px;
  }
  .iconfont{
    cursor: pointer;
  }
  .rateText{
    color: #333;
    font-size: 14px;
  }
style>

你可能感兴趣的:(Vue,elementui,vue)