Vue.js实战第五章练习题

利用计算属性、指令等知识开发购物车

题目描述

购物车需要展示一个已加入购物车的商品列表,包含商品名称、商品单价、购买数量、操作等信息,还需要实时显示购买的总价。其中购买的数量可以增加或减少,每类商品可以从购物车中移除。

进阶1

在上述问题的基础上,新增一项是否选中该商品的功能,总价变为只计算选中商品的总价,同时提供一个全选按钮

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>第五章练习一</title>
    <style>
        [v-cloak] {
            display: none;
        }

        table {
            border: 1px solid #e9e9e9;
            border-collapse: collapse;
            border-spacing: 0;
            empty-cells: show;
        }

        th,
        td {
            border: 1px solid #e9e9e9;
            text-align: left;
        }

        th {
            background: #f7f7f7;
            color: #5c6b77;
            font-weight: 600;
            white-space: nowrap;
        }
    </style>
</head>

<body>
    <div id="app" v-cloak>
        <template v-if="list.length">
            <table>
                <thead>
                    <tr>
                        <th><input type="checkbox" @click="swap2Checked" :checked=allChecked></th>
                        <th>商品名称</th>
                        <th>商品单价</th>
                        <th>商品数量</th>
                        <th>操作</th>
                    </tr>
                </thead>
                <tbody>
                    <tr v-for="(item,index) in list">
                        <td><input type="checkbox" :checked=item.isCheck :id="item.id" :value="index"
                                @click="changeStatus(index)">
                        </td>
                        <td>{{ item.name }}</td>
                        <td>{{ item.price }}</td>
                        <td>
                            <button @click="handleReduce(index)" :disabled="item.count === 1">-</button>
                            {{ item.count }}
                            <button @click="handleAdd(index)">+</button>
                        </td>
                        <td><button @click="handleRemove(index)">移除</button></td>
                    </tr>
                </tbody>
            </table>
            <div>总价:¥ {{ totalPrice }}</div>
        </template>
        <div v-else>购物车为空</div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    <script>
        var app = new Vue({
            el: '#app',
            data() {
                return {
                    msg: 'hello',
                    link: '<a href="#">this is a link</a>',
                    url: 'http://www.baidu.com/',
                    list: [
                        {
                            id: 1,
                            name: 'iphone x',
                            price: 6100,
                            count: 1,
                            isCheck: false
                        },
                        {
                            id: 2,
                            name: 'ipad pro',
                            price: 4000,
                            count: 1,
                            isCheck: true
                        },
                        {
                            id: 3,
                            name: 'mac pro',
                            price: 20100,
                            count: 1,
                            isCheck: false
                        }
                    ],
                    allChecked: false
                }
            },
            computed: {
                totalPrice: function () {
                    var total = 0;
                    for (var i = 0; i < this.list.length; i++) {
                        if (this.list[i].isCheck) {
                            var item = this.list[i];
                            total += item.price * item.count;
                        }
                    }
                    return total;
                },
                // allChecked: function () {
                //     for (var i = 0; i < this.list.length; i++) {
                //         if (!this.list[i].isCheck) {
                //             return false
                //         }
                //     }
                //     return true
                // }
            },
            methods: {
                handleReduce: function (index) {
                    if (this.list[index].count === 1) return;
                    this.list[index].count--;
                },
                handleAdd: function (index) {
                    this.list[index].count++;
                },
                handleRemove: function (index) {
                    this.list.splice(index, 1);
                },
                swap2Checked: function () {
                    this.allChecked = !this.allChecked
                    if (this.allChecked) {
                        for (var i = 0; i < this.list.length; i++) {
                            this.list[i].isCheck = true
                        }
                    }else{
                        for (var i = 0; i < this.list.length; i++) {
                            this.list[i].isCheck = false
                        }
                    }
                },
                changeStatus: function (index) {
                    this.list[index].isCheck = !this.list[index].isCheck
                    var flag = true
                    for (var i = 0; i < this.list.length; i++) {
                            if(!this.list[i].isCheck){
                                flag = false
                            }
                    }
                    this.allChecked = flag
                }
            }
        })
    </script>
</body>

</html>

进阶2

将商品的列表List改为一个二维数组来实现商品的分类,比如可分为“电子商品”,“生活用品”,同类商品聚合在一起。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>第五章练习一</title>
    <style>
        [v-cloak] {
            display: none;
        }

        table {
            border: 1px solid #e9e9e9;
            border-collapse: collapse;
            border-spacing: 0;
            empty-cells: show;
        }

        th,
        td {
            border: 1px solid #e9e9e9;
            text-align: left;
        }

        th {
            background: #f7f7f7;
            color: #5c6b77;
            font-weight: 600;
            white-space: nowrap;
        }
    </style>
</head>

<body>
    <div id="app" v-cloak>
        <template v-if="list.length">
            <table>
                <tbody v-for="(items,tableIndex) in list">
                    <tr>
                        <th><input type="checkbox" @click="swapTableChecked($event,items)"
                                :checked="isTableAllChecked(items)">{{items.name}}</th>
                        <th>商品名称</th>
                        <th>商品单价</th>
                        <th>商品数量</th>
                        <th>操作</th>
                    </tr>
                    <tr v-for="(item,index) in items.productList">
                        <td><input type="checkbox" :checked=item.isCheck :id="item.id" :value="index"
                                @click="changeStatus(item)">
                        </td>
                        <td>{{ item.name }}</td>
                        <td>{{ item.price }}</td>
                        <td>
                            <button @click="handleReduce(index,items)" :disabled="item.count === 1">-</button>
                            {{ item.count }}
                            <button @click="handleAdd(index,items)">+</button>
                        </td>
                        <td><button @click="handleRemove(index,items)">移除</button></td>
                    </tr>
                </tbody>
            </table>
            <div><input type="checkbox" @click="swapAllChecked" :checked="isAllChecked()">全选</div>
            <div>总价:¥ {{ totalPrice }}</div>
        </template>
        <div v-else>购物车为空</div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    <script>
        var app = new Vue({
            el: '#app',
            data() {
                return {
                    msg: 'hello',
                    link: '<a href="#">this is a link</a>',
                    url: 'http://www.baidu.com/',

                    list: [{
                        name: "电子产品",
                        productList: [{
                            id: '1',
                            name: 'iPhone 7',
                            price: 6188,
                            count: 1,
                            isCheck: false
                        },
                        {
                            id: '2',
                            name: 'iPad Pro',
                            price: 5188,
                            count: 1,
                            isCheck: false
                        },
                        {
                            id: '3',
                            name: 'MacBook Pro',
                            price: 21488,
                            count: 1,
                            isCheck: false
                        }
                        ]
                    },
                    {
                        name: "生活用品",
                        productList: [{
                            id: '1',
                            name: '尺子',
                            price: 2.00,
                            count: 1,
                            isCheck: false
                        },
                        {
                            id: '2',
                            name: '包装箱',
                            price: 29.99,
                            count: 1,
                            isCheck: false
                        },
                        {
                            id: '3',
                            name: '毛巾',
                            price: 15.98,
                            count: 1,
                            isCheck: false
                        }
                        ]
                    },
                    {
                        name: "水果蔬菜",
                        productList: [{
                            id: '1',
                            name: '国产香蕉',
                            price: 2.88,
                            count: 1,
                            isCheck: false
                        },
                        {
                            id: '2',
                            name: '草莓',
                            price: 15.00,
                            count: 1,
                            isCheck: false
                        },
                        {
                            id: '3',
                            name: '车厘子',
                            price: 29.99,
                            count: 1,
                            isCheck: false
                        }
                        ]
                    }
                    ],
                    allChecked: false
                }
            },
            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.isCheck) {
                                total += item.price * item.count;
                            }
                        }
                    }
                    return total != 0 ? total.toString().replace(/\B(?=(\d{3})+$)/g, ',') : 0;
                },

            },
            methods: {
                handleReduce: function (index,items) {
                    
                    if (items.productList[index].count === 1) return;
                    items.productList[index].count--;
                },
                handleAdd: function (index,items) {
                    console.log(items)
                    items.productList[index].count++;
                },
                handleRemove: function (index,items) {
                    items.productList.splice(index, 1);
                },
                swapTableChecked: function (e, items) {
                    console.log(e)
                    console.log(e.currentTarget.checked)
                    if (e.currentTarget.checked) {
                        for (var i = 0; i < items.productList.length; i++) {
                            items.productList[i].isCheck = true
                        }
                    } else {
                        for (var i = 0; i < items.productList.length; i++) {
                            items.productList[i].isCheck = false
                        }
                    }
                },
                changeStatus: function (item) {
                    item.isCheck = !item.isCheck
                },
                isTableAllChecked: function (items) {
                    var flag = true
                    for (var i = 0; i < items.productList.length; i++) {
                        if (!items.productList[i].isCheck) {
                            return false
                        }
                    }
                    return true
                },
                swapAllChecked: function (e) {
                    if (e.currentTarget.checked) {
                        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].isCheck = true;
                            }
                        }
                    } else {
                        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].isCheck = false;
                            }
                        }
                    }
                },
                isAllChecked: function () {
                    var flag = true
                    for (var i = 0; i < this.list.length; i++) {
                        for (var j = 0; j < this.list[i].productList.length; j++) {
                            if (!this.list[i].productList[j].isCheck) {
                                return false
                            }
                        }
                    }
                    return true
                }
            }
        })
    </script>
</body>

</html>

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券