这个组件就是根据点击第几颗星星算出分数,并且对星星的样式做出对应的改变,支持打半颗星。
实现效果如下
开始的时候,我想如何能够实现星星两边颜色不同的效果,我使用的是iconfont,直接设置color颜色,但是color没有一半的设定,所以我搜索了一下发现通过背景颜色设定比较合适
对于样式最主要的是下面三句
第一句:background: linear-gradient(to right, #FFA940 50%, #E4E4E4 0) (实现背景色一半一半的效果)
第二句:-webkit-background-clip: text;(规定背景的绘制区域为文字部分。)
之前接触过的background-clip有下面几种取值:
background-clip: border-box(默认)|padding-box|content-box;
意思分别是,背景被裁剪到边框盒 | 背景被裁剪到内边距框|背景被裁剪到内容框。
第三句:-webkit-text-fill-color: transparent;(文字填充颜色)
*这里注意一定要定义为transparent,否则会覆盖底部的背景色。
这里使用了-webkit-前缀,Chrome和Safari能够正常使用,如果有兼容性需求,需要谨慎使用
接下来就比较简单了通过offsetX定位来判断点击位置在星星中线的左侧还是右侧
我这里使用的icon是16px宽度,所以下面用8来算,具体可以根据自己使用的图标来决定
直接上代码
2023.6.26更新
这个方法果然有兼容问题,因为offestx在谷歌中是拿的整串星星的长度,在火狐中拿的是单个星星的,所以方法改动
<template>
<div class="starScore">
<span v-for="(item, index) of star" :key="index" @click="changeScore(index)">
<i class="iconfont icon-star" :class="{'active':starIndex > index, 'half':starIndex === index + 0.5}"></i>
</span>
<span class="starScore-key">{{score}}分</span>
</div>
</template>
<script>
export default {
name: 'starScore',
data() {
return {
score: 0,
starIndex: -1,
star: [0, 1, 2, 3, 4] // 分数
};
},
methods: {
changeScore(index) {
let offsetX = window.event.offsetX;
offsetX = offsetX > 22 ? offsetX % 22 : offsetX;
this.starIndex = index + (offsetX < 11 ? 0.5 : 1);
this.score = (this.starIndex) * 2;
}
}
};
</script>
<style lang="scss" scoped>
.starScore {
.icon-star {
cursor: pointer;
color: #E4E4E4;
padding: 0 3px;
&.half {
background: linear-gradient(to right, #FFA940 50%, #E4E4E4 0);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
&.active {
color: #FFA940;
}
}
.starScore-key {
color: #FFA940;
padding-left: 5px;
}
}
</style>