vue组件化购物车

<!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>Document</title>
</head>

<body>
    <div id="app">
        <div class=container>
            <my-cart></my-cart>

        </div>
    </div>
    <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script type="text/javascript">
        /*标题头子组件*/
        var cartTitle = {
            props: ['uname'],/*用于从父组件传来值*/
            template: `
                <div class='title'>{{uname}}商品</div>
            `
        }
        /*商品列表子组件*/
        var cartList = {
            props: ['list'],
            template: `
                <div>
                    <div v-bind:key='item.id' v-for='item in list' class="item"><!-- 遍历展示所有商品 -->
                        <img v-bind:src="item.img"/>
                        <div class="name">{{item.name}}</div>
                        <div class="change">
                            <a href="" v-on:click.prevent='sub(item.id)'>-</a><!-- 阻止a标签原有跳转,并在点击时,触发sub方法-->
                            <input type="text" class="num" v-on:blur='changeNum(item.id,$event)' v-bind:value='item.num' /><!-- 在失去焦点时触发changeNum方法,通过$event传递原有数据值-->
                            <a href="" v-on:click.prevent='add(item.id)'>+</a>
                        </div>
                        <div class="del" v-on:click='del(item.id)'>×</div><!-- 删除商品-->
                    </div>
                </div>
            `,
            methods: {
                sub: function (id) {
                    this.$emit('change_num', {/*子组件不直接对数据处理,通过向父组件传递change_num事件,让父组件处理数据*/
                        id: id,
                        type: 'sub'
                    })
                },
                add: function (id) {
                    this.$emit('change_num', {
                        id: id,
                        type: 'add'
                    })
                },
                changeNum: function (id, event) {
                    this.$emit('change_num', {/*子组件不直接对数据处理,通过向父组件传递change_num事件,让父组件处理数据,原来商品数量通过event.target.value传递*/
                        id: id,
                        num: event.target.value,
                        type: 'change'
                    });
                },
                del: function (id) {
                    this.$emit('cart-del', id);/*子组件不直接对数据处理,通过向父组件传递cart-del事件,让父组件处理数据*/
                }
            }
        }
        /*结算尾子组件*/
        var cartTotal = {
            props: ['list'],
            template: `
                    <div class="total">
                        <span>总价:{{total}}</span>
                        <button>结算</button>
                    </div>
            `,
            computed: {/*计算方法*/
                total: function () {
                    var t = 0;
                    this.list.forEach(item => {
                        t += item.price * item.num;
                    });
                    return t;
                }
            }
        }
        Vue.component('my-cart', {/*组件名称my-cart*/
            /*数据data*/
            data: function () {
                return {
                    uname: 'ben',
                    list: [{
                            id: 1,
                            name: 'TCL彩电',
                            price: 1000,
                            num: 1,
                            img: 'img/a.jpg'
                        },
                        {
                            id: 2,
                            name: '机顶盒',
                            price: 1000,
                            num: 1,
                            img: 'img/b.jpg'
                        }, {
                            id: 3,
                            name: '海尔冰箱',
                            price: 1000,
                            num: 1,
                            img: 'img/c.jpg'
                        }, {
                            id: 4,
                            name: '小米手机',
                            price: 1000,
                            num: 1,
                            img: 'img/d.jpg'
                        }, {
                            id: 5,
                            name: 'PPTV电视',
                            price: 1000,
                            num: 2,
                            img: 'img/e.jpg'
                        }
                    ]
                }
            },
            /*包含三个子组件,分别是标题头,中间的商品列表,最后的结算尾*/
            template: `
                <div>
                    <cart-title v-bind:uname='uname'></cart-title>
                    <cart-list v-bind:list='list' v-on:cart-del='delCart($event)' v-on:change_num='changeNum($event)'></cart-list>
                    <cart-total v-bind:list='list'></cart-total>
                </div>
            `,
            components: {
                'cart-title': cartTitle,
                'cart-list': cartList,
                'cart-total': cartTotal
            },
            methods: {
                /*改变商品数量的方法*/
                changeNum: function (val) {
                    if (val.type == 'change') {
                        /*遍历找到商品与之所对应的id*/
                        this.list.some(item => {
                            if (item.id == val.id) {
                                item.num = val.num;
                                return true;
                            }
                        });
                    } else if (val.type == 'sub') {
                        this.list.some(item => {
                            if (item.id == val.id) {
                                item.num -= 1
                            }
                        })
                    } else {
                        this.list.some(item => {
                            if (item.id == val.id) {
                                item.num += 1
                            }
                        })
                    }
                },
                /*删除商品的方法*/
                delCart: function (id) {
                    /*遍历找到id所对应的列表中的序号*/
                    var index = this.list.findIndex(item => {
                        return item.id == id;
                    });
                    /*删除列表中该序号的值*/
                    this.list.splice(index, 1);
                }
            }
        });
        var app = new Vue({
            el: '#app',
            data: {
            }
        });
    </script>
</body>

</html>
原文地址:https://www.cnblogs.com/Qi-Lin/p/12257850.html