# 飲料點餐版面(Vue簡單版) ###### codepen在這邊:https://codepen.io/liu_0821/pen/YzjGoOV?editors=0010 ![](https://i.imgur.com/Be6hXMq.png) ## 前情提要 ##### 江~這章是簡單版,有打算再做個挑戰版出來,但先記錄一下ㄏㄏ ##### 另外裡面有做一些補充說明,不多說了,直接看程式碼 ## HTML > @click.prevent 阻止html原生事件影響 :class="{'active':itemSelected.engName === item.engName}" 判斷點擊後的樣式 item.toppings.toString() 陣列轉字串 ``` <div id="app"> <div class="container gx-2"> <div class="row gx-3 bg-light py-3"> <div class="col-md-4"> <div class="list-group"> <a href="#" class="list-group-item list-group-item-action" v-for="(item,key) in products" @click.prevent="selectedProduct(item)" :class="{'active':itemSelected.name === item.name}" :key="item.name" > <h6 class="card-title mb-1">{{item.name}}</h6> <div class="d-flex align-items-center justify-content-between" > <p class="mb-0"><small>{{item.engName}}</small></p> <p class="mb-0"><small>NT$ {{item.price}}</small></p> </div> </a> </div> </div> <div class="col-md-8"> <div class="card mb-2"> <div v-if="!itemSelected.name" class="position-absolute text-white d-flex align-items-center justify-content-center active" style=" top: 0; bottom: 0; left: 0; right: 0; background-color: rgba(0, 0, 0, 0.65); z-index: 100; " > 請先選擇飲品 </div> <div class="card-body px-4"> <div class="mb-3"> <label for="productNum" class="form-label">數量</label> <input type="number" class="form-control" id="productNum" placeholder="數量" v-model="itemSelected.count" min="1" /> </div> <div class="mb-3"> <label for="productNum" class="form-label d-block" >冰塊*</label > <div class="form-check form-check-inline" v-for="(item,key) in iceType" :key="'ice'+ key" > <input class="form-check-input" name="iceType" type="radio" :id="'ice'+ key" :value="item" v-model="itemSelected.ice" /> <label class="form-check-label" :for="'ice'+ key" >{{item}}</label > </div> </div> <div class="mb-3"> <label for="productNum" class="form-label d-block" >甜度</label > <div class="form-check form-check-inline" v-for="(item,key) in sugarType" :key="'sugar'+key" > <input class="form-check-input" name="sugarType" type="radio" :id="'sugar'+key" :value="item" v-model="itemSelected.sugar" /> <label class="form-check-label" :for="'sugar'+key" >{{item}}</label > </div> </div> <div class="mb-3"> <label for="productNum" class="form-label d-block" >加料</label > <div class="form-check form-check-inline" v-for="(item,key) in toppingsType" :key="'topping'+key" > <input class="form-check-input" type="checkbox" :id="'topping'+key" :value="item" v-model="itemSelected.toppings" /> <label class="form-check-label" :for="'topping'+key" >{{item}}</label > </div> </div> <div class="mb-3"> <label for="productNotice" class="form-label" >備註</label > <textarea class="form-control" id="productNotice" rows="2" v-model="itemSelected.text" ></textarea> </div> <div class="d-flex gap-2"> <button class="btn btn-outline-primary w-100" type="button" @click.prevent="resetOrder()" > 取消 </button> <button class="btn btn-primary w-100" @click.prevent="addToOrder(itemSelected)" type="button" > 加入 </button> </div> </div> </div> <div class="card"> <div class="card-body"> <table class="table"> <thead> <tr> <th scope="col">品項</th> <th scope="col">冰塊</th> <th scope="col">甜度</th> <th scope="col">加料</th> <th scope="col">單價</th> <th scope="col">數量</th> <th scope="col">小計</th> </tr> </thead> <tbody> <tr v-for="(item,key) in orderList" :key="'order'+key" > <th scope="row"> {{ item.name }}<br /> <small class="text-muted fw-normal" >備註:{{item.text}}</small > </th> <td>{{item.ice}}</td> <td>{{item.sugar}}</td> <td>{{item.toppings.toString()}}</td> <td>{{item.price + item.toppings.length*10}}</td> <td>{{item.count}}</td> <td class="text-end">{{item.total}}</td> </tr> </tbody> </table> <p class="text-end">共 NT$ {{totalPrice}}元</p> <button class="btn btn-sm btn-secondary w-100" @click.prevent="clearOrder" > 清空清單 </button> </div> </div> </div> </div> </div> </div> ``` ## JS(Vue) > itemSelected 放被選擇的項目 orderList 購物車 totalPrice 訂單總價 ``` const App = { data() { return { itemSelected: {}, orderList: [], totalPrice: "", iceType: ["正常冰", "少冰", "微冰", "去冰", "熱"], sugarType: ["全糖", "七分", "半糖", "三分", "無糖"], toppingsType: ["珍珠", "粉條", "小粉圓", "椰果", "芋頭"], products: [ { name: "珍珠鮮奶茶", engName: "Pearl Milk Tea", price: 60, }, { name: "鮮奶茶", engName: "Milk Tea", price: 50, }, { name: "古意冬瓜茶", engName: "Winter Melon Drink", price: 30, }, { name: "蜜香紅茶", engName: "Black Tea", price: 30, }, { name: "包種青茶", engName: "Black Tea", price: 35, }, { name: "檸檬烏龍", engName: "Lemon Oolong Tea", price: 55, }, { name: "薑母茶", engName: "Ginger Tea", price: 55, }, { name: "青草茶", engName: "Herbal Tea", price: 35, }, { name: "金桔檸檬", engName: "Kumquat Lemonade", price: 40, }, { name: "柳澄青茶", engName: "Orange Mountain Tea", price: 45, }, ], }; }, methods: { selectedProduct(product) { this.itemSelected = { ...product, count: 1, // 預設一杯 toppings: [], // 加料 ice: "", // 溫度 sugar: "", // 甜度 text: "", // 備註 }; }, addToOrder(selectProduct) { const order = { ...selectProduct, total: (selectProduct.price + selectProduct.toppings.length * 10) * selectProduct.count, // 加入加料的價錢 }; this.orderList.push(order); this.countTotal(); // 計算總價 this.resetOrder(); // 加入計算之後重新清空 }, countTotal() { this.totalPrice = 0; this.orderList.forEach((item) => { this.totalPrice += item.total; }); }, resetOrder() { this.itemSelected = {}; // 重新清空 }, clearOrder() { this.orderList = []; // 清空購物車 } }, }; Vue.createApp(App).mount("#app"); ``` --- ## 補充 ##### 更新版本啦! [**版本1**](https://hackmd.io/@LindaLiu/HkTU3gSqi) [**版本2**](https://hackmd.io/@LindaLiu/ryBeOxt9i) #### ヽ(∀゚ )人(゚∀゚)人( ゚∀)人(∀゚ )人(゚∀゚)人( ゚∀)ノヽ(∀゚ )人(゚∀゚)人( ゚∀)人(∀゚ )人(゚∀゚)人( ゚∀)人 ##### 以上 如果註解哪裡有錯誤或有問題,歡迎提出來一起討論~~~~