vuex+浏览器本地储存localstorage管理购物车
总结:
- 1、localStorage和sessionStorage的区别:localstorage可以将第一次请求的数据直接存储到本地,但在IE8以上才支持这个属性,目前所有浏览器都会把localstorage的值类型限定为string类型,所有我么比较常见的json对象类型需要一些转换,本质是对字符串的读取,如果存储内容多的话会消耗内存空间,导致页面变卡。(不能被爬虫抓取到)。与sessionStorage唯一的区别就是localStorage属于永久性存储,sessionStorage属于当回话结束的时候键值对会被清空。
- 2、Vuex主要部分:
state:包含了store中存储的各个状态
getter:类似于vue中的计算属性,根据其他getter或state计算返回值
mutation:一组方法,是改变store中状态的执行者,只能进行同步操作
action:包含异步操作
module:模块的局部状态
CraftDetail.vue
//添加到vuex中state
addCart(item){
alert("添加成功");
// console.log("-------添加成功---------")
setTimeout(() => {
this.$router.push({name:"Cart"})
}, 1500);
this.$store.commit("addCart",item);
console.log("additem");
console.log(item)
},
Cart.vue
<template>
<div id="cartbox">
<link
href="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/css/bootstrap.min.css"
rel="stylesheet"
/> <!-- twitter-bootstrap链接引用-->
<template v-if="$store.state.craftlist.length===0">
<div class="panel panel-default">
<div class="panel-body">
<p>购物车空空如也</p>
<button @click="backrecom">继续添加</button>
</div>
</div>
</template>
<template v-else>
<div class="container" id="app">
<div class="row">
<!-- bootstrap的面板组件包含带标题的面板、带表格的面板灯 -->
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">我的购物车</h3>
</div>
<div class="panel-body">
<!-- 带表格的面板 table-hover:鼠标悬停高亮的表格-->
<table class="table table-hover">
<thead class="thead">
<tr>
<th>
<input type="checkbox" v-model="flag" @change="ch()" />
</th>
<th>商品名称</th>
<th>商品单价</th>
<th>购买数量</th>
<th>小计</th>
<th>商品操作</th>
</tr>
</thead>
<tbody class="tbody">
<tr v-for="(item,index) in $store.state.craftlist" :key="index">
<td>
<input type="checkbox" :value="item.id" v-model="arr" />
</td>
<td>{{item.name}}</td>
<td>{{item.price}}</td>
<td>
<button @click="reduce(index)">-</button>
<input type="text" v-model="item.num" style="width:26px;text-align:center;"/>
<button @click="add(index)">+</button>
</td>
<td>{{item.price*item.num}}</td>
<td>
<div class="btn-group btn-group-sm">
<button class="btn btn-danger" type="button" @click="del(index)">删除</button>
</div>
</td>
</tr>
</tbody>
<button @click="backrecom">继续添加</button>
<button @click="gopay">结算</button>
</table>
</div>
<!-- 带脚注的面板 -->
<div class="panel-footer" style="text-align: right;">
共计
<span>{{totalPrice}}元</span>
</div>
</div>
</div>
</div>
</template>
</div>
</template>
Cart中js
export default {
name: "Cart",
data(){
return{
flag:false,
arr:[]
}
},
methods: {
add(index){
this.$store.commit("add",index)
},
reduce(index){
this.$store.commit("reduce",index)
},
del(index){
this.$store.commit("delete",index)
},
ch(){
this.arr = [];
if(this.flag){
this.$store.state.craftlist.forEach(craftlist => {
this.arr.push(craftlist.id)
})
}
else{
this.arr = []
}
},
backrecom(){
this.$router.push({name:"About"});
},
gopay(){
this.$router.push({name:"Pay"});
}
},
computed:{
totalPrice(){
var total = 0;
for(var i in this.arr){
for(var j in this.$store.state.craftlist){
if(this.arr[i] == this.$store.state.craftlist[j].id){
total+=this.$store.state.craftlist[j].num*this.$store.state.craftlist[j].price
}
}
}
return total;
}
}
}
vuex-index.js
index.js中state、mutations、actions可以分成三个文件进行封装,显得更加简洁。
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
//安装插件
Vue.use(Vuex)
//创建对象
const store = new Vuex.Store({
state: {
craftlist: JSON.parse(localStorage.getItem("craftlist"))||[]
},
mutations: {
addCart(state,item){
var obj = {
id:item.craftId,
name:item.craftName,
price:item.price,
num:1
}
console.log("store obj")
console.log(obj)
var index = state.craftlist.findIndex(v => {
return item.craftId == v.id
})
if(index == -1){
state.craftlist.push(obj)
localStorage.setItem("craftlist",JSON.stringify(state.craftlist))
}
else{
state.craftlist[index].num++;
localStorage.setItem("craftlist",JSON.stringify(state.craftlist))
}
},
reduce(state,index){
state.craftlist[index].num--;
localStorage.setItem("craft",JSON.stringify(state.craftlist))
if(state.craftlist[index].num <= 0){
if(confirm("是否移除购物车")){
state.craftlist.splice(index,1)
localStorage.setItem("craftlist",JSON.stringify(state.craftlist))
}
else{
state.craftlist[index].num = 1
localStorage.setItem("craftlist",JSON.stringify(state.craftlist))
}
}
},
add(state,index){
state.craftlist[index].num++;
localStorage.setItem("craftlist",JSON.stringify(state.craftlist))
},
delete(state,index){
state.craftlist.splice(index,1);
localStorage.setItem("craftlist",JSON.stringify(state.craftlist))
}
},
actions: {
getcraft(context){
axios.get('/api/CartInfo').then(res => {
context.commit('getcraft',res)
})
}
}
})
//导出store
export default store
参考:
https://blog.csdn.net/weixin_42554191/article/details/105397179?utm_medium=distribute.pc_relevant.none-task-blog-OPENSEARCH-2.edu_weight&depth_1-utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-2.edu_weight
https://blog.csdn.net/sslcsq/article/details/104819075?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.edu_weight&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.edu_weight