---
# System prepended metadata

title: 1-3.Vue外送平台App-異步顯示數據(評分的星星)
tags: [components, Vue]

---

# 1-3.Vue外送平台App-異步顯示數據(評分的星星)
### 1. 要先從Miste.vue抽取組件，創建新的組件(Start.vue)
![](https://i.imgur.com/A8krKbQ.png)
```htmlmixed=
<template>
<div class="star star-24">
    <span class="star-item on"></span>
    <span class="star-item on"></span>
    <span class="star-item on"></span>
    <span class="star-item half"></span>
    <span class="star-item off"></span>
</div>
</template>



<style lang="scss">
@import '../../assets/style/common/_common.scss';
@import '../../assets/style/common/_mixins.scss';

//2x图 3x图
.star {
    float: left;
    font-size: 0;

    .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 {
                    @include bg-image ('./images/star48_on');
                }

                &.half {
                    @include bg-image ('./images/star48_half');
                }

                &.off {
                    @include bg-image ('./images/star48_off');

                }

            }
        }

    }

    &.star-36 {
        .star-item {
            width: 15px;
            height: 15px;
            margin-right: 6px;
            background-size: 15px 15px;

            &:last-child {
                margin-right: 0;

            }

            &.on {
                @include bg-image ('./images/star36_on');

            }

            &.half {
                @include bg-image ('./images/star36_half');

            }

            &.off {
                @include bg-image ('./images/star36_off');

            }

        }
    }

    &.star-24 {
        .star-item {
            width: 10px;
            height: 10px;
            margin-right: 3px;
            background-size: 10px 10px;

            &:last-child {
                margin-right: 0;

            }

            &.on {
                @include bg-image ('./images/star24_on');
            }

            &.half {
                @include bg-image ('./images/star24_half');
            }

            &.off {
                @include bg-image ('./images/star24_off');
            }

        }

    }
}
</style>
```
### 2. 總共五個星:分別on(全星)off(空星)half(半星)
![](https://i.imgur.com/2FgOPRq.png)
![](https://i.imgur.com/yKQ5F7I.png)
### 3. 要傳什麼屬性(props)?
不同評分的星星有哪些區別?
* 分數-half , off , on
* 大小-24, 36, 48
```htmlmixed=
<script>
export default {
    //分析需要傳什麼屬性
    props: {
        score: Number,// 分數
        size: Number // 大小
    }
}
</script>
```
### 5. Star.vue組件放回ShopList.vue
```htmlmixed=
<section class="shop_rating_order_left">
<!--接收star屬性-->
    <Star :score="shop.rating" :size="24" />
        <div class="rating_section">
            {{shop.rating}}
        </div>
        <div class="order_section">
            月售{{shop.recent_order_num}}單
        </div>
</section>
import Star from '../Star/Star'

export default {
    components: {
        Star
    }
}
```
### 6.運用計算屬性來計算(computed)評分

```htmlembedded=
<template>
<!--1.動態綁定尺寸變化 (24, 36, 48 )-->
<div class="star" :class="`star-${size}`">
    <!--2.主要顯示五個星星，類名不相同 on ,half,off
    3.類名是有順序的on->half->off
    4.假設[]數組有五個類名，我們通過便利(v-for)的方式來獲取
    5.StarClasses 可以根據score 計算產生 (computed)計算屬性-->
    <span class="star-item" v-for="(sc, index) in StarClasses" :key="index" :class="sc">
    </span>
</div>
</template>

<script>
//這些值是固定的 ，可以添加類名常量(沒有也可以)
const CLASS_ON = 'on'
const CLASS_HALF = 'half'
const CLASS_OFF = 'off'
export default {
    /*
    3.2 -> 3個on 0個half 2個off
    3.5 -> 3個on 1個half(>=0.5) 1個off
    starClasses: []
    */
    //分析需要傳什麼屬性
    props: {
        score: Number,
        size: Number
    },
    computed: {
        StarClasses() {
            const {
                score
            } = this
            const scs = []
            //1.向scs添加 n個 'on'(CLASS_ON)
            //on ->要看整數部分多少,用Math.floor得到分數的整數
            //(Math.floor:用來對數字做無條件捨去，會返回小於等於傳入參數的最大整數值。)
            const scoreInteger = Math.floor(score)
            //用for循環讓scss執行n次
            for (let i = 0; i < scoreInteger; i++) {
                scs.push(CLASS_ON)
            }
            //2.向scs添加 0/1個 'half' (CLASS_HALF)
            //那什麼時候需要往這裡添加half,要達到某個條件
            //直接score-scoreInteger 可能會形成4.99所以把前後都*10
            if (score * 10 - scoreInteger * 10 >= 5) {
                scs.push(CLASS_HALF)
            }
            //3.向scs添加 n個 'off'  (CLASS_OFF)
            //用for循環執行n次或while 到什麼時候停止 (總個數是5個星星)
            while (scs.length < 5) {
                scs.push(CLASS_OFF)
            }
            return scs
        }
    }
}
</script>

```
![](https://i.imgur.com/3RyHFCt.png)
###### tags: `Vue` `components`