vue-实现购物车(vue指令、filter过滤器、computed计算属性、Vue.set)

这篇文章主要是为大家介绍一下vue实现购物车,代码量不大,但包含的知识点很充足,麻雀虽小,五脏俱全,请继续往下看

知识点包含:vue指令、filter过滤器、computed计算属性、Vue.set设置属性,综合起来功能很全面

效果图gif如下所示:

具体实现代码如下:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<style>
    table {
        border-collapse: collapse;
        width: 600px;
        margin: 0 auto;
        text-align: center;
    }

    th,
    td {
        border: 1px red solid;
        height: 40px;
    }

    #num {
        text-align: center;
    }

    .number span {
        padding: 5px 10px;
        background-color: #eee;
        cursor: pointer;
    }

    .hh-enter-active {
        animation: slideInLeft .3s;
    }

    .hh-leave-active {
        animation: slideOutRight .3s;
    }
    #num p{
        font-size: 24px;
    }
</style>

<body>
    <div id="app">
        <table>
            <thead>
                <th></th>
                <th>名称</th>
                <th>价格</th>
                <th>数量</th>
                <th>小计</th>
                <th>操作</th>
            </thead>
            <tbody>
                <transition-group name='hh'>
                <tr v-for="(item,index) in goods" :key='index'>
                    <td>
                        <input type="checkbox" @click='selectGood(item)' :checked='item.check'>
                    </td>
                    <td>{{item.title}}</td>
                    <td>{{item.price | foDate }}</td>
                    <td class="number">
                        <span @click='changeNum(item,0)'>-</span>
                        <input type="text" v-model='item.count'>
                        <span @click='changeNum(item,1)'>+</span>
                    </td>
                    <td>{{item.price*item.count | foDate }}</td>
                    <td>
                        <input type="button" value="删除" @click='del(index)'>
                    </td>
                </tr>
                </transition-group>
            </tbody>
        </table>
        <div id="num">
            <input type="checkbox" @click='checkAll' :checked='allCheck'>
            <label for="" style="margin-right: 10px;">全选</label>
            <button style="margin-right: 10px;" @click='checkOtherAll'>反选</button>
            <button @click="delSelected" style="margin-right: 10px;" @click='checkOtherAll'>删除全选</button>
            <p>已选择:{{changed }}个</p>
            <p>总计:{{totalNum }}个</p>
            <p>总计:{{priceTotal | foDate }}</p>
        </div>

    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    Vue.filter('foDate', function (val) {
        return '¥' + val.toFixed(2)
    })
    var vm = new Vue({
        el: "#app",
        data: {
            goods: [
                { title: "上衣", price: 200, count: 1 },
                { title: "裤子", price: 100, count: 1 },
                { title: "鞋子", price: 500, count: 1 },
                { title: "风衣", price: 1000, count: 1 },
                { title: "帽子", price: 300, count: 1},
                { title: "西服", price: 2000, count: 1 },
            ]
        },
        methods: {
            //单选商品
            selectGood(item) {
                if (!item.check) {
                    Vue.set(item, 'check', true)
                } else {
                    item.check = !item.check;
                }
            },
            //加减数量
            changeNum(item, i) {
                // 加
                if (i == 0) {
                    item.count--;
                    if (item.count < 2) {
                        item.count = 1;
                    }
                    //减
                **} else {**
                    item.count++;
                    **if (item.count > 14) {**
                        item.count = 15;
                    }
                }
            },
            //删除一个
            del(index) {
                this.goods.splice(index, 1);
            },
            //删除选中
            delSelected() {
                var abc = this.goods.filter((item, index) => {
                    return item.check != true;
                });
                this.goods = abc;
            },
            //全选
            checkAll() {
                this.flag = !this.flag;
                this.goods.forEach(item => {
                    if (!item.check) {**
                        Vue.set(item, 'check', true)
                    } else {**
                        item.check = !item.check;
                    }
                });**
            },
            //反选
            checkOtherAll() {
                this.goods.forEach(item => {
                    if (!item.check) {
                        Vue.set(item, 'check', true)
                    } else {
                        item.check = !item.check;
                    }
                });
            }
        },
        computed: {
            //监听全选按钮是否应该勾选,受单选的影响
            allCheck() {
                return this.goods.every(item => {
                **    return item.check == true
                })
            },
            //计算总价总价
            priceTotal() {
                var num = 0;
               ** this.goods.forEach(item => {
                    if (item.check == true) {
                        num += item.price * item.count
                    }
                });
                return num;
            },
            // 计算总数量
            totalNum() {
                var num = 0;
                this.goods.forEach(item => {
                    num += item.count
                });
                return num;
            },
            // 计算已选数量
            changed() {
                var num = 0;**
                this.goods.forEach(item => {
                    if (item.check == true) {
              **          num += item.count
                    }
                });
                return num;
            }
        }
    })
</script>
</html>
posted @ 2020-07-23 20:17  飘逸_winxin  阅读(317)  评论(0编辑  收藏  举报