目录
- 一、加购效果动图
- 二、前提条件
- 三、开始操作
- 四、解决vuex刷新数据丢失问题
- 五、最终效果
一、加购效果动图
二、前提条件
创建了vue项目,安装了vuex
三、开始操作
目录结构如下:
main.js文件中引入store:
import Vue from 'vue'
import App from './App.vue'
import store from './store'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
store,
}).$mount('#app')
page-index.vue页面组件代码如下:
<template>
<div>
<div class="item">
<h1>我的购物车:</h1>
<ul>
<li v-for="(item, index) in this.$store.state.cartGoods" :key="index">
商品名称:{{item.name}}<br>
<button @click="numRed(index)">-</button>
<span class="num">{{item.num}}</span>
<button @click="numAdd(index)">+</button>
<span>单价:¥{{item.price}}</span>
</li>
</ul>
</div>
<div class="item">
<h1>商品列表:</h1>
<ul class="prod-list">
<li v-for="(item, index) in prodList" :key="index">
<span class="pro">名称:{{item.name}}</span>
<span class="pro">单价:{{item.price}}</span>
<span class="pro">
<button @click="addCart(item)">加入购物车</button>
</span>
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
data(){
return{
prodList:[
{
name:"CPU",
price:999.99
},
{
name:"显示器",
price:199.99
},
{
name:"显卡",
price:1000
},
{
name:"内存",
price:500
},
{
name:"硬盘",
price:500
}
]
}
},
methods: {
numRed(index){
this.$store.dispatch('red',index)
},
numAdd(index){
this.$store.dispatch('add', index)
},
addCart(item){
this.$store.commit('ADD_CART',item)
}
}
}
</script>
<style scoped>
.item{
margin-bottom: 50px;
}
.prod-list{ line-height: 22px;}
.prod-list li{ border-bottom: #ddd solid 1px; padding: 10px;}
.prod-list li .pro{ min-width: 150px; display: inline-block; vertical-align: middle;}
</style>
state.js文件内容如下:
export default {
cartGoods: []
}
getters.js文件内容如下:
export default {
countGoods:(state)=>{
var count={
allNum:0,
allPrice:0
}
state.cartGoods.forEach((item)=>{
function ConvertAdd(arg1, arg2) {//加法精确运算
var r1, r2, m;
try { r1 = arg1.toString().split(".")[1].length; } catch (e) { r1 = 0; }
try { r2 = arg2.toString().split(".")[1].length; } catch (e) { r2 = 0; }
m = Math.pow(10, Math.max(r1, r2));
var result = (arg1 * m + arg2 * m) / m;
//return (arg1 * m + arg2 * m) / m;
var ws = 1, ln = 0,
lnArr1 = arg1.toString().split("."),
lnArr2 = arg2.toString().split("."),
ln1 = (lnArr1.length < 2) ? 0 : lnArr1[1].length,
ln2 = (lnArr2.length < 2) ? 0 : lnArr2[1].length;
if ((ln1 - ln2) >= 0) {
ln = ln1;
} else {
ln = ln2;
}
if (ln > 0) {
switch (ln) {
case 0: { break; }
case 1: { ws = 10; break; }
case 2: { ws = 100; break; }
case 3: { ws = 1000; break; }
case 4: { ws = 10000; break; }
case 5: { ws = 100000; break; }
case 6: { ws = 1000000; break; }
case 7: { ws = 10000000; break; }
case 8: { ws = 100000000; break; }
default: { break; }
}
}
return Math.round(result * ws) / ws;
}
if(item.num>0){
count.allNum +=item.num;
count.allPrice =ConvertAdd(count.allPrice,Math.round(item.num*item.price * Math.pow(10, 3)) / Math.pow(10, 3));
}
})
return count;
}
}
mutations.js文件内容如下:
import { ADD,RED,ADD_CART } from './mutationTypes'
export default {
// 我们可以使用 ES2015 风格的计算属性命名功能
// 来使用一个常量作为函数名
// 这样可以使 linter 之类的工具发挥作用,同时把这些常量放在单独的文件中可以让你的代码合作者对整个 app 包含的 mutation 一目了然
[ADD](state,req){
console.log(state.cartGoods,req);
state.cartGoods[req].num++;
},
[RED](state,req){
if(state.cartGoods[req].num>0){
state.cartGoods[req].num--;
}
},
[ADD_CART](state,req){
var newFlag=true;
for(var i=0; i<state.cartGoods.length; i++){
if(state.cartGoods[i].name==req.name){
newFlag=false;
state.cartGoods[i].num++;
break
}
}
if(newFlag){
let item={
name:req.name,
price:req.price,
num:1
}
state.cartGoods.push(item);
}
}
}
mutationTypes.js内容如下:
export const ADD = 'ADD';
export const RED = 'RED';
export const ADD_CART = 'ADD_CART';
actions.js文件内容如下:
export default {
red({commit},req){
commit('RED',req);
},
add({commit}, req){
commit('ADD', req)
}
}
index.js文件内容如下:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import state from '@/store/state.js';
import getters from "@/store/getters";
import mutations from "@/store/mutations";
import actions from "@/store/actions"
const store = new Vuex.Store({
// 用来存入状态
state: state,
// 计算属性(对state中的属性进行计算)
getters: getters,
mutations: mutations,
actions: actions
})
export default store
到此,已经能实现基本的加购操作了。
但是,有一个问题就是页面刷新的时候vuex里面的数据会丢失,购物车就会被清空。显然这是不符合实际购物的。要把数据存进本地才能避免这种情况。
四、解决vuex刷新数据丢失问题
修改state.js文件:
export default {
// 从本地获取购物车商品数据,如果没有初始化为空数组
cartGoods: JSON.parse(window.localStorage.getItem('cart-products')) || []
}
在mutations.js的ADD_CART方法中每次更改过的数据,都需要记录到本地存储中。增加一句:window.localStorage.setItem('cart-products', JSON.stringify(state.cartGoods))
最终文件内容如下:
import { ADD, RED, ADD_CART } from './mutationTypes'
export default {
[RED](state,req){
// console.log(state, req)
if(state.cartGoods[req].num > 0){
state.cartGoods[req].num--;
}
},
[ADD](state, req){
state.cartGoods[req].num++;
},
[ADD_CART](state, req){
var newFlag = true;
for(var i = 0; i < state.cartGoods.length; i++){
if(state.cartGoods[i].name == req.name){
newFlag = false;
state.cartGoods[i].num ++;
break
}
}
if(newFlag){
let item = {
name: req.name,
price: req.price,
num: 1
}
state.cartGoods.push(item)
}
window.localStorage.setItem('cart-products', JSON.stringify(state.cartGoods))
}
}
五、最终效果
可见,现在刷新不会再清空购物车数据了。