Vue入门小案例-购物车

1,004 阅读2分钟

使用Vue制作一个购物车小案例

1. html

<div id="app" class="table-box">
    <table class="common-table table-bordered table-striped table-hover">
        <colgroup>
            <col width="5%" />
            <col width="10%" />
            <col width="25%" />
            <col width="10%" />
            <col width="10%" />
            <col width="15%" />
            <col width="10%" />
            <col width="15%" />
        </colgroup>
        <thead>
            <tr>
                <th>
                    <!-- 使用change而不用click是因为 click 执行比 model绑定快一步,数据是不对的 -->
                    <input type="checkbox" name="all" v-model="isall" @change="checkall" />
                </th>
                <th>ID</th>
                <th>品名</th>
                <th>单位</th>
                <th>单价/元</th>
                <th>数量</th>
                <th>金额/元</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>
            <!-- key索引最好不要用 index, 若是存在分页情况可能会出现问题 -->
            <tr v-for="(item, index) in goods" :key="item.id">
                <td>
                    <!-- input checkbox 中不管 checked 为何值,只要有就是选中状态 -->
                    <!-- <input type="checkbox" name="id" checked /> -->
                    <!-- Vue中的复选框 v-model 可以是boolean值,也可以是数组,数值元素就是 value -->
                    <input type="checkbox" :value="item" v-model="checklist" />
                </td>
                <td class="a-left">{{ item.id }}</td>
                <td class="a-left">{{ item.name }}</td>
                <td>{{ item.unit }}</td>
                <td class="price">{{ item.price }}</td>
                <td class="count">
                    <button @click="item.count--" :disabled="item.count < 1">-</button>
                    {{ item.count }}
                    <!-- 使用disabled直接进行库存加购限制 -->
                    <button @click="item.count++" :disabled="item.count >= item.stock">+</button>
                </td>
                <td class="item-amount">{{ item.price * item.count }}</td>
                <td>
                    <button @click="deletegood(item.id)">移除商品</button>
                </td>
            </tr>
        </tbody>
        <tfoot>
            <tr class="summary">
                <td colspan="5">总计</td>
                <td>{{ sum().count }}</td>
                <td>{{ sum().amount }}</td>
                <td></td>
            </tr>
        </tfoot>
    </table>
    <!-- {{ checklist }} -->
</div>

2. js

 var obj = {
    data() {
        return {
            // 选中列表
            checklist: [],
            // 是否全选
            isall: false,
            // 商品列表
            goods: [{
                id: 'SN-0001',
                name: '小米Redmi Note8',
                unit: '台',
                price: 999,
                count: 1,
                stock: 99, // 库存
            }, {
                id: 'SN-0002',
                name: '华为 HUAWEI Mate 30 Pro',
                unit: '台',
                price: 6399,
                count: 1,
                stock: 11, // 库存

            }, {
                id: 'SN-0003',
                name: '华为 HUAWEI P40 Pro',
                unit: '台',
                price: 5988,
                count: 1,
                stock: 2, // 库存
            }]
        }
    },
    watch: {
        checklist(value) {
            // 通过对checklist监听来判断全选状态
            this.isall = (value.length == this.goods.length && this.goods.length > 0) ? true : false
        }
    },
    methods: {
        sum() {
            // 求和 -- forEach方式
            // let amount = 0
            // let count = 0
            // this.checklist.forEach(item => {
            //     amount += item.price * item.count
            //     count += item.count
            // })
            // return { amount, count }

            // 求和 -- reduce方式
            // return {
            //     amount: this.checklist.reduce((total, item) => {
            //         return total + item.price * item.count
            //     }, 0),
            //     count: this.checklist.reduce((total, item) => {
            //         return total + item.count
            //     }, 0)
            // }

            // 求和 -- reduce方式优化
            return this.checklist.reduce((total, item) => {
                return {
                    amount: total.amount + item.price * item.count,
                    count: total.count + item.count,
                }
            }, { amount: 0, count: 0 })
        },
        // 全选
        checkall() {
            this.checklist = this.isall ? this.goods : []
        },
        // 选中数组的同步操作
        deletegood(id) {
            // 删除对应商品
            this.goods = this.goods.filter(item => item.id != id)
            // 选中数组删除对应商品
            this.checklist = this.checklist.filter(item => item.id != id)
        }
    }
}

let vm = Vue.createApp(obj).mount('#app')

3. 效果图

购物车.png

4. 开发中的一些小要点

  1. 复选框值的绑定
<input type="checkbox" :value="item" v-model="checklist" />

这里使用数组来绑定复选框,可以赋值value为商品的某一项,这样使得后续拿到完整数据,比如拿id: item.id 2. 总计求和通过定义sum方法得到,当然放到watch监听checklist中也同样可以,这里是为了看起来更直观些(主要是因为懒,不想再定义两个初始总计数据,后续想扩展几个就直接sum中加就行了)

sum() {
   ... 
}
  1. 对商品数量的限制使用disabled实现
<button @click="item.count--" :disabled="item.count < 1">-</button>
{{ item.count }}
<!-- 使用disabled直接进行库存加购限制 -->
<button @click="item.count++" :disabled="item.count >= item.stock">+</button>
  1. 删除商品方法参数方法不建议使用index(易出问题), 使用唯一编号id不会出错
deletegood(id) {
    // 删除对应商品
    this.goods = this.goods.filter(item => item.id != id)
    // 选中数组删除对应商品
    this.checklist = this.checklist.filter(item => item.id != id)
}

ps: 这里直接替换原数组是最方便的(偷懒了),若是遇到业务复杂的删除,不建议这么做,老老实实去删除对应元素