vue实现店铺的星级评价

需求分析####

1.星级评价在店铺中多次使用,因此作为组件进行编写
2.星级评价的标准是该店铺的得分,样式以星星的尺寸来划分总共有三种,分别是48,36和24
3.调用插件时传入两个参数,第一个星星的size,数据类型为number,第二个店铺的评分score,数据类型为number

<template>
    <div class="star" :class="starType">
        <span v-for="itemClass in itemClasses" :class="itemClass" class="star-item" track-by="$index"></span>
    </div>
</template>
<script type="text/ecmascript-6">
const LENGTH = 5;
const CLS_ON = 'on';
const CLS_HALF = 'half';
const CLS_OFF = 'off';

export default {
props: {
size: {
type: Number
},
score: {
type: Number
}
},
computed: {
starType() {
return 'star-' + this.size;
},
itemClasses() {
let result = [];
let score = Math.floor(this.score * 2) / 2;
let hasDecimal = score % 1 !== 0;
let integer = Math.floor(score);
for (let i = 0; i < integer; i++) {
result.push(CLS_ON);
}
if (hasDecimal) {
result.push(CLS_HALF);
}
while (result.length < LENGTH) {
result.push(CLS_OFF);
}
return result;
}
}
};
</script>
<style lang="stylus" rel="stylesheet/stylus">
    @import "../../common/stylus/mixin";
    .star
        .star-item
            display: inline-block
            background-repeat: no-repeat
        &.star-48
            .star-item
                width: 20px
                height: 20px
                margin-right: 22px
                background-size: 20px 20px
                &:last-child
                    margin-right: 0
                &.on
                    bg-image('star48_on')
                &.half
                    bg-image('star48_half')
                &.off
                    bg-image('star48_off')
        &.star-36
            .star-item
                width: 15px
                height: 15px
                margin-right: 16px
                background-size: 15px 15px
                &:last-child
                    margin-right: 0
                &.on
                    bg-image('star36_on')
                &.half
                    bg-image('star36_half')
                &.off
                    bg-image('star36_off')
        &.star-24
            .star-item
                width: 10px
                height: 10px
                margin-right: 3px
                background-size: 10px 10px
                &:last-child
                    margin-right: 0
                &.on
                    bg-image('star24_on')
                &.half
                    bg-image('star24_half')
                &.off
                    bg-image('star24_off')

</style>

以上为star组件
其中类名为star的div是存放星星的容器,使用vue的v-for方法对span进行循环,每一个span代表一个星星,星星有三种状态,空白,半星和全星


第1行 <template>中包含组件的html框架
第2行 :class="starType"是v-bind:class的简写,是vue中给元素绑定一个类的方法,其中starType是一个方法该方法在第21行中有声明,返回的是一个字符串,该字符串由'star-' + this.size拼接而成,this.size是调用组件时传入的num,上面有提到num有三种分别是48,36和24,因此完成拼接后,会出现三个类名,分别是star-48,star-36,star-24,这三个类名决定了星星的大小,类名的定义在代码的50行,后面分析
第3行 <span v-for="itemClass in itemClasses" :class="itemClass" class="star-item" track-by="$index"></span>其中v-for是vue的循环写法,由此可见itemClasses()方法返回是一个数组,v-for是对数组的遍历,对于itemClass的声明在代码的第25行,:class="itemClass"从数组中拿到的itemClass以类名的形式绑定到span上用于决定每个span呈现的状态,状态可分为空白,半星和全星三种。track-by="$index"是为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素。
第13行 使用props进行数据传递,之前提到调用该组件时需要传入两个参数,size和score,外部组件调用该组件时,参数的作用域不同star组件无法直接使用size和score参数,因此需要使用props来进行数据传递,使得外部传入的数据可以被正常使用。
第14行 声明size参数
第15行 定义size的参数为number类型,十七行和十八行功能同上
第21行 computed是vue中实时计算使用方法,当vue检测到数据发生变动时就会执行对相应数据有引用的函数
第22行 starType()获取到传入的size返回字符串star-48,star-36或者是star-24作为类名,来决定星星的大小
第25行 itemClasses()方法,主要作用是用于输出星星的状态,根据传入的score即店铺的分数来决定星星的展示,星星总共三种状态,空白,半星和全星,分数则是采用特殊的计算方法映射到星星的状态上,比如店铺分数是4.8分,显示4星半,分数为4.2分,显示为4星,分数为5分,显示为5星。
第26行 let result = [],定义了一个数组,该数组用于存放星星的类名,由于满分为5分,因此该数组的长度应该为5
第27行 let score = Math.floor(this.score×2) / 2,将分数乘以二并向下取整之后除以二,得到x.0或者是x.5的数字
第28行 let hasDecimal = score % 1 !== 0,hasDecimal的值是true或者false对score取余,有余数时hasDecimal为true,无余数时返回false
第29行 let integer = Math.floor(score),对score再次向下取整,此时的score是第二十七行处理后的score
第30行 for循环,根据integer的数值确定向result数组中push类名CLS_ON的个数,由此可以得到全星的个数
ps:LENGTH,CLS_ON,CLS_HALF,CLS_OFF为7~10行定义的常量,分别表示数组的总长度,和星星三种状态的类名
第33行 if语句hasDecimal为true则有半星,false则无半星
第36行 while语句全星循环的半星判断执行完之后对result数组的长度进行判断,小于总长度则向数组中push空白星
第39行 返回result数组。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容