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

news2024/11/29 0:43:39

目录

      • 一、加购效果动图
      • 二、前提条件
      • 三、开始操作
      • 四、解决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))
    }
}

五、最终效果

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1028289.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

星戈瑞Cyanine7-COOH在生物学和医学中的应用 CY7-COOH

Cyanine7-COOH作为一种近红外荧光染料&#xff0c;在生物学和医学领域应用。以下是一些Cyanine7-COOH在这些领域中可能的应用&#xff1a; 生物荧光成像&#xff1a; Cyanine7-COOH可以用于细胞和组织的荧光成像&#xff0c;特别是在近红外范围内。这个波长范围的荧光信号穿透…

分布式链路追踪系统zipkin【杭州多测师_王sir】

一、部署zipkin环境的方式 》1.docker 2、java -jar 3、运行源码 二、分别可以在Linux系统和Windows系统里面运行zipkin 三、在地址栏输入&#xff1a;http://127.0.0.1:9411 四、zipkin的流程图 由上图可以看出&#xff0c;应用的代码(User Code)发起 Http Get 请求(请…

Unity丨移动相机朝向目标并确定目标在摄像机可视范围内丨摄像机注释模型丨摄像机移动丨不同尺寸模型优化丨

文章目录 问题描述功能展示技术细节小结 问题描述 本文提供的功能是摄像机朝向目标移动&#xff0c;并确定整个目标出现在摄像机视角内&#xff0c;针对不同尺寸的模型优化。 功能展示 提示&#xff1a;这里可以添加技术名词解释 技术细节 直接上代码 using UnityEngine;…

阿里云产品试用系列-函数计算 FC

函数计算&#xff08;Function Compute&#xff09;是一个事件驱动的全托管 Serverless 计算服务&#xff0c;您无需管理服务器等基础设施&#xff0c;只需编写代码并上传&#xff0c;函数计算会为您准备好计算资源&#xff0c;并以弹性、可靠的方式运行您的代码。 如上所示&am…

Selenium 4.11 正式发布--再也不用手动更新chrome driver 了

Selenium 4.11.0 正式发布了&#xff0c;先来看一下主要特性。 Chrome DevTools支持的版本现在是&#xff1a;v113、v114和v115&#xff08;Firefox仍然对所有版本使用v85&#xff09; 通过Selenium Manager支持Chrome For Testing&#xff08;CfT&#xff09; Selenium Manag…

网络基础 (深信服)

一 走进网络世界 1.1.1 企业网络环境介绍 计算机网络类型&#xff1a; LAN ------本地局域网 Local Area Network&#xff1a; •通常指几千米以内的&#xff0c;可通过某种介质互联的计算机、打印机、modem或其他设备的集合 WAN ------ 广 域 网 Wide Area Network&am…

ClickHouse分布式集群部署

目录 ​编辑 一、环境说明 二、安装部署 2.1 RPM方式安装 2.1.1 安装yum-utils 2.1.2 配置yum repo源 2.1.3 yum install 下载安装clickhouse 2.2 信息配置 2.2.1 配置外网可访问地址 2.2.2 修改存储路径 2.2.2.1 新建存储目录 2.2.2.2 授权 2.2.2.3 修改配置 2.…

Tomcat的启动问题

今天去打开Tomcat的时候没反应 如下 按之前是到Tomcat目录下的bin目录下的startup.bat文件&#xff0c;双击&#xff0c;就可以启动Tomcat服务器。启动后可以 打开浏览器&#xff0c;在浏览器地址栏中输入以下地址测试&#xff1a; 1、http://localhost:8080 2、http://127.…

手撕 LFU 缓存

大家好&#xff0c;我是 方圆。LFU 的缩写是 Least Frequently Used&#xff0c;简单理解则是将使用最少的元素移除&#xff0c;如果存在多个使用次数最小的元素&#xff0c;那么则需要移除最近不被使用的元素。LFU 缓存在 LeetCode 上是一道困难的题目&#xff0c;实现起来并不…

Fair下发产物-布局DSL生成原理

一、概述 大家都知道,Flutter在release环境是以AOT模式运行的,这就决定了我们要做动态化的话无法简单的通过动态下发dart代码执行的。根据Fair团队的前期调研,我们对布局动态化和逻辑动态化的实现采用了两套不同的实现方案,对于布局部分,我们在解析dart源文件之后生成DSL…

xterm使用

xterm使用 前言1. xterm介绍2. xterm使用2.1 xterm简单示例2.2 xterm监听输入并在终端中实时显示方式1:onKey监听方式2:onData监听onData和onKey什么区别 2.3 xterm与vue整合2.3 xterm vue websocket 附录配置说明 前言 vue与xterm整合记录 1. xterm介绍 xterm 是一个基于…

jvm深入研究文档--java中的堆--详解!--jvm底层探索(1)

阿丹&#xff1a; JVM的内存分区包括以下几个部分&#xff1a; 堆区&#xff08;Heap&#xff09; - 这是JVM的主要部分&#xff0c;用于存储实例对象和大多数Java对象&#xff0c;如数组和用户定义的类。方法区&#xff08;Method Area&#xff09; - 这是线程私有的&#x…

内网穿透的应用-NAS私有云存储 - 搭建Nextcloud私有云盘并公网远程访问

文章目录 摘要1. 环境搭建2. 测试局域网访问3. 内网穿透3.1 ubuntu本地安装cpolar3.2 创建隧道3.3 测试公网访问 4 配置固定http公网地址4.1 保留一个二级子域名4.1 配置固定二级子域名4.3 测试访问公网固定二级子域名 摘要 Nextcloud,它是ownCloud的一个分支,是一个文件共享服…

利用fiddler正向代理前端请求到本地后端

前景&#xff1a;在实际开发测试环境中&#xff0c;&#xff08;前后端均已上线到测试服务器或前端以上线而后端还在开发中)。在测试过程中&#xff08;前端页面点击&#xff0c;功能测试&#xff09;发现了bug或异常点。 正常排查问题可能是先利用浏览器检查工具查看接口的返回…

Unity Bolt UGUI事件注册方式总结

Bolt插件提供了丰富的事件注册方式&#xff0c;开发者几乎不用编写任何代码就可以完成事件的注册&#xff0c;进行交互。下面是我使用UI事件注册的相关总结。 1、通过UI控件自身拖拽实现事件的注册。 Button的事件注册&#xff1a; 新建一个UnityEvent事件&#xff0c; Butt…

PASCAL VOC2012数据集详细介绍

PASCAL VOC2012数据集详细介绍 0、数据集介绍2、Pascal VOC数据集目标类别3、 数据集下载与目录结构4、目标检测任务5、语义分割任务6、实例分割任务7、类别索引与名称对应关系 0、数据集介绍 2、Pascal VOC数据集目标类别 在Pascal VOC数据集中主要包含20个目标类别&#xff…

uniapp开发h5 调用微信sdk 全网最全指南!!!! 血泪史!!!

目录 场景&#xff1a; 技术栈&#xff1a; 遇到的问题先抛出来&#xff1a; 1.通过后端同学获取调用微信sdk所需的签名过程中&#xff0c;遇到的跨域问题 2.使用微信sdk前提必须是微信容器&#xff0c;换句话说就是微信浏览器打开&#xff0c;才能使用微信sdk 3.如何在开…

方案:浅析利用AI智能识别与视频监控技术打造智慧水产养殖监管系统

一、方案背景 针对目前水产养殖集约、高产、高效、生态、安全的发展需求&#xff0c;基于智能传感、智慧物联网、人工智能、视频监控等技术打造智慧水产系统&#xff0c;成为当前行业的发展趋势。传统的人工观察水产养殖方式较为单一&#xff0c;难以及时发现人员非法入侵、偷…

Windows系统如何部署Wing FTP Server与公网远程访问【内网穿透】

Wing FTP Server安装配置结合内网穿透实现公网访问本地站点 文章目录 Wing FTP Server安装配置结合内网穿透实现公网访问本地站点前言1.Wing FTP Server下载安装2.Wing FTP Server配置部署3.安装cpolar内网穿透3.1 注册账号3.2 下载cpolar客户端3.3 登录cpolar web ui管理界面3…

ChatGLM 实现一个BERT

前言 本文包含大量源码和讲解,通过段落和横线分割了各个模块,同时网站配备了侧边栏,帮助大家在各个小节中快速跳转,希望大家阅读完能对BERT有深刻的了解。同时建议通过pycharm、vscode等工具对bert源码进行单步调试,调试到对应的模块再对比看本章节的讲解。 涉及到的jupyt…