Vue.js之简单购物车实现

这篇文章详细描述了一个使用Vue.js构建的购物车应用,包括商品列表、数量控制(增加、减少和编辑)以及总价计算的功能,通过组件化开发实现复用和管理
摘要由CSDN通过智能技术生成

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
	<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.5/vue.js"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        
        li {
            list-style: none;
        }
        
        input {
            outline: none;
            width: 30px;
            height: 30px;
            margin: 0 5px;
        }
        
        button {
            width: 20px;
            font-size: 20px;
        }
        
        #cart {
            width: 500px;
            margin: 50px auto;
        }
        
        .title {
            background-color: #A2C8D5;
            text-align: center;
            height: 50px;
            line-height: 50px;
        }
        
        li {
            font-size: 20px;
            height: 70px;
            line-height: 70px;
            background-color: #E9E9E9;
            padding: 0 10px;
            border-bottom: 2px solid #C5CDCB;
        }
        
        li span:first-of-type {
            float: left;
        }
        
        li span:last-of-type {
            float: right;
            margin-left: 20px;
            color: #D61615;
            font-size: 60px;
            cursor: pointer;
            width: 70px;
            text-align: center;
        }
        
        li span:last-of-type:hover {
            background-color: #f7b709;
        }
        
        li .btn {
            float: right;
        }
        
        .footer {
            height: 70px;
            background-color: #E8C04A;
            line-height: 70px;
            text-align: center;
            position: relative;
        }
        
        .footer>span:first-child {
            color: red;
            font-size: 25px;
        }
        
        .footer>span:last-child {
            position: absolute;
            top: 50%;
            right: 40px;
            transform: translateY(-50%);
            width: 80px;
            height: 40px;
            background-color: #CC4F45;
            line-height: 40px;
        }
    </style>
</head>

<body>
    <div id="app">
        <my-cart></my-cart>
    </div>
    <script>
        // 购物车标题子组件
        let cartTitle = {
                props: ['uname'],
                template: ` <div class="title">{{uname}}的商品</div>`
            }
            // 购物车商品列表子组件
        let cartList = {
                props: ['list'],
                template: `<ul>
                <li :key="item.id" v-for="(item,index) in list"><span>{{item.name+' 价格: '+item.price}}</span><span @click="del(index)">×</span>
                    <div class="btn"><button @click="sub(index)">-</button><input type="text" :value="item.num" @blur="changeNum(index,$event)"><button @click="add(index)">+</button></div>
                </li>
            </ul>`,
                methods: {
                    del(i) {
                        this.$emit('cart-del', i);

                    },
                    changeNum(i, e) {
                        this.$emit('goods-num', {
                            id: i,
                            num: e.target.value,
                            type: 'inputChange'
                        })
                    },
                    sub(i) {
                        this.$emit('goods-num', {
                            id: i,
                            type: 'subChange'
                        })
                    },
                    add(i) {
                        this.$emit('goods-num', {
                            id: i,
                            type: 'addChange'
                        })
                    }
                }
            }
            // 购物车总价子组件
        let cartTotal = {
                props: ['list'],
                template: ` <div class="footer">
                <span>总价:<span>{{sum}}</span></span>
                <span>结算</span>
            </div>`,
                computed: {
                    sum() {
                        let sum = this.list.reduce((total, e) => {
                            return total + e.price * e.num;
                        }, 0)
                        return sum;
                    }
                }
            }
            // 购物车父组件
        Vue.component('my-cart', {
            data: function() {
                return {
                    uname: '张三',
                    list: [{
                        id: 1,
                        name: '手机',
                        price: 6000,
                        num: 1
                    }, {
                        id: 2,
                        name: '电脑',
                        price: 8000,
                        num: 1
                    }, {
                        id: 3,
                        name: '耳机',
                        price: 200,
                        num: 5
                    }, {
                        id: 4,
                        name: '充电宝',
                        price: 100,
                        num: 10
                    }]
                }
            },
            template: `<div id="cart">
                <cart-title :uname="uname"></cart-title>
                <cart-list :list="list" @cart-del="del($event)"  @goods-num="changeNum($event)"></cart-list>
                <cart-total :list="list"></cart-total>
                </div>`,
            components: {
                'cart-title': cartTitle,
                'cart-list': cartList,
                'cart-total': cartTotal
            },
            methods: {
                del(i) {
                    this.list.splice(i, 1);
                },
                changeNum(e) {
                    if (e.type == 'inputChange') {
                        this.list[e.id].num = e.num;
                    } else if (e.type == 'addChange') {
                        this.list[e.id].num++;
                    } else {
                        if (this.list[e.id].num == 0) {
                            this.list[e.id].num = 0;
                        } else {
                            this.list[e.id].num--;
                        }
                    }
                }
            }
        })


        let vu = new Vue({
            el: '#app',
            data: {}
        })
    </script>
</body>

</html>

https://juejin.cn/post/7148754381645545502

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
	<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.5/vue.js"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        
        li {
            list-style: none;
        }
        
        input {
            outline: none;
            width: 30px;
            height: 30px;
            margin: 0 5px;
        }
        
        button {
            width: 20px;
            font-size: 20px;
        }
        
        #cart {
            width: 500px;
            margin: 50px auto;
        }
        
        li {
            font-size: 20px;
            height: 70px;
            line-height: 70px;
            background-color: #E9E9E9;
            padding: 0 10px;
            border-bottom: 2px solid #C5CDCB;
        }
        
        li span:first-of-type {
            float: left;
        }
        
        li span:last-of-type {
            float: right;
            margin-left: 20px;
            color: #D61615;
            font-size: 60px;
            cursor: pointer;
            width: 70px;
            text-align: center;
        }
        
        li span:last-of-type:hover {
            background-color: #f7b709;
        }
        
        li .btn {
            float: right;
        }
        
        .footer {
            height: 70px;
            background-color: #E8C04A;
            line-height: 70px;
            text-align: center;
            position: relative;
        }
        
        .footer>span:first-child {
            color: red;
            font-size: 25px;
        }
        
        .footer>span:last-child {
            position: absolute;
            top: 50%;
            right: 40px;
            transform: translateY(-50%);
            width: 80px;
            height: 40px;
            background-color: #CC4F45;
            line-height: 40px;
        }
    </style>
</head>

<body>
    <div id="app">
        <my-cart></my-cart>
    </div>
    <script>
            // 购物车商品列表子组件
        let cartList = {
                props: ['list'],
                template: `<ul>
                <li :key="item.id" v-for="(item,index) in list"><span>{{item.name+' 价格: '+item.price}}</span><span @click="del(index)">×</span>
                    <div class="btn"><button @click="sub(index)">-</button><input type="text" :value="item.num" @blur="changeNum(index,$event)"><button @click="add(index)">+</button></div>
                </li>
            </ul>`,
                methods: {
                    del(i) {
                        this.$emit('cart-del', i);

                    },
                    changeNum(i, e) {
                        this.$emit('goods-num', {
                            id: i,
                            num: e.target.value,
                            type: 'inputChange'
                        })
                    },
                    sub(i) {
                        this.$emit('goods-num', {
                            id: i,
                            type: 'subChange'
                        })
                    },
                    add(i) {
                        this.$emit('goods-num', {
                            id: i,
                            type: 'addChange'
                        })
                    }
                }
            }
            // 购物车总价子组件
        let cartTotal = {
                props: ['list'],
                template: ` <div class="footer">
                <span>总价:<span>{{sum}}</span></span>
                <span>结算</span>
            </div>`,
                computed: {
                    sum() {
                        let sum = this.list.reduce((total, e) => {
                            return total + e.price * e.num;
                        }, 0)
                        return sum;
                    }
                }
            }
            // 购物车父组件
        Vue.component('my-cart', {
            data: function() {
                return {
                    list: [{
                        id: 1,
                        name: '手机',
                        price: 6000,
                        num: 1
                    }, {
                        id: 2,
                        name: '电脑',
                        price: 8000,
                        num: 1
                    }, {
                        id: 3,
                        name: '耳机',
                        price: 200,
                        num: 5
                    }, {
                        id: 4,
                        name: '充电宝',
                        price: 100,
                        num: 10
                    }]
                }
            },
            template: `<div id="cart">
                <cart-list :list="list" @cart-del="del($event)"  @goods-num="changeNum($event)"></cart-list>
                <cart-total :list="list"></cart-total>
                </div>`,
            components: {
                'cart-list': cartList,
                'cart-total': cartTotal
            },
            methods: {
                del(i) {
                    this.list.splice(i, 1);
                },
                changeNum(e) {
                    if (e.type == 'inputChange') {
                        this.list[e.id].num = e.num;
                    } else if (e.type == 'addChange') {
                        this.list[e.id].num++;
                    } else {
                        if (this.list[e.id].num == 0) {
                            this.list[e.id].num = 0;
                        } else {
                            this.list[e.id].num--;
                        }
                    }
                }
            }
        })


        let vu = new Vue({
            el: '#app',
            data: {}
        })
    </script>
</body>

</html>
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.5/vue.js"></script>
    <title>购物车案例</title>
    <style>
      .cart {
        width: 300px;
        margin: auto;
      }
      .cart .title {
        background-color: rgb(252, 11, 240);
        height: 40px;
        line-height: 40px;
        color: white;
        text-align: center;
      }
      .cart .item {
        /* 子绝对位置父相对位置 */
        position: relative;
        height: 55px;
        line-height: 55px;
        border-top: 1px dashed rgb(116, 21, 103);
      }
      .cart .item:first-child {
        border-top: none;
      }
      .cart .item img {
        width: 45px;
        height: 45px;
        margin: 5px;
      }
      .cart .item .name {
        position: absolute;
        left: 55px;
        top: 0;
        font-size: 16px;
      }
      .cart .item .change {
        position: absolute;
        top: 0;
        right: 50px;
        width: 100px;
      }
      .cart .item .change a {
        font-size: 20px;
        text-decoration: none;
        display: inline-block;
        height: 25px;
        width: 20px;
        line-height: 25px;
        background-color: lightgray;
        text-align: center;
        vertical-align: middle;
      }
      .cart .item .change .num {
        width: 40px;
        height: 25px;
      }
      .cart .item .del {
        position: absolute;
        top: 0;
        right: 0;
        width: 50px;
        font-size: 28px;
        text-align: center;
        color: red;
      }
      .cart .total {
        background-color: rgb(116, 21, 103);
        height: 50px;
        line-height: 50px;
        text-align: right;
        color: white;
      }
      .cart .total .account {
        margin: 0 10px;
      }
    </style>
  </head>
  <body>
    <div id="app">
        <!--将组件渲染到页面上,定义组件名时,如果是用的驼峰命名,页面这里的组件名用短横线连接两个小写单词。-->
      <my-cart></my-cart>
    </div>
    <script>
      const cartTitle = {
          //
        props: ["uname"],
        //注意:template创建的模板有且只有一个根元素。
        template: `
            <div class="title">{{uname}}的商品</div> `,
      };

      const cartList = {
        props: ["list"],
        //click.prevent阻止默认行为
        template: `
            <div>
                <div class="item" v-for="ii in list" :key="ii.id">
                    <img :src="ii.img">
                    <div class="name">{{ii.name}}</div>
                    <div class="change">
                      
                        <a href="" @click.prevent="$emit('change-num',{id:ii.id,type:'sub'})">-</a>
                        <input type="text" class="num" v-model="ii.num" @blur="$emit('change-num',{id:ii.id,type:'edit',num:$event.target.value})">
                        <a href="" @click.prevent="$emit('change-num',{id:ii.id,type:'add'})">+</a>
                    </div>
                    <div class="del" @click="$emit('del',ii.id)">X</div>
                </div>
            </div>
            `,
      };

      const cartTotal = {
        props: ["list"],
        template: `
            <div class="total">
              <span>总价:{{total}}</span>
              <input type="button" value="结算" class="account">
            </div>
            `,
            //计算属性,进行累加和
        computed: {
          total() {
            return this.list.reduce((sum, item) => {
              return item.num * item.price + sum;
            }, 0);
          },
        },
      };
      //定义全局组件
      Vue.component("myCart", {
        template: `
            <div class="cart">
                <cart-title :uname="uname"></cart-title>
                <cart-list :list="goods" @change-num='changeNum' @del="delItem"></cart-list>
                <cart-total :list="goods"></cart-total>
            </div>
            `,
        components: {
          cartTitle,
          cartList,
          cartTotal,
        },
        methods:{
          delItem(id){
            console.log("del");
            this.goods=this.goods.filter(item=>{
              return item.id!==id;
            })
          },
          //先找到id,
          changeNum(arg){
            console.log(arg);
            let id=arg.id;
            let type=arg.type;
            if(type==='add'){
              this.goods.some(item=>{
                if(item.id===id){
                  item.num++;
                  return true;
                }
              })
              
            }else if(type==='sub'){
              this.goods.some(item=>{
                if(item.id===id){
                  if(item.num>=2){
                    item.num--;
                  }else{
                    //删除
                    this.delItem(id);
                  }
                  return true;
                }
              })
            }else if(type==='edit'){
              this.goods.some(item=>{
                if(item.id===id){
                  item.num=arg.num;
                  return true;
                }
              })
            }
          }
        },
        data() {
          return {
            uname: "张三",
            goods: [
              {
                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",
              },
            ],
          };
        },
      });
      const vm = new Vue({
        el: "#app",
      });
    </script>
  </body>
</html>

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱吃java的羊儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值