星星评分功能

最近因为公司业务,需要做一个点击星星实现评分的功能,整体来说,样式上不是很麻烦,主要记录一下自己碰到的几个问题:

首先是星星评分组件

<template>
<div class="setgrade">  
    <div class="star">
        <ul id="star">
            <li>
                <a href="javascript:void(0)" onclick="halfStar(1)"></a>
                <a href="javascript:void(0)" onclick="halfStar(2)"></a>
            </li>
            <li>
                <a href="javascript:void(0)" onclick="halfStar(3)"></a>
                <a href="javascript:void(0)" onclick="halfStar(4)"></a>
            </li>
            <li>
                <a href="javascript:void(0)" onclick="halfStar(5)"></a>
                <a href="javascript:void(0)" onclick="halfStar(6)"></a>
            </li>
            <li>
                <a href="javascript:void(0)" onclick="halfStar(7)"></a>
                <a href="javascript:void(0)" onclick="halfStar(8)"></a>
            </li>
            <li>
                <a href="javascript:void(0)" onclick="halfStar(9)"></a>
                <a href="javascript:void(0)" onclick="halfStar(10)"></a>
            </li>
        </ul>
    </div>
</div>
</template>
<script>
export default{
props:['score'],
data(){
    return {

    }
},
watch:{
    score:{
        handler:function(val){
            this.halfStar(Number(val) / 10)
        },
        immediate:false,
        deep:true
    }
},
mounted(){
    this.halfStar(Number(this.score) / 10)
},
methods:{
    halfStar(x){
        var star = document.getElementById('star');
    var items = star.getElementsByTagName("li");
    x = parseInt(x) - 1;
    var tem = -1;
    for(var i = 0; i < items.length; i++) {
        if(x > i*2) {
            items[i].style.backgroundImage = "url('../img/full.png') no-repeat";
            items[i].style.backgroundRepeat = "no-repeat";
            items[i].style.backgroundSize = "100% 100%";
        } else {
            if(tem == -1) {
                tem = i;
            } 
            items[i].style.backgroundImage = "url('../img/empty.png') no-repeat";
            items[i].style.backgroundRepeat = "no-repeat";
            items[i].style.backgroundSize = "100% 100%";
        }
    }
    if(x == parseInt(tem)*2) {
        items[tem].style.backgroundImage = "url('../img/half.png') no-repeat";
        items[tem].style.backgroundRepeat = "no-repeat";
        items[tem].style.backgroundSize = "100% 100%";
    }
    this.$emit('changeScore',(parseInt(x) + 1) * 10)
    }
}
}
</script>
<style scoped>
.star {
    width: 100%;
}
ul {
    width: 100%;
    padding: 0;
    margin: 0 ;
}
ul li {
    width: 20px;
    height: 20px;
    display: inline-block;
    background: url("../img/empty.png") no-repeat;
    background-repeat:no-repeat;
    background-size:100% 100%;
}
ul li a {
    height: 20px;
    width: 10px;
    display: inline-block;
    float: left;
}
</style>

然后在页面中调用该组件

 此时,有一个问题就是默认的时候是有图片的,但是点击之后星星图片就没有了。后来定位发现是默认用的css加载图片,但是点击之后用的js里面的样式,导致图片加载失败,在js中加载图片需要使用require:

 在解决完这个问题后,点击星星后实现了对应点亮的功能,但是我在表格里面调用时,不管点击的是第几行,分数对应的修改了,但是界面效果一直是作用在第一行。刚开始以为是表格循环导致了重复,于是给组件外层套用了div,然后给div添加了一个唯一的key,还是没效果,又尝试将key加到组件里面去,也还是不行,于是反复读代码,最后发现在js里是通过id获取元素的,但是使用是没问题的,但是在表格里面,导致重复渲染,出现了多个重复id,而在js中id重复的时候,都只会识别到第一个,所以才会出现分数改了,但效果作用在第一个的效果:

 

 

 

posted on 2021-12-16 09:21  紅葉  阅读(117)  评论(0编辑  收藏  举报