vuex实现简易购物车加购效果

2023-09-21 15:04:51

一、加购效果动图

在这里插入图片描述

二、前提条件

创建了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))
    }
}

五、最终效果

在这里插入图片描述
可见,现在刷新不会再清空购物车数据了。

更多推荐

PostgreSQL 技术内幕(十)WAL log 模块基本原理

事务日志是数据库的重要组成部分,记录了数据库系统中所有更改和操作的历史信息。WALlog(WriteAheadLogging)也被称为xlog,是事务日志的一种,也是关系数据库系统中用于保证数据一致性和事务完整性的一系列技术,在数据库恢复、高可用、流复制、逻辑复制等模块中扮演着极其重要的角色。在这次直播中,我们为大家介

【8B10B编解码及verilog(xilinx example)解析】

8B10B编解码及verilog(xilinxexample)解析编码查表算法解码代码解析极性控制字K码编码8b/10b编码将串行的数据以8bit为一个单位进行编码处理得到一个10bit的数据,具体怎么操作呢,假设原始8位数据从高到低用HGFEDCBA表示,将8位数据分成高3位HGF和低5位EDCBA两个子组。经过5B

成都直播基地火热招商中,天府蜂巢成都直播基地招商政策汇总

随着直播产业的发展,四川天府新区也在逐步形成成熟的直播产业链。近日,记者采访到成都天府蜂巢直播产业基地即将竣工,正式进入运营阶段,作为成都科学城兴隆湖高新技术服务产业园的主打新一代成都直播基地,正积极招商中!引领大规模的平台聚合发展的树莓集团与专注城市资产运营的上市公司德商产投携手打造产业+直播赋能平台——成都天府蜂巢

MyBatis初级

文章目录一、mybatis1、概念2、JDBC缺点2.1、之前jdbc操作2.2、原始jdbc操作的分析3、mybatis的使用3.1、导入maven依赖3.2、新建表3.3、实体类3.4、编写mybatis的配置文件3.5、编写接口和映射文件3.6、编写测试类3.7、注意事项4、代理方式开发5、mybatis和spr

03MyBatis-Plus中的常用注解

常用注解@TableNameMyBatis-Plus根据BaseMapper中指定的泛型(实体类型名)确定数据库中操作的表,如果根据实体类型名找不到数据库中对应的表则会报表不存在异常//向表中插入一条数据@TestpublicvoidtestInsert(){Useruser=newUser(null,"张三",23,

华为云云耀云服务器L实例评测 | Linux系统宝塔运维部署H5游戏

文章目录前言一、云服务器相对传统服务器有什么优势1.1、可伸缩性(Scalability)1.2、灵活性(Flexibility)1.3、高可用性(HighAvailability)1.4、备份和恢复(BackupandRecovery)1.5、成本效益(Cost-Effectiveness)1.6、全球性(Globa

SpringMvc常用注解

目录一、@RequestParam二、@RequestHeader,@CookieValue三、@ModelAttribute(1)作用1(2)作用2四、@ResponseBody五、@RestController六、@RequestBody一、@RequestParam@RequestParam可以在控制器方法中获取

Java线程池ExecutorService和Executors应用(Spring Boot微服务)

记录:476场景:在SpringBoot微服务中使用ExecutorService管理Java线程池。使用Executors创建线程池。使用Runnable接口实现类提交线程任务到线程池执行。版本:JDK1.8,SpringBoot2.6.3。1.线程和线程池基础JDK自带线程和线程池包位置:java.util.con

嵌入的是PWM

PWM简介在嵌入式系统中,PWM(脉冲宽度调制)是一种常用的技术,用于控制和生成脉冲信号,通常用于控制电机、LED亮度、音频输出等。针对STM32微控制器,它们通常具有内置的PWM控制器模块,使PWM生成相对容易。PWM是一种用于控制电子设备的技术,通过调整信号的脉冲宽度和周期,可以模拟出不同的电压或功率级别。频率、占

JVM 虚拟机 ---->垃圾收集算法

文章目录JVM垃圾收集器一、判断对象是否存活1、引用计数算法(1)基本思路(2)存在的问题2、可达性分析算法(1)基本思路二、Java中的四种引用方式1、强引用(StrongReference)(1)弱化方式1(2)弱化方式22、软引用(SoftReference)3、弱引用(WeakReference)4、虚引用(P

外包干了2个月,技术退步明显.......

先说一下自己的情况,大专生,18年通过校招进入武汉某软件公司,干了接近4年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试,已经让我变得不思进取,谈了2年的女朋友也因为我的心态和工资和我分手了。于是,我决定要改变现状,冲击下大厂。刚开始准备时

热文推荐