vue.js实战实现购物车的单选全选和二维数组分类--第五章购物车练习(二)

本例介绍《vue.js实战》第五章最后的购物车练习二,

练习2:将商品列表list改为一个二维数组来实现商品的分类,比如分为"电子产品","生活用品","果蔬",同类商品聚合在一起.提示,你可能用到两次v-for.

提醒:二维数组可以采用这种方式

[
 {
     name:'电子产品',
     productList:[
    {
      id:1,
      name:'手机'
   },
    {
      id:2,
     name:'电脑'
    }

   ]
 }

]

vue.js实战实现购物车的单选全选和二维数组分类--第五章购物车练习(二)

html:

  <div id="app" cloak>
        <template v-if="list.length">
            <table>
                <tbody v-for="(tableItem, tableIndex) in list" v-if="tableItem.productList.length">
                    <tr>
                        <th><input type="checkbox" @click="handleTableItem(tableItem)"
                                :checked="isCheckedTableItem(tableItem)">{{ tableItem.name }}</th>
                        <th>序号</th>
                        <th>商品名称</th>
                        <th>商品单价</th>
                        <th>购买数量</th>
                        <th>操作</th>
                    </tr>
                    <tr v-for="(item, index) in tableItem.productList">
                        <td><input type="checkbox" @click="handleChecked(item)" :checked="isChecked(item)"></td>
                        <td>{{ index + 1 }}</td>
                        <td>{{ item.name }}</td>
                        <td>{{ item.price }}</td>
                        <td>
                            <button @click="handleReduce(item)" :disabled="item.count===1">-</button>
                            {{ item.count }}
                            <button @click="handleAdd(item)">+</button>
                        </td>
                        <td>
                            <button @click="handleRemove(index, tableIndex)">移除</button>
                        </td>
                    </tr>
                </tbody>
            </table>
            <div>
                <input type="checkbox" @click="checkAll()" :checked="isCheckedAll()">全选
            </div>
            <div>总价:¥{{ totalPrice }}</div>
        </template>
        <div v-else>购物车为空</div>
    </div>

js:

 var app = new Vue({
            el: '#app',
            data: {
                list: [{
                        name: "电子产品",
                        productList: [{
                                id: '1',
                                name: 'iPhone 7',
                                price: 6188,
                                count: 1,
                                status: 1
                            },
                            {
                                id: '2',
                                name: 'iPad Pro',
                                price: 5188,
                                count: 1,
                                status: 1
                            },
                            {
                                id: '3',
                                name: 'MacBook Pro',
                                price: 21488,
                                count: 1,
                                status: 1
                            }
                        ]
                    },
                    {
                        name: "生活用品",
                        productList: [{
                                id: '1',
                                name: '尺子',
                                price: 2.00,
                                count: 1,
                                status: 1
                            },
                            {
                                id: '2',
                                name: '包装箱',
                                price: 29.99,
                                count: 1,
                                status: 1
                            },
                            {
                                id: '3',
                                name: '毛巾',
                                price: 15.98,
                                count: 1,
                                status: 1
                            }
                        ]
                    },
                    {
                        name: "水果蔬菜",
                        productList: [{
                                id: '1',
                                name: '国产香蕉',
                                price: 2.88,
                                count: 1,
                                status: 1
                            },
                            {
                                id: '2',
                                name: '草莓',
                                price: 15.00,
                                count: 1,
                                status: 1
                            },
                            {
                                id: '3',
                                name: '车厘子',
                                price: 29.99,
                                count: 1,
                                status: 1
                            }
                        ]
                    }
                ]
            },
            computed: {
                totalPrice: function () {
                    var total = 0;
                    for (var i = 0; i < this.list.length; i++) {
                        for (var j = 0; j < this.list[i].productList.length; j++) {
                            var item = this.list[i].productList[j];
                            if (item.status) {
                                total += item.price * item.count;
                            }
                        }
                    }
                    return total != 0 ? total.toString().replace(/\B(?=(\d{3})+$)/g, ',') : 0;
                }
            },
            methods: {
                handleTableItem: function (tableItem) {
                    var status = this.isCheckedTableItem(tableItem);
                    status = status ? 0 : 1;
                    for (var i = 0; i < tableItem.productList.length; i++) {
                        tableItem.productList[i].status = status;
                    }
                },
                isCheckedTableItem: function (tableItem) {
                    //console.log("tableItem: " + tableItem)

                    var status = true;
                    for (var i = 0; i < tableItem.productList.length; i++) {
                        if (!tableItem.productList[i].status) {
                            status = false;
                            return status;
                        }
                    }
                    return status;
                },
                //改变某条记录选中状态
                handleChecked: function (item) {
                    item.status = !item.status;
                },
                handleReduce: function (item) {
                    if (item.count === 1) return;
                    item.count--;
                },
                handleAdd: function (item) {
                    item.count++;
                },
                handleRemove: function (index, tableIndex) {
                    this.list[tableIndex].productList.splice(index, 1);
                },
                isChecked: function (item) {
                    return item.status;
                },
                isCheckedAll: function () {
                    //列表全为true该status才为true,否则为false
                    var status = true;
                    for (var i = 0; i < this.list.length; i++) {
                        //一旦列表的status有一个为false则status就为false
                        for (var j = 0; j < this.list[i].productList.length; j++) {
                            if (!this.list[i].productList[j].status) {
                                status = false;
                                return status;
                            }
                        }
                    }
                    return status;
                },
                checkAll: function () {
                    //拿到是否是全选
                    var status = this.isCheckedAll();
                    status = status ? 0 : 1;
                    for (var i = 0; i < this.list.length; i++) {
                        for (var j = 0; j < this.list[i].productList.length; j++) {
                            this.list[i].productList[j].status = status;
                        }
                    }
                }
            }
        })