Vuex仿饿了么购物车功能

饿了么购物车功能

今天通过Vuex完成了基本的购物车功能,对Vuex的store和mutation有了进一步认识。

实现购物车所需要的数据

store作为可以全局访问的数据仓库,满足了我们在任意一个组件使用数据的需求。所以,我预先在store里声明三个变量:f_count数组类型,cart_list数组类型,cart_item 整数类型,以便在全局调用。

  1. 数字类型数组 f_count ,存储购物车内单个商品的数量;
  2. 数字类型数组 cart_list,存储与商品数量对应的商品编号,即fid;
  3. 整数 cart_item,购物车里商品的总数量;
    代码如下:
   	 state:{
   		 f_count:[],
   		 cart_list:[],
   		 cart_item:0
   	}

添加和删除商品方法

main.js中

mutations:{
    //操作共享数据,只能用mutations提供的方法
    //如果组件要使用mutations定义的方法,只能使用 this.$store.commit('函数名');
    increment(state,i){ 
      //当前商品fid,在cart_list中的索引
      var tmp_index = state.cart_list.indexOf(i.fid);
      
      if(!state.cart_list.includes(i.fid)){//如果商品未存在于cart_list,
        //则将商品对象加入cart_list
        //并且在f_count对应索引位置添加值
        state.f_count.push(1);
        state.cart_list.push(i.fid);
        
      }else{
        //如果商品已存在,则把f_count对应索引位置的值+1
        state.f_count[tmp_index]++;
      }      
    },
    subtract(state,i){
      var tmp_index = state.cart_list.indexOf(i.fid);
      state.f_count[tmp_index]--;
      if(state.f_count[tmp_index]==0){
        //删除商品对象在f_count和cart_list中对应的值
        state.f_count.splice(tmp_index,1);
        state.cart_list.splice(tmp_index,1);
      }
    },
    //计算购物车内商品总件数 cart_item
    item_sum(state){
      if(state.f_count.length==1){
        state.cart_item = state.f_count[0];
      }else{
        state.cart_item =0;
        for(var n in state.f_count){
          state.cart_item+=state.f_count[n]
        }
      }
    }
  },
   
}

操作购物车组件 counter.vue

//模板部分
<template>
    <div class='active_btn'>
        <transition name="fade">
            <div class='del_cart' v-show='item.count'><div  @click='delCart(item)'>-</div></div>
        </transition>
        <span v-show="item.count">{{item.count}}</span>
        <div class='add_cart'><div @click="addCart(item)">+</div></div>
    </div>
</template>
import Vue from 'vue';

export default {
    data(){
        return{
        }
    },
    props:['item'],//从父组件接收传值
	methods:{
	        addCart(item){
	            this.$store.commit('increment',item);    //改变状态里的f_count,购物车内商品数量
	            
	            //记录单个商品的数量和值
	            if(!item.count){
	                Vue.set(item,'count',1);
	            }
	            else{
	                item.count++;
	            }
	            this.i_count=item.count;
	            this.$store.commit("item_sum");     //计算购物车内商品总件数
	        },
	        delCart(item){
	            this.$store.commit('subtract',item);
	            item.count--;
	            this.$store.commit("item_sum");
	        },
	    }
	}

点单页面 shopDetails.vue
由于counter.vue是作为子组件嵌套在shopDetails.vue中的,所以必要的传值不可少

<dl>
     <dt>
         <strong class='sort_tag'>热销</strong>
         <span>大家都喜欢1</span>
     </dt>
     <dd v-for='i in foodlist' :key='i.fid'>
         <div class='food_show'>
             <span class="food_img" > <img :src="i.f_img_sm" alt=""></span>
             <section class='food_info'>
                 <p class='food_name'>{{i.f_name}}</p>
                 <p class='food_sub'>{{i.summary}}</p>
                 <p class='food_sub'><span>月售{{i.sold_count}}份</span><span>好评率99%</span></p>
                 <div class='food_act'>
                     <span>每单限{{i.max_p}}份优惠</span>
                     <span class='rest'>剩{{i.rest_count}}份</span>
                 </div>
                 <section>
                     <span class='price'>
                         <span>{{i.min_p}}</span>
                         <span class='sale_base'></span>
                         <del class='old_price'>{{i.old_price}}</del>
                     </span>
                     <!-- <div class='active_btn'>
                         <div class='del_cart'><a v-show='i.count' @click='delCart(i)'>-</a></div>
                         <span>{{i.count}}</span>
                         <div class='add_cart'><a @click="addCart(i)">+</a></div>
                     </div> -->
                     <counter :item='i'></counter>
                 </section>
             </section>
         </div>
     </dd>
</dl>
...
<!-- 购物车默认收起状态 -->
<div class='cart'>
    <div class='cart_img my_car'>
    		<div v-show='cart_item'>
    			<span>{{cart_item}}</span>
    		</div>
    </div>
    <div class='price_fee'>
        <p class='order_item' v-if='!cart_item'>未选购商品</p>
        <p v-else='cart_item.length'>{{cart_item}}</p>
        <p class='fee'>另需配送费3.8元</p>
    </div>
    <a class='pay_order'>¥20起送</a>
</div>

计算属性获取store中cart_item的值

computed:{
        cart_item(){
            return this.$store.state.cart_item;
        }
    },

最后实现效果,当添加商品时,单个商品数量,和商品总数量会相应改变。
在这里插入图片描述

明天计划:
1.购物车展开详情:商品单价,商品数量,总计,折扣
2.商品详情页:商品大图,商品描述,价格,留言等

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值