[Vue]购物车案例(五)

196 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

购物车案例——实现组件更新数据功能【下】

  • 子组件通过一个标识符来标记对应的用户点击 +- 或者输入框输入的内容;
  • 父组件拿到标识符更新对应的组件;

html 代码结构

 <div id="app">
    <div class="container">
      <!-- 把组件渲染到页面上 --> 
      <my-cart></my-cart>
    </div>
  </div>

js 代码结构

  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
      code in here
  </script>

1、实现组件更新数据功能【下】

1.1 +- 按钮绑定事件

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">
			  # 1.  + - 按钮绑定事件 
              <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>
      `,

1.2 数量的增加和减少通过父组件来计算

  • 每次都是加1减1 不需要传递数量。
  • 父组件需要一个类型来判断 是 加1 还是减1 ,以及是输入框输入的数据。我们通过type标识符来标记不同的操作。
 methods: {
        changeNum: function(id, event){
          this.$emit('change-num', {
            id: id,
            type: 'change',
            num: event.target.value
          });
        },
        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传递给父组件
          this.$emit('cart-del', id);
        }
      }
    }
     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: 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'
          }]
        }
      },

1.3 父组件通过事件监听,接收子组件的数据。

 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
      },

1.4 分为三种情况:输入框变更、加号变更、减号变更

根据子组件传递过来的数据,跟新list中对应的数据。

      methods: {
        changeNum: function(val) {
          if(val.type=='change') {
            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;
              }
            });
          }
        }
      }
    });
    var vm = new Vue({
      el: '#app',
      data: {

      }
    });