Vue购物车案例(重点)

本例采用组件化的方式实现业务需求

在这里插入图片描述
功能实现步骤:
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style type="text/css">
    .container {
    }
    .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;
    }
  </style>
</head>
<body>
  <div id="app">
    <div class="container">
      <my-cart></my-cart>
    </div>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    
    var CartTitle = {
    	props: ['uname'],
      template: `
        <div class="title">{{uname}}商品</div>
      `
    }
    var CartList = {
    	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)'>×</div>
          </div>
        </div>
      `,
      methods: {
      	changeNum: function (id, event) {
      		// console.log(id, event.target.value)
      		this.$emit('change-num', {
      			id: id,
      			type: 'change',
      			num: event.target.value
      		});
      	},
      	//一般不会在子组件中对props中的数据进行操作
      	del: function (id) {
      		//把id传递给父组件
      		this.$emit('cart-del', id);
      	},
      	sub: function (id) {
      		this.$emit('change-num', {
      			id: id,
      			type: 'sub'
      		});
      	},
      	add: function (id) {
      		this.$emit('change-num', {
      			id: id,
      			type: 'add'
      		});
      	}
      }
    }
    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',{
    	//一般用父组件中传递数据
    	data: function () {
    		return {
    			uname: '张三',
    			list: [{
    				id: 1,
    				name: 'TCL彩电',
    				price: 1000,
    				num: 1,
    				img: 'img/a.jpg'
    			}, {
    				id: 2,
    				name: '机顶盒',
    				price: 2000,
    				num: 1,
    				img: 'img/b.jpg'
    			}, {
    				id: 3,
    				name: '海尔冰箱',
    				price: 3000,
    				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 class='cart'>
          <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': CartTitle,
        'cart-list': CartList,
        'cart-total': CartTotal
      },
      methods: {
      	changeNum: function (val) {
      		//分为三种情况:输入与变更,加号变更,减号变更
      		if (val.type == 'change') {
      			//根据子组件传递过来的数据,更新list中对应的数据
      		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;
      				//终止遍历
      				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>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值