(1).用了vant组件van-card,van-checkbox,van-submit-bar来搭建页面。这里主要讲购物车逻辑关系:全选,反选,选择,添加,删除,总计。用了vuex来处理购物车数据。
state.js,存放数据
export default{
cars:[]
}
actions.js,逻辑操作
export default{
initCars({commit}){//初始化购物车数据
let cars=localStorage.cars?JSON.parse(localStorage.cars):[]
commit('changCar',cars)
},
addCar({commit},params){//添加购物车
let cars=localStorage.cars?JSON.parse(localStorage.cars):[]
//如果存在 num+1 如果不存在 push
//array.some 函数 遍历数组 如果内部返回ture 整个表达式就是ture 不返回就是假
let index=0;
let isHas=cars.some((item)=>{
index++
if(item.id===params.id && item.dec==item.dec){
return true
}
})
if (isHas) {
// 已经存在 num++
cars[index-1].num+=1
}else{
//不存在
params.num=1
cars.push(params)
}
//本地缓存模拟的数据进行更新
localStorage.cars=JSON.stringify(cars)
//vuex 进行更新
commit('changCar',cars)
},
addItem({commit},params){//加号按钮
console.log('添加一件');
let cars=JSON.parse(localStorage.cars)
let arr = cars.filter(function (item) {//选择出符合条件,添加到新数组
return item.id === params.id;
});
if(arr[0].num<arr[0].pnum){
arr[0].num +=1;
}
console.log(cars);
//本地缓存模拟的数据进行更新
localStorage.cars=JSON.stringify(cars)
//vuex 进行更新
commit('changCar',cars)
},
remItem({commit},params){//减号按钮
console.log('减少一件');
let cars=JSON.parse(localStorage.cars)
let arr = cars.filter(function (item) {
return item.id === params.id;
});
if(arr[0].num>0){
arr[0].num -=1;
}
if(arr[0].num==0){//到0时,从数组中删除当前值
cars = cars.filter(function (item) {
return item.id !== arr[0].id;
});
}
//本地缓存模拟的数据进行更新
localStorage.cars=JSON.stringify(cars)
//vuex 进行更新
commit('changCar',cars)
},
selectItem({commit},params){//复选框按钮,选中和不选中
let cars=JSON.parse(localStorage.cars)
cars.map(function (item) {//遍历数组,修改属性
if (item.id === params.id) {
item.check = !params.check;
}
})
localStorage.cars = JSON.stringify(cars);
commit('changCar',cars)
},
allItem({commit},params){//全选,不全选
console.log(params)
let cars=JSON.parse(localStorage.cars)
cars.map(function (item) {
item.check = !params;
})
localStorage.cars = JSON.stringify(cars);
commit('changCar',cars)
},
removeItem({commit},params){//当到订单时,去掉选中的数据,购物车此时剩下没有被选中的数据
let cars=JSON.parse(localStorage.cars)
let arr = cars.filter(function (item) {
return item.check==false;
});
localStorage.cars = JSON.stringify(arr);
commit('changCar',arr)
}
}
mutations.js,修改数据
import Vue from 'vue'
export default{
changCar(state,params){
console.log('触发mutations')
Vue.set(state,'cars',params)
// state.cars=params
}
}
getters.js ,扩展数据的变化
export default{
all(state){
let price=0;
console.log(state)
for (var i = 0; i <state.cars.length; i++) {
if(state.cars[i].check){
price+=Number(state.cars[i].num)*Number(state.cars[i].price)
}//总计被选中的数据的价格
}
return price;
}
}
index.js
import state from './state'
import mutations from './mutations'
import actions from './actions'
import getters from './getters'
export default{
state,
mutations,
actions,
getters
}
index.js,模块化
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import shopcar from './shopcar'
const store = new Vuex.Store({
modules:{
shopcar:shopcar
}
})
export default store
在组件中的使用
在商品详情页中,添加购物车
<van-goods-action-button type="warning" text="加入购物车" color="#ef5350" @click="addCar(goodsinfo)" />
<script>
import {mapActions} from 'vuex'
export default {
name:"ProductDetail",
data(){
return{
goodsinfo:{
}
}
},
methods: {
onAddCartClicked(skuData){
this.addCar(this.goodsinfo)//商品对象数据
},
...mapActions(['addCar'])
},
在购物页中的逻辑处理
<template>
<div id="shop">
<Header title="购物车" :back="back"></Header>
<div class="content">
<div class="header">
<van-checkbox v-model="checked" checked-color="#f44336" @click="allItem(checked)"></van-checkbox><span class="title">蛋糕精选</span>
<div class="right">
<van-icon name="info-o" />
<span>已免运费</span>
</div>
</div>
<div class="list">
<van-card
v-for="item in cars"
:key="item.id"
:price="item.price"
:desc="item.dec"
:title="item.name"
:thumb="root+item.imgurl"
>
<div slot="tags" class="check">
<van-checkbox v-model="item.check" checked-color="#f44336" @click="selectItem(item)"></van-checkbox>
</div>
<div slot="footer">
<button @click="remItem(item)">-</button>
<span>{{item.num}}</span>
<button @click="addItem(item)">+</button>
</div>
</van-card>
</div>
<van-submit-bar
:price="all*100"
button-text="提交订单"
@submit="onSubmit"
>
<van-checkbox v-model="checked" checked-color="#f44336" @click="allItem(checked)">全选</van-checkbox>
<span slot="tip">
你的收货地址不支持同城送, <span>修改地址</span>
</span>
</van-submit-bar>
</div>
</div>
</template>
<script>
import { mapState, mapGetters ,mapActions} from "vuex";
import Vue from 'vue';
export default {
name:'Shop',
data(){
return{
checked: true,//全选按钮
}
},
created() {
var arr = this.cars.filter(function (item) {
return item.check==false;
});
if(arr.length!==0){//如果有一个没有被选中,就不全选
this.checked=false
}else{
this.checked=true
}
},
updated() {
var arr = this.cars.filter(function (item) {
return item.check==false;
});
console.log(arr)
if(arr.length!==0){
this.checked=false
}else{
this.checked=true
}
},
methods: {
onSubmit(){
this.$router.push({name:'address'})//this.$route.params
},
...mapActions(['addItem','remItem','allItem','selectItem'])//逻辑方法
},
computed: {
...mapState({//得到购物车数据
cars:state => state.shopcar.cars
}),
...mapGetters(['all'])//得到扩展数据
}
}
</script>
<style lang="less" scoped>
@import url('../../../style/main.less');
#shop{
.content{
overflow:hidden;
background:#fafafa;
.m_t(45);
.p_b(100);
.header{
.van-checkbox{
float:left;
}
.title{
.m_l(10);
}
.fs(14);
background:white;
.margin(10,10,0,10);
.padding(5,5,5,5);
.right{
float:right;
display:flex;
align-items:Center;
.fs(12);
color:#646566;
}
}
.list{
.padding(0,10,10,10);
background:#fafafa;
.van-card{
background:white;
.p_l(38);
}
.van-card:not(:first-child){
margin-top:0;
}
.van-card__price{
color:#b71c1c;
}
.check{
position:relative;
.right(122);
}
.van-card__footer{
position:relative;
.top(-26);
button{
border:0;
background:white;
.fs(18);
font-weight:600;
}
span{
display:inline-block;
.h(16);
.w(16);
text-align:center;
background:#fafafa;
}
}
}
.van-submit-bar{
bottom:50px;
}
}
}
</style>
这样就实现了购物车功能。