vue组件化购物车

第一步建立一个组件的布局

在这里插入图片描述

上面部分划为3部分的组件块,第一部分标题,第二部分内容,第三部分结算

实现步骤

  • 实现整体布局和样式效果
  • 划分独立的功能组件
  • 组合所有的子组件形成整体结构
  • 逐个实现各个组件功能

具体代码如下

<body>
<div id="app">
    <div class="container">
        <my-cart></my-cart>
    </div>
</div>
<script src="../../js/vue.js"></script>
<script type="text/javascript">

    var CartTitle = {
        template: `
        <div class="title">我的商品</div>
      `
    };
    var CartList = {
        template: `
        <div>
          <div class="item">
            <img src="../img/a.jpg"/>
            <div class="name"></div>
            <div class="change">
              <a href="">-</a>
              <input type="text" class="num" />
              <a href="">+</a>
            </div>
            <div class="del">×</div>
          </div>
          <div class="item">
            <img src="../img/b.jpg"/>
            <div class="name"></div>
            <div class="change">
              <a href="">-</a>
              <input type="text" class="num" />
              <a href="">+</a>
            </div>
            <div class="del">×</div>
          </div>
          <div class="item">
            <img src="../img/c.jpg"/>
            <div class="name"></div>
            <div class="change">
              <a href="">-</a>
              <input type="text" class="num" />
              <a href="">+</a>
            </div>
            <div class="del">×</div>
          </div>
          <div class="item">
            <img src="../img/d.jpg"/>
            <div class="name"></div>
            <div class="change">
              <a href="">-</a>
              <input type="text" class="num" />
              <a href="">+</a>
            </div>
            <div class="del">×</div>
          </div>
          <div class="item">
            <img src="img/e.jpg"/>
            <div class="name"></div>
            <div class="change">
              <a href="">-</a>
              <input type="text" class="num" />
              <a href="">+</a>
            </div>
            <div class="del">×</div>
          </div>
        </div>
      `
    }
    var CartTotal = {
        template: `
        <div class="total">
          <span>总价:123</span>
          <button>结算</button>
        </div>
      `
    }
    Vue.component('my-cart',{
        template: `
        <div class='cart'>
          <cart-title></cart-title>
          <cart-list></cart-list>
          <cart-total></cart-total>
        </div>
      `,
        components: {
            'cart-title': CartTitle,
            'cart-list': CartList,
            'cart-total': CartTotal
        }
    });
    var vm = new Vue({
        el: '#app',
        data: {

        }
    });

</script>
</body>

css样式

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

第二步利用组件化的思想实现以下功能

  • 实现标题的显示
  • 实现数据的显示
  • 删除数据功能
  • 实现加减
  • 更新数量num,失去焦点的时候改变数量(同时价格也改变)

1.实现标题的显示

在父组件设置一些数据

 Vue.component('my-cart',{
    
    
        data:function(){
    
    
            return{
    
    
                name:'张三',//这是标题名字

                list:[
                    {
    
    id:1,name:'手机',peice:1200,num:2,img:'../img/a.jpg'},
                    {
    
    id:2,name:'电脑',peice:11200,num:4,img:'../img/b.jpg'},
                    {
    
    id:3,name:'机顶盒',peice:200,num:5,img:'../img/c.jpg'},
                    {
    
    id:4,name:'1手机',peice:1200,num:1,img:'../img/d.jpg'},
                    {
    
    id:5,name:'海尔',peice:1800,num:3,img:'../img/e.jpg'},

                    ]
            }
        },

然后绑定

<div class='cart'>
          <cart-title :name="name"></cart-title>

子组件接受数据

 var CartTitle = {
    
    
        props:['name'],
        template: `
        <div class="title">{
     
     {name}}的商品</div>
      `
    };

2.实现标数据的显示

在CartList子组件中利用v-for遍历list的数据(切记要绑定数据)

var CartList = {
    
    
        props:['list'],
        template: `
        <div>
          <div  v-for="item in list" :key="item.id" class="item">
            <img :src="item.img"/>
            <div class="name">{
    
    {
    
    item.name}}</div>

3.实现删除数据

首先找到每一项的索引,根据索引删除

 delcart(id) {
    
    
                //找到id的索引
                var index=this.list.findIndex(item=>{
    
    
                    return item.id == id;
                })
                this.list.splice(index,1);
            },

4。更新数量num和实现加减

首先在子组件中定义,计算结果在父组件中运算

gen(val){
             this.list.some(item=>{
                 if (item.id == val.id) {
                    item.num=val.num ;
                     return true;
                 }
                 //终止遍历

             })
            },
            sub(val){
                this.list.some(item=>{
                    if (item.id == val.id) {
                        item.num -=1;
                        return true;
                    }
                    //终止遍历

                })
            },
            add(val){
                this.list.some(item=>{
                    if (item.id == val.id) {
                        item.num +=1;
                        return true;
                    }
                    //终止遍历

                })
            }

最终效果:
在这里插入图片描述
整合代码:

<div id="app">
    <div class="container">
        <my-cart></my-cart>
    </div>
</div>
<script src="../../js/vue.js"></script>
<script type="text/javascript">

    var CartTitle = {
        props:['name'],
        template: `
        <div class="title">{
   
   {name}}的商品</div>
      `
    };
    var CartList = {
        props:['list'],
        template: `
        <div>
          <div  v-for="item in list" :key="item.id" class="item">
            <img :src="item.img"/>
            <div class="name">{
   
   {item.name}}</div>
                <p>价格{
   
   {item.peice}}</p>
            <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>

      `,

        methods:{
            del(id){
                this.$emit('cart-del',id);//把id给父组件
           //应该把处理结果给父组件
            },
            changenum(id,event){
                this.$emit('cart-changenum',{
                    id:id,
                    num:event.target.value
                })

            },
            sub(id){
                this.$emit('cart-sub',{
                    id:id
                });//把id给父组件
            },
            add(id){
                this.$emit('cart-add',{
                    id:id
                });//把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.peice*item.num;
               });
               return t;
            }
        }
    }
    Vue.component('my-cart',{
        data:function(){
            return{
                name:'张三',

                list:[
                    {id:1,name:'手机',peice:1200,num:2,img:'../img/a.jpg'},
                    {id:2,name:'电脑',peice:11200,num:4,img:'../img/b.jpg'},
                    {id:3,name:'机顶盒',peice:200,num:5,img:'../img/c.jpg'},
                    {id:4,name:'1手机',peice:1200,num:1,img:'../img/d.jpg'},
                    {id:5,name:'海尔',peice:1800,num:3,img:'../img/e.jpg'},

                    ]
            }
        },
        template: `
        <div class='cart'>
          <cart-title :name="name"></cart-title>
          <cart-list :list="list" @cart-del="delcart($event)" @cart-changenum="gen($event)" @cart-sub="sub($event)"
          @cart-add="add($event)"
          ></cart-list>
          <cart-total :list="list"></cart-total>
        </div>
      `,
        components: {
            'cart-title': CartTitle,
            'cart-list': CartList,
            'cart-total': CartTotal
        },
        methods: {
            delcart(id) {
                //找到id的索引
                var index=this.list.findIndex(item=>{
                    return item.id == id;
                })
                this.list.splice(index,1);
            },
            gen(val){
             this.list.some(item=>{
                 if (item.id == val.id) {
                    item.num=val.num ;
                     return true;
                 }
                 //终止遍历

             })
            },
            sub(val){
                this.list.some(item=>{
                    if (item.id == val.id) {
                        item.num -=1;
                        return true;
                    }
                    //终止遍历

                })
            },
            add(val){
                this.list.some(item=>{
                    if (item.id == val.id) {
                        item.num +=1;
                        return true;
                    }
                    //终止遍历

                })
            }
        }
    });
    var vm = new Vue({
        el: '#app',
        data: {

        }
    });

</script>

感觉组件化这样写比较麻烦,但是遇到比较大的东西时可能比较复杂吧,
这个案例的知识点有

(1)父组件向子组件传值(props传递数据原则:单向数据流)

首先在父组件定义数据和绑定数据
然后子组件利用 props传递数据获取父组件的数据

(2)子组件向父组件传值

 子组件通过$emit把数据给父组件
 父组件通过$event数据

(3)event.target.value代表最新的值

猜你喜欢

转载自blog.csdn.net/qq_41309350/article/details/114238313
今日推荐