这个小demo具有添加商品进购物车 、增加购物车内商品的数量、减少购物车内商品的数量、计算一类商品的总价、以及计算所有商品的总价
首先看目录结构


因为我们的Tab.vue Car.vue 以及Carinfo.vue中的数据有关联 所以用到了vuex
在store文件夹下的index.js中```
import Vue from 'vue'; import Vuex from 'vuex'; import logger from 'vuex/dist/logger'; Vue.use(Vuex); // 状态
//state里面存放的数据是cartList 这个cartList数据manuations和getter都能用到
let state = {cartList:[]}; import mutations from './mutations.js'; import getters from './getters.js' export default new Vuex.Store({ state, mutations, getters, strict:true, plugins:[logger()] }); ```
在main.js里面引入store文件夹下的index.js
main.js文件内容
import Vue from 'vue' import App from './App' import router from './router' //购物车 import store from './store' /* eslint-disable no-new */ new Vue({ el: '#app', router, components: { App }, template: '<App/>', store })
在store文件夹下的manutations-types.js文件
//加入购物车的功能 //添加购物车(添加的商品) export const ADD_CART='ADD_CART'; //删除购物车(要求传入id) export const REMOVE_CART='REMOVE_CART'; //更改商品数量({id,1/-1}) export const CHANGE_COUNT='CHANGE_COUNT'; //清空购物车 export const CLEAR_CART='CLEAR_CART';
List.vue组件
<template>
<div>
<MHeader>列表页</MHeader>
<div class="content" ref="scroll" @scroll="loadMore">
<ul>
<router-link v-for="(book,index) in books" :key="index" :to="{name:'detail',params:{bid:book.bookId}}" tag="li">
<img v-lazy="book.bookCover">
<div>
<h4>{{book.bookName}}</h4>
<p>{{book.bookInfo}}</p>
<b>{{book.bookPrice}}</b>
<div class="btn-list">
<button @click.stop="remove(book.bookId)">删除</button>
<button @click.stop="addCart(book)">添加进购物车</button>
</div>
</div>
</router-link>
</ul>
<div @click="More" class="More">加载更多</div>
</div>
</div>
</template>
<script>
import * as Types from '../store/mutations-types.js'
export default {
methods:{
//点击添加进购物车按钮 触发此方法 发布订阅 添加指定图书进购物车Car.vue
addCart(book){
this.$store.commit(Types.ADD_CART,book)
}
}
}
</script>
在store文件夹下的manutations.js文件内容 添加指定商品进购物车
import * as Types from './mutations-types.js'; const mutations={ //添加商品进购物车 [Types.ADD_CART](state,book) { //book是添加的一本书 如果有这本书 累加的是数量 如果没有那么数量为1 放到cartList中 //查找cartList里面有没有添加进来的那本书 let product=state.cartList.find(item=>item.bookId===book.bookId); //如果有的话 if(product) { product.bookCount+=1; //还要更新掉原数组 原数组里面有book内容和book 否则不会刷新 state.cartList=[...state.cartList]; }else { book.bookCount=1; //用新数组替换到老数组 state.cartList=[...state.cartList,book] } } } export default mutations;
Car.vue组件
<template>
<div>
<MHeader>购物车</MHeader>
<ul class="content">
<li v-for="(l,index) in cartList" :key="index">
<img :src="l.bookCover" alt="" style="120px;height:140px">
<div class="right">
<h3>{{l.bookName}}</h3>
<button @click="delOneCart(l)">-</button><span>{{l.bookCount}}</span><button @click="addCart(l)">+</button>
//计算此类商品的价钱
<p>小计 :¥{{l.bookPrice*l.bookCount | numFilter}}</p>
<button @click="delCart(l)">删除</button>
</div>
</li>
</ul>
<Carinfo></Carinfo>
</div>
</template>
<script>
import MHeader from '../base/MHeader.vue';
import Carinfo from './Carinfo.vue';
import * as Types from '../store/mutations-types.js'
// 辅助函数 语法糖
import {mapState,mapGetters} from 'vuex';
export default {
data(){
return {msg: 'hello'}
},
created(){
},
filters:{//过滤器
numFilter(value) {
//截取当前数据到小数点后两位
let realVal=Number(value).toFixed(2);
return Number(realVal);
}
},
methods: {
addCart(l){//当触发此事件是同样也是提交给manutations
this.$store.commit(Types.ADD_CART,l)
},
delOneCart(l){
this.$store.commit(Types.CHANGE_COUNT,l);
},
delCart(l){
this.$store.commit(Types.REMOVE_CART,l);
}
},
computed: {
...mapGetters(['count','totolPrice']),
...mapState(['cartList'])
/*cartList(){
return this.$store.state.cartList
}*/
},
components: {MHeader,Carinfo}
}
manutaions.js
import * as Types from './mutations-types.js'; const mutations={ [Types.ADD_CART](state,book) { //book是添加的一本书 如果有这本书 累加的是数量 如果没有那么数量为1 放到cartList中 //查找cartList里面有没有添加进来的那本书 let product=state.cartList.find(item=>item.bookId===book.bookId); //如果有的话 if(product) { product.bookCount+=1; //还要更新掉原数组 否则不会刷新 state.cartList=[...state.cartList]; }else { book.bookCount=1; //用新数组替换到老数组 state.cartList=[...state.cartList,book] } console.log('state.cartList',state.cartList); }, [Types.CHANGE_COUNT](state,book) { let product=state.cartList.find(item=>item.bookId===book.bookId); if(product) { product.bookCount-=1; //还要更新掉原数组 否则不会刷新 state.cartList=[...state.cartList]; } }, [Types.REMOVE_CART](state,book){ state.cartList.forEach((item,i) => { if(item.bookId===book.bookId){ state.cartList.splice(i,1); } }); state.cartList=[...state.cartList]; }, [Types.CLEAR_CART](state){ state.cartList=[]; } }
export default mutations;
Carinfo.vue
<template>
<div class="item-wrapper">
<div class='item'>总数:
<strong>{{count}}</strong>
</div>
<div class='item'>总价:
¥<strong>{{totalPrice|numFilter}}</strong>
</div>
<button class="item btn btn-danger" @click="clearAll">清空购物车</button>
</div>
</template>
<script>
import * as Types from '../store/mutations-types.js'
//两个辅助函数
import {mapState,mapGetters} from 'vuex';
export default {
data(){
return {
}
},
filters:{
numFilter(value) {
//截取当前数据到小数点后两位
let realVal=Number(value).toFixed(2);
return Number(realVal);
}
},
methods:{
clearAll(){
this.$store.commit(Types.CLEAR_CART);
}
},
computed:{
...mapGetters(['count']),
...mapGetters(['totalPrice'])
}
}
Getter.js
let getters={ //求购物车中所有商品的总数量 //迭代相加 reduce count:(state)=>state.cartList.reduce((prev,next)=>prev+next.bookCount,0), totalPrice:(state)=>state.cartList.reduce((prev,next)=>prev+next.bookCount*next.bookPrice,0) } export default getters;