assets\icon
文件内,再在 main.js
当中使用 import "./assets/icon/iconfont.css";
导入图标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组件源码
<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>