一、 购物车的实现原理:
注意:在写购物车之前,我们需要知道vuex里的方法如何使用,若是不太清除方法的使用,可以看我之前的文章,其中有一章是介绍vuex的方法的使用和调用的!
1,首先,我们需要一个json数据,自己写或者找一个就可以。
2. 然后把数据渲染到页面,即为商品列表,在每一个商品后面加上一个加号,代表着点击添加商品就将该商品添加到购物车。
3. 其次,就是购物车内的操作,在此之前需要把数据存储到本地,好在购物车页面渲染点击获取的数据。
4. 最后,就是对数据进行全选,单选,加加减减及总价的操作。
二、购物车的具体操作
1、store文件中的index.js代码(即vuex操作)
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
//引入axios,需要下载
Vue.use(Vuex)
export default new Vuex.Store({
state: {
cartlist: [],//用于商品列表渲染的数据
cartItem: JSON.parse(localStorage.getItem("carto")) || [],//存储到localStorage(本地存储),的数组
delchecked: JSON.parse(localStorage.getItem("carto")) || false,
//同步的全选的状态
zong:JSON.parse(localStorage.getItem("zong")) ||0,
//总价
dan:JSON.parse(localStorage.getItem("dan")) ||0,
//总件数
},
mutations: {
//用于商品列表
CARTLIST(state, item) {
state.cartlist = item
},
//用于本地存储并进行去重操作
CARTITEM(state, item) {
var flg = false;
state.cartItem.forEach(e => {
if (e._id === item._id) {
e.count++;
flg = true;
}
});
if (!flg) {
item.count = 1;
item.checked = false;
state.cartItem.push(item)
}
localStorage.setItem("carto", JSON.stringify(state.cartItem))
},
//判断单选是否全选,同步全选
ONCHANGE(state, item) {
console.log(state.cartItem[0].checked)
console.log(item);
state.cartItem.forEach(e => {
if (e._id === item.id) {//判断是否是选中的那个元素
e.checked = item.checked;
//改变存储中的checked的状态
}
});
//同步全选状态
state.delchecked = state.cartItem.every(e => {
return e.checked === true
//判断存在本地的数据是否全为true,若为true则同步全选
})
localStorage.setItem("carto", JSON.stringify(state.cartItem));
//计算总价件数
state.zong=0;
state.dan=0;
state.cartItem.forEach(e=>{
if(e.checked){
state.zong +=(e.count*e.salePrice);
state.dan +=e.count;
}
})
localStorage.setItem("zong",JSON.stringify(state.zong))
localStorage.setItem("dan",JSON.stringify(state.dan))
},
//全选同步单选
ONCLICK(state, checked) {
console.log(state.cartItem[0].checked)
console.log(checked);
state.delchecked = checked;
state.cartItem.forEach(e => {
e.checked = checked;
});
localStorage.setItem("carto", JSON.stringify(state.cartItem));
},
jian(state,item){
state.cartItem.forEach(e=>{
if(e.count>1&&e._id === item._id){
e.count--
}
})
state.zong=0;
state.dan=0;
state.cartItem.forEach(e=>{
if(e.checked){
state.zong +=(e.count*e.salePrice);
state.dan +=e.count;
}
})
localStorage.setItem("zong",JSON.stringify(state.zong))
localStorage.setItem("dan",JSON.stringify(state.dan))
},
jia(state,item){
state.cartItem.forEach(e=>{
if(e._id === item._id){
e.count++
}
})
state.zong=0;
state.dan=0;
state.cartItem.forEach(e=>{
if(e.checked){
state.zong +=(e.count*e.salePrice);
state.dan +=e.count;
}
})
localStorage.setItem("zong",JSON.stringify(state.zong))
localStorage.setItem("dan",JSON.stringify(state.dan))
},
},
actions: {
CARTLIST(context) {
axios.get('./data(1).json')
.then(res => {
context.commit("CARTLIST", res.data.list);
console.log(res.data.list)
})
},
CARTITEM(context, item) {
context.commit("CARTITEM", item)
console.log(item)
},
ONCHANGE(context, item) {
context.commit("ONCHANGE", item)
console.log(item)
},
ONCLICK(context, checked) {
context.commit("ONCLICK", checked)
console.log(checked)
},
jian(context,item){
context.commit("jian",item)
},
jia(context,item){
context.commit("jia",item)
}
},
modules: {
}
})
2、商品列表页代码(Home.vue)
<template>
<div class="home">
<div class="list">
<div class="list_z" v-for="(item,index) in cartlist" :key="index">
<img :src="item.productImage" width="90px" alt="">
<div class="list_y">
<p>{{item.productName}}</p>
<p>{{item.salePrice |delre}}</p>
</div>
<p style="font-size:30px;float:right;"
@click="tocart(item)"
>+</p>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {};
},
computed: {
cartlist:function(){
//对商品列表的调用
return this.$store.state.cartlist;
}
},
mounted() {
this.$store.dispatch("CARTLIST")
},
methods:{
//点击添加,并跳转到About页面
tocart(item){
this.$router.push('/about')
this.$store.dispatch("CARTITEM",item)
}
},
filters:{
//修饰符
delre(value){
var remp=parseFloat(value).toFixed(2)
return `¥${remp}`
}
}
};
</script>
3、购物车页面(About.vue)
<template>
<div>
<div @click="back">购物车</div>
<div class="cart">
<div class="list_x" v-for="(item,index) in cartItem" :key="index">
<input type="checkbox" :checked="item.checked" @change="onchange(item)">
<img :src="item.productImage" width="90px" alt />
<div class="list_y">
<p>{{item.productName}}</p>
<p class="zz">
<span> ¥{{item.salePrice}}</span>
<span @click="jian(item)">-</span>
<span>{{item.count}}</span>
<span @click="jia(item)">+</span>
</p>
</div>
</div>
</div>
<div class="bottom">
<input type="checkbox" :checked="delchecked" @click="onclick">全选
<p>总价:{{zong|farls}}</p>
<p>总件数:{{dan}}</p>
</div>
</div>
</template>
<script>
export default {
// porps:{
// item:Object
// }
computed: {
cartItem: function() {
return this.$store.state.cartItem;
},
delchecked: function() {
return this.$store.state.delchecked;
},
dan:function(){
return this.$store.state.dan
},
zong:function(){
return this.$store.state.zong
}
},
mounted() {},
methods: {
back() {
window.history.back();
},
onchange(item){
var checked = event.target.checked;
//动态绑定实时监听单选的状态
this.$store.dispatch("ONCHANGE",{checked:checked,id:item._id})
},
onclick(){
var checked= event.target.checked;
//动态绑定实时监听全选的状态
this.$store.dispatch("ONCLICK",checked)
},
jian(item){
this.$store.dispatch("jian",item)
},
jia(item){
this.$store.dispatch("jia",item)
}
},
filters:{
farls(value){
var temp=parseFloat(value).toFixed(2);
return `¥${temp}`;
}
}
};
</script>