商城中商品購買中多規格的選擇
阿新 • • 發佈:2022-12-02
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>規格選擇</title> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.min.js"></script> <style> html, body { padding: 0; margin: 0; } #app { font-size: 16px; width: 100%; height: 100%; margin: auto; padding: 20px; box-sizing: border-box; } .productBox { display: block; margin: 0 auto; } .productContent { margin-bottom: 50px; } .productDelcom { color: #323232; border-bottom: 1px solid #EEEEEE; padding-bottom: 30px; } .productFooter { margin-top: 10px; } .productFooter .specItem { border: 1px solid #606060; border-radius: 5px; color: #606060; text-align: center; padding: 4px 12px; margin-right: 20px; cursor: pointer; display: inline-block; } .productFooter .specItem.productActive { background-color: #1A1A29; color: #fff; border: 1px solid #1A1A29; } .productFooter .specItem.noneActive { background-color: #ccc; opacity: 0.4; color: #000; pointer-events: none; } .buyBtn { background-color: #1A1A29; color: #fff; text-align: center; height: 44px; display: flex; align-items: center; justify-content: center; width: 90%; margin: 0 auto; border-radius: 8px; } .price { height: 30px; line-height: 30px; margin-top: 10px; } </style> </style> </head> <body> <div id="app"> <div class="productBox"> <div class="productContent"> <div class="productDelcom" v-for="(ProductItem,n) in simulatedData.specifications"> <p>{{ProductItem.name}}</p> <div class="productFooter"> <div class="specItem" v-for="(item,index) in ProductItem.item" @click="specificationBtn(item.name,n,$event,index)" :class="[item.isShow?'':'noneActive',subIndex[n] == index?'productActive':'']"> {{item.name}} </div> </div> </div> <p class="price"> ¥ {{price}}</p> </div> <div class="buyBtn">立即購買</div> </div> </div> <script> var app = new Vue({ el: '#app', data() { return { simulatedData: { //模擬後臺返回的資料 多規格 "difference": [{ "id": "19", "price": "200.00", "stock": "19", // 庫存 "difference": "100,白色,AA" // 規格 }, { "id": "20", "price": "100.00", "stock": "29", "difference": "200,白色,AA" }, { "id": "21", "price": "300.00", "stock": "10", "difference": "100,黑色,AA" }, { "id": "22", "price": "900.00", "stock": "0", "difference": "200,黑色,AA" }, { "id": "23", "price": "600.00", "stock": "48", "difference": "100,綠色,AA" }, { "id": "24", "price": "500.00", "stock": "40", "difference": "200,綠色,AA" }, { "id": "25", "price": "90.00", "stock": "0", "difference": "100,藍色,AA" }, { "id": "26", "price": "40.00", "stock": "20", "difference": "200,藍色,AAA" } ], "specifications": [//這裡是要被渲染欄位 { "name": "尺寸", "item": [{ "name": "100", }, { "name": "200", } ] }, { "name": "顏色", "item": [{ "name": "白色", }, { "name": "藍色", }, { "name": "黑色", }, { "name": "綠色", } ] }, { "name": "尺寸", "item": [{ "name": "AA", }, { "name": "AAA", }] }, ] }, selectArr: [], //存放被選中的值 shopItemInfo: {}, //存放要和選中的值進行匹配的資料 subIndex: [], //是否選中 因為不確定是多規格還是單規格,所以這裡定義陣列來判斷 price: 0 //選中規格的價錢 } }, mounted() { this.checkItem() }, methods: { specificationBtn: function(item, n, event, index) { if (this.selectArr[n] != item) { this.selectArr[n] = item; this.subIndex[n] = index; } else { this.selectArr[n] = ""; this.subIndex[n] = -1; //去掉選中的顏色 } this.checkItem(); }, checkItem: function() { var option = this.simulatedData.specifications; console.log(option) var result = []; //定義陣列儲存被選中的值 for (var i in option) { result[i] = this.selectArr[i] ? this.selectArr[i] : ''; } console.log(result) for (var i in option) { var last = result[i]; //把選中的值存放到字串last去 for (var k in option[i].item) { console.log(result[i]) console.log(option[i].item[k].name) result[i] = option[i].item[k].name; //賦值,存在直接覆蓋,不存在往裡面新增name值 option[i].item[k].isShow = this.isMay(result); //在資料裡面新增欄位isShow來判斷是否可以選擇 } result[i] = last; //還原,目的是記錄點下去那個值,避免下一次執行迴圈時被覆蓋 } if (this.shopItemInfo[result]) { let str = this.shopItemInfo[result].difference.split(',') this.price = str.length == 3 ? this.shopItemInfo[result].price : 0 } else { this.price = 0 } self.$forceUpdate(); // 強制更新 }, isMay: function(result) { for (var i in result) { if (result[i] == '') { return true; //如果數組裡有為空的值,那直接返回true } } console.log(result) console.log(this.shopItemInfo[result]) return !this.shopItemInfo[result] || this.shopItemInfo[result].stock == 0 ? false : true; //匹配選中的資料的庫存,若不為空返回true } }, created: function() { console.log(this.simulatedData.difference) for (var i in this.simulatedData.difference) { this.shopItemInfo[this.simulatedData.difference[i].difference] = this.simulatedData .difference[i]; } //[100,白色,AA: {}, 100,白色,AA: {}] console.log(this.shopItemInfo) this.checkItem(); } }) </script> </body> </html>