# 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`