当前位置: 代码迷 >> 综合 >> Vuex的使用 实现添加购物车,购物车商品数量加减 以及 IScroll 和 lazyload的使用
  详细解决方案

Vuex的使用 实现添加购物车,购物车商品数量加减 以及 IScroll 和 lazyload的使用

热度:36   发布时间:2023-11-21 09:41:03.0

知识点:

  • IScroll 实现拖动下滑效果
  • lazyload实现懒加载效果
  • Vuex 的使用
  • 加入购物车,购物车的数量加减

商品页面 goods/Index.vue组件

显示所有商品列表,用 IScroll 实现拖动下滑效果, 用 lazyload 实现懒加载效果

<template><div class="box" @touchmove.prevent><ul ><li> goods {
   {type}} </li><li is="Item" v-for="item of arr" :key="item._id" :item="item"></li></ul></div>
</template><script>
import Item from "./Item.vue"
import { host } from "../../const"
import IScroll from 'iscroll'
import lazy from '../../directives/lazyload'export default {data(){return {type : "没有分类",arr : []}},components:{Item},mounted(){// 通过$emit事件在子组件中自定义事件,通过操作子组件中的事件,向父组件传递参数;this.$eventbus.$emit("setTitle", "商品")this.type = this.$route.params.type;let url = host+"/goods?_type=_type&_word="+this.type+"&_limit=10&_page=1";this.$axios.get(url).then(res=>{this.arr = res.data.result;})var that = this;var boxH = document.querySelector(".box").offsetHeight;var myIScroll;setTimeout(function(){myIScroll = new IScroll(".box");myIScroll.on('scrollEnd', function () {if( this.y*-1 == document.querySelector(".box>ul").offsetHeight-document.querySelector(".box").offsetHeight ){//console.log('到底啦')}else if( this.y == 0 ){//console.log('到头啦')}else{//console.log(this.y)}lazy.show( boxH, this.y );})lazy.show( boxH, 0 );}, 1000)           }
}
</script><style lang="scss">
.box{overflow: hidden;
}
.box>ul{background: #b6e4c5
}
</style>

商品详情页面组件 goods/Detail.vue

<template><div class="detail"><h1>{
   { title }}</h1><img :src="img"><div v-html="content"></div></div>
</template><script>
import { host } from "../../const";export default {data(){return {title: "",img: "",content: ""}},props:[],mounted(){let { id } = this.$route.query;let url = host+"/goods?_type=_id&_word="+id;this.$axios.get(url).then(res=>{var obj = res.data.result[0];this.title = obj.title;this.img = host+"/uploads/"+obj.img;this.content = obj.content;})}
}
</script><style lang="scss">
.detail{}
.detail h1{font-size: 14px;
}
.detail img{width:200px;
}
</style>

商品列表页 goods/Item组件

实现点击加入购物车功能

<template><li class="item"><router-link :to="'/detail?id='+item._id"><img :src="initimg" v-lazyload="host+'/uploads/'+item.img"><br>{
   { item.title }}{
   { item.price | money("元") }}查看详情</router-link>//在商品列表页添加一个按钮,点击时添加一个事件add();<button @click="add(item)"><font class="fa fa-shopping-cart"></font>添加到购物车</button></li>
</template><script>
import { host } from "../../const";
import { mapActions } from "vuex";
import timg from "../../assets/images/timg.gif";var f = {filters:{money( val, d ){return val+d;}}
}export default {data(){return {host:host,initimg:timg//"/src/assets/images/timg.gif"}},props:["item"],mixins:[f],mounted(){//console.log( host )},methods:{add(item){//console.log( 'item:', item )// vue希望我们在组件中,调用actions中的方法,actions中再调用mutation中的方法,mutation中改变state数据//this.$store.commit("addCart", item);// 用commit调用vuex中mutations中的方法//this.$store.dispatch("addCart", item);// 用dispatch调用vuex中actions中的方法item.n = 1;this.addCart(item); // 先用map把actions中的addCart函数合并到methods中,然后调用它this.$toast("商品添加成功")},...mapActions(["addCart"])}
}
</script><style lang="scss">
.item{padding-bottom: 20px;
}
.item img{width: 2rem;height: 2rem;border: 1px solid gray;border-radius: 5px;
}
</style>

购物车页面 buycar/Index.vue 组件

<template><div class="buycar" @touchmove.prevent><ul><li v-for="(item, ind) of goodslist" :key="ind"><img :src="host+'/uploads/'+item.img" />{
   { item.title }}<button @click="update(item, -1)"><font class="fa fa-minus-square-o"></font></button>{
   { item.num }}<button @click="update(item, 1)"><font class="fa fa-plus-square-o"></font></button></li></ul></div>
</template><script>
import { host } from '../../const';
import IScroll from 'iscroll'
import { mapActions } from 'vuex';export default {data(){return {host : ""}},computed:{goodslist(){// 获取 store 中的 state 中的 goodslist 数据return this.$store.state.goodslist;}},methods:{update(item, n){item.n = n; // 决定是+1还是-1this.addCart(item);},...mapActions(["addCart"])},mounted(){this.$eventbus.$emit("setTitle", "购物车");this.host = host;var myIScroll;setTimeout(function(){myIScroll = new IScroll(".buycar");}, 0)}
}
</script><style lang="scss">
.buycar{overflow: hidden;
}
.buycar>ul{background: #b6e4c5
}
.buycar img{width:3rem;height:3rem;
}
</style>

Vuex 仓库 store/index.js

import Vue from 'vue';
import Vuex from 'vuex';    // npm i vuex
Vue.use(Vuex);// vuex 状态管理
// 创建一个仓库,作用是存储那些被共享出来的数据(数据就是状态)
const store = new Vuex.Store({state:{goodslist : JSON.parse(localStorage.getItem("goodslist")||"[]")      // 保存那些添加到购物车中的商品},mutations:{// 只是做最后一个state的改变addCart(state, payload){// state 表示 store 中的 state,可以直接操作// payload 表示有效载荷,表示别人使用addCart函数时,传进来的数据state.goodslist.push(payload);//console.log( '将商品保存到购物车中了 payload:', payload )},updateNum(state, payload){state.goodslist[payload.ind].num += payload.n;  // 不会让视图层自动更新           state.goodslist = JSON.parse(JSON.stringify(state.goodslist)); // 让视图自动更新//console.log( "updateNum:", state.goodslist[payload.ind] )},delCart(state, payload){state.goodslist.splice(payload, 1);   //根据下标,删除数组中的成员,然后视图自动更新//console.log( "delCart:", state.goodslist )    }},actions:{// 所有的业务逻辑的代码,及异步的代码,都应该写在actions中addCart(context, payload){// 判断要添加的这个商品,是否已经保存在goodslist中var ind = context.state.goodslist.findIndex(obj=>obj._id===payload._id);            if( ind > -1 ){// 如果已经存在,则数量进行变更if( payload.n == 1 ){// 如果是加法context.commit("updateNum", {ind, n:payload.n})}else{ // 减法var i = context.state.goodslist[ind].num-1;if( i == 0 ){// 删除商品context.commit("delCart", ind)}else{// 数量减少context.commit("updateNum", {ind, n:payload.n})}}                }else{       // 如果不存在,则直接追加var obj = payload;obj.num = 1;context.commit("addCart", obj) // 在actions中调用mutations中的方法}}}
})// 订阅(监听),只要数据发生变化,则回调函数就会被触发
store.subscribe(function(mutations, state){localStorage.setItem("goodslist", JSON.stringify(state.goodslist))
})export default store;

购物车梳理

  1. store/index.js Vuex 管理页面

const store = new Vuex.Store({
state:{
存储数据
goodslist:[] 保存到购物车的商品数据
},
mutations:{
改变数据的方法,在 mutations 不应该写逻辑代码,异步代码,只写逻辑赋值的代码
addCart() 添加
updateNum() 更新商品数量
delCart() 删除商品
},
actions:{
所有的业务逻辑的代码,及异步的代码,都应该写在actions中
},
});
2. 商品列表页…
4. 购物车页 …
购物车梳理

  相关解决方案