Vue implementation of shopping cart case

Finished product displayInsert picture description here

case study

  1. Implement business requirements in a componentized way
  • Componentization based on business functions
    ① Title component (display text)
    ② List component (list display, product quantity change)
    ③ Settlement component (calculate the total amount of products)
    Insert picture description here

Implementation steps

first step

  1. Static layout
  2. Refactor static data into Vue componentized form (implemented through Vue.component)
  3. Use local components within global components to separate the three parts (components)
  4. Implement componentized refactoring

Second step

  1. Realize dynamic data transfer with data and props
  2. Realize the calculation function (the third attribute calculated)
  3. Calculation formula total price = unit price * quantity
  4. v-for loop and fill the list
  5. Obtain the id in the child component and pass it to the child component (this.$emit() and listen in the parent component)
  6. Set the delete button (find the index of the data corresponding to id and use splice to delete the corresponding data)

third step

  1. Make the quantity displayed on the page
  2. Get id and value through $event (event.target.value)
  3. The judgment is to modify the data of that index
  4. Data addition and subtraction
  5. Use @click to bind events and disable a tag jump function
  6. Set a flag for the plus sign and minus sign to distinguish each other (input field change, plus sign change, minus sign change)

To put it in professional terms

  • Achieve overall layout and style effects
  • Divide independent functional components
  • Combine all sub-components to form and overall structure
  • Implement each component function one by one
    • Title component
    • List component
    • Settlement component

Basic style

#app {
    
    
            width: 700px;
            height: 800px;
            margin: 0 auto;
        }

        .container .cart {
    
    
            width: 300px;
            margin: auto;
        }

        .container .title {
    
    
            background-color: lightblue;
            height: 40px;
            line-height: 40px;
            text-align: center;
            /*color: #fff;*/
        }

        .container .total {
    
    
            background-color: #FFCE46;
            height: 50px;
            line-height: 50px;
            text-align: right;
        }

        .container .total button {
    
    
            margin: 0 10px;
            background-color: #DC4C40;
            height: 35px;
            width: 80px;
            border: 0;
        }

        .container .total span {
    
    
            color: red;
            font-weight: bold;
        }

        .container .item {
    
    
            height: 55px;
            line-height: 55px;
            position: relative;
            border-top: 1px solid #ADD8E6;
        }

        .container .item img {
    
    
            width: 45px;
            height: 45px;
            margin: 5px;
        }

        .container .item .name {
    
    
            position: absolute;
            width: 90px;
            top: 0;
            left: 55px;
            font-size: 16px;
        }

        .container .item .change {
    
    
            width: 100px;
            position: absolute;
            top: 0;
            right: 50px;
        }

        .container .item .change a {
    
    
            font-size: 20px;
            width: 30px;
            text-decoration: none;
            background-color: lightgray;
            vertical-align: middle;
        }

        .container .item .change .num {
    
    
            width: 40px;
            height: 25px;
        }

        .container .item .del {
    
    
            position: absolute;
            top: 0;
            right: 0px;
            width: 40px;
            text-align: center;
            font-size: 40px;
            cursor: pointer;
            color: red;
        }

        .container .item .del:hover {
    
    
            background-color: orange;
        }

The main code to realize the function

<div id="app">
        <my-cart></my-cart>
    </div>

    <script type="text/javascript" src="../js/vue.js"></script>
    <script type="text/javascript">
        var CarTitle = {
     
     
            props: ['uname'],
            template: `
        <div class='title'>{
      
      {uname}}的商品</div>
        `
        }
        var CarList = {
     
     
            props: ['list'],
            template: ` 
         <div>
                <div :key='item.id' v-for='item in list' class="item">
                    <img :src="item.img">
                    <div class='name' >{
      
      {item.name}}</div>
                    <div class="change">
                        <a href="" @click.prevent='sub(item.id)'>—</a>
                        <input type="text" class="num" :value='item.num' @blur='changeNum(item.id,$event)' />
                        <a href="" @click.prevent='add(item.id)'>+</a>
                    </div>
                    <div class="del"  @click='del(item.id)'>x</div>
                </div>
            </div>

        `,
            methods: {
     
     
                changeNum: function (id, event) {
     
     
                    // console.log(id, event.target.value)
                    // 触发自定义事件
                    this.$emit('change-num', {
     
     
                        id: id,
                        num: event.target.value,
                        type: 'change'
                    })
                },
                sub: function (id) {
     
     
                    this.$emit('change-num', {
     
     
                        id: id,
                        type: 'sub'
                    })
                },
                add: function (id) {
     
     
                    this.$emit('change-num', {
     
     
                        id: id,
                        type: 'add'
                    })
                },
                del: function (id) {
     
     
                    // 把id传递给父组件
                    // console.log(id);
                    this.$emit('cart-del', id);
                }
            },
        }
        var CarTotal = {
     
     
            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', {
     
     
            // 包含三个子属性  (局部属性)
            data: function () {
     
     
                return {
     
     
                    uname: '张三',
                    list: [
                        {
     
     
                            id: 1,
                            name: 'TCL彩电',
                            price: 1000,
                            num: 2,
                            img: 'img/a.jpg'
                        },
                        {
     
     
                            id: 2,
                            name: '机顶盒',
                            price: 2000,
                            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: '电视机',
                            price: 1000,
                            num: 1,
                            img: 'img/e.jpg'
                        }
                    ]
                }
            },
            template: `
            <div class="container">
                <cart-title :uname='uname'></cart-title>
                <cart-list :list='list' @change-num='changeNum($event)' @cart-del='delCart($event)'></cart-list>
                <cart-total :list='list'></cart-total>
            </div>
            `,
            components: {
     
     
                'cart-title': CarTitle,
                'cart-list': CarList,
                'cart-total': CarTotal,
            },
            methods: {
     
     
                changeNum: function (val) {
     
     
                    // 分为三种情况 : 输入域变更,加号变更,减号变更
                    if (val.type == 'change') {
     
     
                        // 根据子组件传递过来的数据,跟新list中对应的数据
                        this.list.some(item => {
     
     
                            if (item.id == val.id) {
     
     
                                item.num = val.num;
                                //     // 终止遍历
                                console.log(item.num)
                                return true;
                            }
                        })
                    } else if (val.type == 'sub') {
     
     
                        // 减一操作
                        this.list.some(item => {
     
     
                            if (item.id == val.id) {
     
     
                                item.num = 1;
                                //     // 终止遍历
                                return true;
                            }
                        })
                    } else if (val.type == 'add') {
     
     
                        // 加一操作
                        this.list.some(item => {
     
     
                            if (item.id == val.id) {
     
     
                                item.num += 1
                                //     // 终止遍历
                                return true;
                            }
                        })
                    }


                },
                delCart: function (id) {
     
     
                    // 根据id删除list中对应的数据
                    // 1.根据id 所对应数据的索引
                    var index = this.list.findIndex(item => {
     
     
                        return item.id == id;
                    });
                    // 2.根据索引删除对应的数据
                    this.list.splice(index, 1)
                }
            }
        })
        var vm = new Vue({
     
     
            el: '#app',
            data: {
     
     

            }
        })
    </script>

Self-motivation

There is no straight path in life. When you feel confused or lost, find a few movies full of positive energy, sit down and enjoy them quietly, to discover the real important things in life.

Guess you like

Origin blog.csdn.net/weixin_50001396/article/details/112869192