使用vuex让购物车联动

使用vuex让购物车联动_第1张图片
使用vuex让购物车联动_第2张图片
// 1.vuex点击加减触发函数提交仓库把我们请求的数据存到仓库
2.在仓库定义这个函数和对象 把我们存进去的数据存起来
// 3。在我们需要的页面拿出数据,然后循环就可以
// 4.当我们点击加号就触发函数然后在vuex对这个数据进行处理
// 5.对我们点进来的数据进行一个对右边的循环我们只要判断他是否》0,如果是大于0就push到新的数组
6.然后拿到新的数组渲染到购物车里面

这个是goods页面 就是整体的页面 asidelist: [], 是左边要渲染的数据定义
rightlist: [],就是右边要渲染的数组

<template>
 <div class="box">
   <!-- 左边 -->
   <div class="leftbox">
     <van-sidebar v-model="activeKey">
       <van-sidebar-item
         @click="onChange"
         v-for="(v,i) in asidelist"
         :title="v.name"
         :key="i"
         :id="'cate' +i"
       />
     </van-sidebar>
   </div>
   <!-- 右边 -->
   <div class="rightbox">
     <div>
       <div v-for="(v,i) in rightlist" :key="i" :id="'list' +i">
         <h3>{{v.name}}</h3>
         <van-card
           v-for="(v2,i2) in v.foods"
           :key="i2"
           :num="v2.num"
           :price="v2.price"
           :desc="v2.goodsDesc"
           :title="v2.name"
           :thumb="v2.imgUrl"
         >
           <template #tags>
             <van-tag plain type="danger">标签</van-tag>
             <van-tag plain type="danger">标签</van-tag>
           </template>
           <template #footer>
             <van-stepper
               @change="changecate"
               v-model="v2.num"
               theme="round"
               button-size="16"
               min="0"
               disable-input
             />
           </template>
         </van-card>
       </div>
     </div>
   </div>
 </div>
</template>
<script>
import { goodsList } from "@/api/account.api";
import BScroll from "@better-scroll/core";
import { mapState, mapMutations } from "vuex";
export default {
 data() {
   return {
     activeKey: 0,
     bs: {},
     bsr: {}
   };
 },
 // 点击左边跳转到右边的节点
 methods: {
   onChange(i) {
     this.bsr.scrollToElement("#list" + i, 300);
   },
   // 4.当我们点击加号就触发函数然后在vuex对这个数据进行处理

   changecate() {
     this.$store.commit("changecate");
   }
 },
 async created() {
   // 页面初始化的时候把他提交给仓库,提交仓库要用commit去提交仓库里面去定义一个数组
   console.log(this.rightlist);
   const res = await goodsList();
   res.data.data.forEach(v => {
     v.foods.forEach(v2 => {
       v2.num = 0;
     });
   });
   // 1.vuex点击加减触发函数提交仓库把我们请求的数据存到仓库
   this.$store.commit("addlist", res.data.data);
   // 获取两个左右边的父节点
   this.$nextTick(() => {
     this.bs = new BScroll(".leftbox", {
       probeType: 3,
       click: true
     });
     this.bsr = new BScroll(".rightbox", {
       probeType: 3,
       click: true
     });

     // 拿到我们初始值的右边所有商品列表把他放到一个数组里面
     let arr = [];
     this.rightlist.forEach((v, i) => {
       arr.push(
         document.querySelector("#list" + i).offsetTop -
           document.querySelector("#list0").offsetTop
       );
     });

     // 给右边添加滚动事件
     this.bsr.on("scroll", v => {
       let y = Math.abs(v.y);

       for (let i = 0; i < arr.length; i++) {
         if (y >= arr[i] && y < arr[i + 1]) {
           this.activeKey = i;
           this.bs.scrollToElement("#cate" + i, 300);
           break;
         }
       }
     });
   });
 },
 // 3。在我们需要的页面拿出数据,然后循环就可以
 computed: {
   
   ...mapState(["rightlist"]),

   asidelist() {
     return this.rightlist;
   }
 }
};
</script>
<style lang="scss" scoped>
h3 {
 color: black;
 font-size: 14px;
 height: 4vh;
 line-height: 4vh;
 width: 100%;
 background-color: rgb(218, 209, 209);
 text-indent: 1em;
}
.box {
 display: flex;
 flex-direction: row;
 .leftbox {
   // width: 100px;
   overflow-y: hidden;
   background-color: f7f8fa;
   margin-bottom: 50px;
 }
 .rightbox {
   height: 100vh;
   flex: 1;
   margin-bottom: 100px;
   overflow-y: hidden;
   // background-color: antiquewhite;
 }
}
</style>


...............................................
下面是vuex的代码
import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
 namespaced: true,
 state: {
   asidelist: [],
   rightlist: [],
 },

 mutations: {
   // 2.在仓库定义这个函数和对象  把我们存进去的数据存起来
   addlist(state, payload) {
     state.rightlist = payload;
   },
   // 5.对我们点进来的数据进行一个对右边的循环我们只要判断他是否》0,如果是大于0就push到新的数组
   changecate(state, payload) {
     let arr = [];
     state.rightlist.forEach((v) => {
       v.foods.forEach((v2) => {
         console.log(v2.num);
         if (v2.num > 0) {
           arr.push(v2);
           console.log(v2);
         }
       });
     });
     state.asidelist = arr;
   },
 },

 getters: {},

 actions: {},
 modules: {},
});
。。。。。。。。。。。。。。。。。。。。。。。。。。。



这个是我们下面 那个 购物车的代码
<template>
 <div class="cart">
   <!-- 购物车显示条 -->
   <div class="cartbar">
     <div class="concat">
       <van-icon name="smile-o" />联系商家
     </div>
     <div class="cartico">
       <van-badge v-if="asidelist.length>0" :content="asidelist.length">
         <van-icon name="shopping-cart" @click="show = !show" />
       </van-badge>
       <van-icon v-else name="shopping-cart" class="cartico-off" />

       <div class="price">
         <strong>{{tatol}}</strong>
         <span>{{asidelist.num}}</span>
       </div>
     </div>

     <div v-if="asidelist.length>0" class="delivery delivery-on">去结算</div>
     <div v-else class="delivery">20元起送</div>
   </div>

   <!-- 购物车列表 -->
   <van-popup v-model="show" round position="bottom" :style="{ height: '30%' }">
     <h1>新用户下单立减39</h1>
     <div class="clear">
       <span>购物车</span>
       <span>
         <van-icon name="delete-o" />清空购物车
       </span>
     </div>

     <ul>
       <li class="box" v-for="(v,i) in asidelist" :key="i">
         <span class="titeles">
           {{v.goodsDesc}}
         </span>
         <span>{{v.price*v.num}}</span>
         <van-stepper v-model="v.num" min="0" />
       </li>
     </ul>
   </van-popup>
 </div>
</template>
<script>
import { mapState } from "vuex";
import { reactive } from "vue";
export default {
 data() {
   return {
     show: false,
     value: 0
   };
 },
 created() {},
 computed: {
   ...mapState(["asidelist"]),
   tatol() {
     let sum = 0;
     this.asidelist.forEach(v => {
       sum += v.price * v.num;
     });
     return sum;
   }
 }
};
</script>

<style lang="scss" scoped>
.box {
 display: flex;
 justify-content: space-between;
 .titeles {
   display: block;
   overflow: hidden; //隐藏文字
   text-overflow: ellipsis; //显示 ...
   white-space: nowrap; //不换行
   width: 150px;
 }
}
.clear {
 display: flex;
 justify-content: space-between;
}
h1 {
 height: 30px;
 line-height: 30px;
 text-align: center;
 width: 100%;
 background-color: #ffcc30;
}
.cart {
 position: fixed;
 left: 0;
 bottom: 0;
}

.cartbar {
 z-index: 9999;
 position: fixed;
 // left: 2%;
 bottom: 10px;
 width: 88%;
 height: 70px;
 display: flex;
 color: #999;

 .concat {
   background: #222;
   width: 65px;
   font-size: 12px;
   text-align: center;
   padding-top: 10px;
   border-radius: 35px 0 0 35px;
   margin-right: 3px;

   .van-icon {
     font-size: 30px;
     display: block;
   }
 }

 .cartico {
   width: 1px;
   flex-grow: 1;
   background: #222;
   display: flex;

   .van-badge__wrapper {
     width: 50px;
     height: 50px;
     background: #ff0;
     font-size: 36px;
     line-height: 50px;
     text-align: center;
     border-radius: 30px;
     margin: 10px 7px;

     :deep(.van-badge--fixed) {
       top: 7px;
       right: 5px;
     }

     .van-icon {
       color: #000;
     }
   }

   .cartico-off {
     width: 56px;
     height: 56px;
     background: #333;
     font-size: 40px;
     line-height: 56px;
     text-align: center;
     border-radius: 30px;
     margin: 7px;
   }

   .price {
     width: 1px;
     flex-grow: 1;
     font-size: 12px;
     padding-top: 14px;

     strong {
       display: block;
       color: #fff;
       font-size: 20px;
     }
   }
 }

 .delivery {
   width: 70px;
   background: #222;
   font-size: 12px;
   line-height: 70px;
   border-radius: 0 35px 35px 0;
   text-align: center;
 }

 .delivery-on {
   background: #ff0;
   font-size: 14px;
   color: #000;
 }
}
</style>

你可能感兴趣的:(javascript,前端,开发语言)