綜合案例:使用vuex對購物車的商品數量和價格等公共數據進行狀態管理

文章目錄

        • 0.實現需求
        • 1.新建購物車模塊cart
        • 2.使用json-server模擬向后端請求數據
        • 3.在vuex請求獲取并存入數據,并映射到組件中,在組件中渲染【重點】
          • 3.1.安裝axios
          • 3.2.準備actions和mutations,獲取和存入數據到vuex中
          • 3.3.動態渲染:先用mapState映射list到組件頁面
        • 4.點擊修改數量并同步前后端【重點】
          • 4.1.要求和思路
          • 4.2.代碼
        • 5.使用getters完成總價和總數量數據的同步
          • 5.1.先提供CartFooter.vue的結構和樣式
          • 5.2.提供getters
          • 5.3. 使用getters
        • 其他
          • 1.為什么在axios在項目中要局部安裝
          • 2.Axios PATCH 方法的功能與使用

0.實現需求
  • 請求動態渲染購物車,數據存放在vuex中
  • 使用數字框修改數據
  • 動態計算總價和總數量

購物車的商品數量,商品價格以及下方的總價,總數量,是共用一個數據,
顯然,此處可以用到vuex,這也是Vuex在Vue項目中常見的使用場景之一

1.新建購物車模塊cart
  • step1:新建store/modules/cart.js
export default{namespaced:true,//state寫成這種形式的原因和data一樣:保證組件實例化后的數據獨立state(){//上面就不要const state={}了,會報錯return{list:[]}}
}
  • step2:掛載到vuex倉庫上
import cart from "@/store/modules/cart"
const store = new Vue.Store({modules:{cart}
})

驗證配置是否成功:控制臺>vue>Root>cart>namespaced

2.使用json-server模擬向后端請求數據
  • 安裝json-server
npm install json-server -g
  • 準備json數據

在vue根目錄下創建db/db.json(數據可以讓deepseek模擬)

{"cart": [{"id": 1,"name": "Wireless Keyboard","price": 49.99,"count": 2,"thumb":"https://img14.360buyimg.com/n7/jfs/t1/141271/22/14881/70446/5fb4a985E1cce213e/beb55f6d1d3221b5.jpg"},{"id": 2,"name": "Gaming Mouse","price": 59.99,"count": 1,"thumb":"https://img14.360buyimg.com/n7/jfs/t1/141271/22/14881/70446/5fb4a985E1cce213e/beb55f6d1d3221b5.jpg"},{"id": 3,"name": "External Hard Drive","price": 89.99,"count": 1,"thumb":"https://img14.360buyimg.com/n7/jfs/t1/141271/22/14881/70446/5fb4a985E1cce213e/beb55f6d1d3221b5.jpg"},{"id": 4,"name": "Bluetooth Speaker","price": 79.99,"count": 1,"thumb":"https://img14.360buyimg.com/n7/jfs/t1/141271/22/14881/70446/5fb4a985E1cce213e/beb55f6d1d3221b5.jpg"},{"id": 5,"name": "Smartphone Case","price": 19.99,"count": 3,"thumb":"https://img14.360buyimg.com/n7/jfs/t1/141271/22/14881/70446/5fb4a985E1cce213e/beb55f6d1d3221b5.jpg"},{"id": 6,"name": "Laptop Backpack","price": 39.99,"count": 1,"thumb":"https://img14.360buyimg.com/n7/jfs/t1/141271/22/14881/70446/5fb4a985E1cce213e/beb55f6d1d3221b5.jpg"},{"id": 7,"name": "USB Flash Drive","price": 14.99,"count": 5,"thumb":"https://img14.360buyimg.com/n7/jfs/t1/141271/22/14881/70446/5fb4a985E1cce213e/beb55f6d1d3221b5.jpg"},{"id": 8,"name": "Headphones","price": 69.99,"count": 1,"thumb":"https://img14.360buyimg.com/n7/jfs/t1/141271/22/14881/70446/5fb4a985E1cce213e/beb55f6d1d3221b5.jpg"},{"id": 9,"name": "Monitor Stand","price": 29.99,"count": 1,"thumb":"https://img14.360buyimg.com/n7/jfs/t1/141271/22/14881/70446/5fb4a985E1cce213e/beb55f6d1d3221b5.jpg"},{"id": 10,"name": "Desk Lamp","price": 24.99,"count": 1,"thumb":"https://img14.360buyimg.com/n7/jfs/t1/141271/22/14881/70446/5fb4a985E1cce213e/beb55f6d1d3221b5.jpg"}],"friends": [{"userID": 101,"name": "Alice Johnson","age": 28},{"userID": 102,"name": "Bob Smith","age": 34},{"userID": 103,"name": "Charlie Brown","age": 22}]
}
  • 啟動
在db目錄下打開CMD:
json-server db.json

踩坑:遇到了端口號被占用的報錯

\db>json-server db.json
node:internal/errors:478ErrorCaptureStackTrace(err);^
RangeError [ERR_SOCKET_BAD_PORT]: options.port should be >= 0 and < 65536. 

解決方法:指定端口號:json-server db.json --port:3008
在這里插入圖片描述

3.在vuex請求獲取并存入數據,并映射到組件中,在組件中渲染【重點】
3.1.安裝axios
全局安裝:npm install axios -g
局部安裝:npm installl axios --save

踩坑:錯誤地使用了全局安裝,導致在package.json中找不到axios依賴,也就調用不成功

3.2.準備actions和mutations,獲取和存入數據到vuex中

過程:actions使用axios發起異步get請求獲取數據,提交,觸發mutations中的函數,該函數更新state的狀態,
即:讓空數組list存放返回的數據(res.data)

state:{return{list:[]}
},
mutations:{updateList(state,newList){state.list=newList}
},
actions:{async getData(context){const res=await axios.get("http:localhost:3008/cart");console.log(res);//查看res的層級結構context.commit("updateList",res.data);//提交,觸發mutations中的方法}
}//在頁面中調用:App.vue
created(){//格式:$store.dispatch("模塊名/xxx")this.$store.dispatch("cart/getData")
}
3.3.動態渲染:先用mapState映射list到組件頁面
//App.vuecomputed: {...mapState("cart", ["list"]),}

此時list已經獲取后臺json文件中的cart數組中的數據作為其元素,并通過mapState映射到組件中,
因此組件可以直接使用list進行頁面渲染

//父組件App.vue
//使用v-for取出商品列表,但不在父組件直接渲染,而是設置自定義屬性item,通過父傳子,在子組件中渲染<div class="app-container"><cart-header></cart-header><cart-item v-for="item in list" :key="item.id" :item="item"></cart-item><cart-footer></cart-footer></div>
//子組件CartItem.vue
//html<div class="wrapper goods-container"><!-- 左側圖片 --><div class="left"><img :src="item.thumb" alt="" class="avatar"></div><!-- 右側商品描述 --><div class="right"><!-- 標題 --><div class="title">{{item.name}}</div><div class="info"><!-- 單價 --><div class="price">¥{{item.price}}</div><!-- 按鈕區域 --><div class="btns"><button class="btn btn-light" @click="btnClick(-1)">-</button><span class="count">{{item.count}}</span><button class="btn btn-light" @click="btnClick(1)">+</button></div></div></div></div>//js
//通過props屬性接收父組件傳過來的參數itemprops: {item:{type:Object,required:true}}//css(****不重要****)
.goods-container {display: flex;
}.left {flex: 1;padding: 10px;text-align: center;
}.right {flex: 2;padding: 10px;box-sizing: border-box;
}
.title {font-size: 16px;font-weight: bold;color: #333;margin-bottom: 10px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;
}
.price {font-size: 18px;color: #e4393c; /* 常見紅色系表示優惠價 */margin-top: 5px;
}
.btns {margin-top: 15px;
}.btns button {display: inline-block;padding: 5px 10px;margin-right: 5px;font-size: 14px;cursor: pointer;border: none;border-radius: 3px;
}/* 不同類型的按鈕樣式 */
.btns .remove-btn {background-color: #ff4d4f;color: white;
}.btns .add-to-cart {background-color: #1abc9c;color: white;
}

效果:
在這里插入圖片描述

4.點擊修改數量并同步前后端【重點】
4.1.要求和思路

點擊"+“和”-",實現數量的增減,要求不僅是vuex中的數據發生改變.后臺json文件中也會同步修改
思路:

  • 按鈕綁定點擊事件,并傳參,點擊事件中會調用actions中的方法

  • actions中的方法主要做兩件事:

    • 提交,觸發mutations方法以更新vuex狀態;
    • 使用axios.patch向后臺發送請求,局部更新count屬性
  • mutations中的方法根據匹配到的id,更新對應的count

4.2.代碼
//CartItem.vue
//"+"和"-"按鈕綁定btnClick
methods:{btnClick(num){const newCount=num+this.list.count;if(newCount<1) return;//商品數量不能少于1(商品數量為0或者刪除商品的業務邏輯單獨實現)count newId=this.list.id//調用actions方法:updateCountAsyncthis.$store.dispatch("cart/updateCountAsync",{newId,newCount})}
}//cart.js
mutations:{updateList(state,obj){//通過傳回來的id找到對應的商品goodsconst goods=state.list.find(item==>item.id===obj.id);//更新這件商品的數量goods.count=obj.count;}
},
actions:{async updateCountAsync(context,obj){//更新后端數據const res=await axios.patch(`http://localhost:3008/cart/${obj.newId}`,{count:obj.newCount})console.log(res.data)//更新前端數據context.commit("updateList",{id:obj.newId,count:obj.newCount})}
}

效果:

  • 點擊按鈕"+",商品數量隨之增加,控制臺console.log(this.item.count)同步更新
  • 打開db.json文件,該商品的count屬性被更新
5.使用getters完成總價和總數量數據的同步
5.1.先提供CartFooter.vue的結構和樣式

如下:

<template><div class="footer-container"><!-- 中間的合計 --><div class="total-section"><span>共計xxx件商品,合計:</span><span class="price">¥xxx</span></div><!-- 右側結算按鈕 --><button class="btn btn-success btn-settle">結算</button></div>
</template><style scoped>
.footer-container {display: flex;justify-content: space-between;align-items: center;background-color: #f8f8f8;padding: 15px 20px;box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.1);
}.total-section {font-size: 16px;color: #333;
}.total-section .price{font-size: 18px;color: #e60012; /* 使用醒目的顏色突出總價 */
}.btn-success {position: relative;display: inline-block;padding: 10px 20px;font-size: 16px;color: #ffffff;background-color: #e60012; /* 醒目紅色背景 */border: none;border-radius: 5px;cursor: pointer;transition: all 0.3s ease-in-out;
}.btn-success:hover {background-color: darken(#e60012, 10%); /* 懸停時加深背景色 */transform: scale(1.05); /* 增加懸停效果 */
}
</style>
5.2.提供getters
	//格式:數組.reduce((求和參數,數組屬性)=>xxx,0);//從0開始累計getters:{totalNum(state){return state.list.reduce((sum,item)=>sum+item.count,0)},totalPrice(state){return state.list.reduce((sum,item)=>sum+item.count*item.price,0)}}
5.3. 使用getters
//CartFooter.vue
//html
...<span>共計{{totalNum}}件商品,合計:</span><span class="price">{{totalPrice}}</span>//jsimport {mapGetters} from "vuex"...computed: {//格式:...mapGetters("子模塊",['要映射的屬性'])...mapGetters('cart',['totalNum','totalPrice'])
},

最終效果:
在這里插入圖片描述

其他
1.為什么在axios在項目中要局部安裝
1. 全局安裝與局部安裝的區別
當使用 npm install axios -g 進行全局安裝時,Axios 被放置在系統的全局環境中,而不是當前項目的 node_modules 文件夾中。這意味著全局安裝不會影響任何具體項目中的依賴列表,也不會更新該項目的 package.json 文件1。
因此,即使成功執行了 npm install axios -g,當前項目的 package.json 文件仍然不會有 axios 字段,這是預期行為而非錯誤。2. 導致模塊未找到的根本原因
Vue 項目運行時,默認只會查找位于當前項目目錄下的 node_modules 文件夾內的模塊。如果 Axios 是通過 -g 參數全局安裝的,則 Vue 構建工具(如 Webpack)無法識別該模塊,從而引發 Module not found: Error: Can't resolve 'axios' 錯誤33. 正確的解決方案
為了使 Axios 在項目中可用,應將其作為局部依賴安裝到當前項目中,而不是采用全局安裝的方式。以下是具體的解決步驟:
方法一:局部安裝 AXIOS 并保存到依賴項
執行以下命令將 Axios 安裝為項目的局部依賴,并自動更新 package.json 文件:
npm install axios --save
此操作會在 package.json 的 dependencies 字段中添加 Axios 條目,同時下載對應的模塊到 node_modules 文件夾中。對于像 Axios 這樣的庫,通常建議始終將其作為局部依賴安裝。這樣不僅可以確保不同項目間互不影響,還能更方便地管理版本沖突問題
2.Axios PATCH 方法的功能與使用

功能
axios.patch() 是一種用于向服務器發送部分修改的數據的方法。它通常用來更新資源的部分屬性,而不是替換整個資源。這種行為符合 RESTful API 設計原則中的“局部更新”概念

作用于后臺數據的能力
通過 axios.patch() 發送的請求會攜帶需要更新的具體字段及其新值,到指定 URL 上對應的資源。
服務器接收到這些數據后,會對目標資源執行相應的更新操作,并返回更新后的狀態或確認消息。
這種方式相比 PUT 更高效,因為它只傳輸變化的內容而非完整的對象

語法

axios.patch(url[, data[, config]])
  • url: (字符串) 表示要訪問的目標地址。
  • data: (可選, 對象或其他序列化類型) 要傳遞給服務器的信息體。
  • config: (可選, 對象) 配置選項,比如超時時間、自定義頭部等。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/79975.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/79975.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/79975.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

《數據結構初階》【順序表 + 單鏈表 + 雙向鏈表】

《數據結構初階》【順序表 單鏈表 順序表】 前言&#xff1a;先聊些其他的東西&#xff01;&#xff01;&#xff01;什么是線性表&#xff1f;什么是順序表&#xff1f;順序表的種類有哪些&#xff1f; 什么是鏈表&#xff1f;鏈表的種類有哪些&#xff1f; ---------------…

Android Retrofit框架分析(三):自動切換回主線程;bulid的過程;create方法+ServiceMethod源碼了解

目錄 Okhttp有什么不好&#xff1f;bulid的過程create方法ServiceMethodcall enqueue的過程為什么要學習源碼呢&#xff1f; 一、Okhttp有什么不好&#xff1f; Okhttp本身來說&#xff0c;是一個挺好的網絡框架&#xff0c;但&#xff0c;對于開發者而言&#xff0c;使用起…

C++ STL 基礎與多線程安全性說明文檔

C STL 基礎與多線程安全性說明文檔 一、STL 簡介 STL&#xff08;Standard Template Library&#xff0c;標準模板庫&#xff09;是 C 標準庫的重要組成部分&#xff0c;提供了常用的數據結構和算法的泛型實現&#xff0c;極大地提高了代碼的復用性和開發效率。 STL 的六大組…

數據結構之圖的分類和存儲

圖 圖(Graph)G由兩個集合V和E組成&#xff0c;記為&#xff1a;G(V,E)&#xff0c;其中V是頂點的有窮非空集合(其實就是頂點)&#xff0c;E是V 中頂點偶對的有窮集合(就是邊)。V(G)和E(G)通常分別表示圖G的頂點集合以及邊集合&#xff0c;E(G)可以為空集合&#xff0c;但是此時…

擴增子分析|微生物生態網絡穩定性評估之魯棒性(Robustness)和易損性(Vulnerability)在R中實現

一、引言 周集中老師團隊于2021年在Nature climate change發表的文章&#xff0c;闡述了網絡穩定性評估的原理算法&#xff0c;并提供了完整的代碼。自此對微生物生態網絡的評估具有更全面的指標&#xff0c;自此網絡穩定性的評估廣受大家歡迎。本系列將介紹網絡穩定性之魯棒性…

setup 函數在 Vue 3 中的作用是什么?什么時候會執行

文章目錄 前言? 一、setup() 函數的作用是什么&#xff1f;? 二、setup() 什么時候執行&#xff1f;? 三、setup() 的參數? 四、setup() 中不能做什么&#xff1f;? 五、常見用法示例? 六、總結&#xff08;適合背誦或面試回答&#xff09; <script setup> 是 **Vu…

JDBC實現--保姆級教程~

本來以為寫過一個使用python與數據庫連接的文章&#xff0c;但是今天突然發現沒有&#xff0c;那就直接寫Java與數據庫連接的吧。當然如果大家有需要可以告訴我&#xff0c;有時間的話也可以寫一個的pymysql的使用的。 數據庫有很多種&#xff0c;接下來我就以MySQL為例來進行講…

Ubuntu18.04搭建samda服務器

一.什么是Samba服務器&#xff1f; Samba服務器是一種基于開源協議實現的網絡共享服務軟件&#xff0c;主要用于在不同操作系統&#xff08;如Windows、Linux、Unix&#xff09;之間實現文件和打印機共享功能。其核心目標是解決跨平臺資源共享的兼容性問題&#xff0c;尤其是在…

《分詞算法大揭秘:BPE、BBPE、WordPiece、ULM常見方法介紹》

分詞算法是自然語言處理&#xff08;NLP&#xff09;中的一個重要預處理步驟&#xff0c;它將文本分割成更小的單元&#xff08;如單詞、子詞或字符&#xff09;。以下是幾種常見的分詞算法&#xff1a;Byte Pair Encoding (BPE)、Byte-level BPE (BBPE)、WordPiece 和 Unigram…

WordPress01 - 后臺常用功能

最近些日子研究Wordpress&#xff0c;做些簡單的筆記。 怎么安裝Wordpress&#xff0c;怎么進的后臺&#xff0c;這些咱就不嘮了哈&#xff0c;網上到處是教程。 目錄 1&#xff0c;Wordpress的后臺 1-1&#xff0c; Posts(投稿) 1-2&#xff0c;Media(媒體) 1-3&#xf…

R8周:RNN實現阿爾茨海默病診斷

&#x1f368; 本文為&#x1f517;365天深度學習訓練營中的學習記錄博客 &#x1f356; 原作者&#xff1a;K同學啊 一、前期準備 1.設置GPU import numpy as np import pandas as pd import torch from torch import nn import torch.nn as nn import torch.nn.functi…

今天python練習題

目錄 一、每日一言 二、練習題 三、效果展示 四、下次題目 五、總結 一、每日一言 不要害怕失敗&#xff0c;失敗可能成為我們前進的動力&#xff01; 二、練習題 有列表lst [[1,2,3],[4,5,6],[7,8,9]],取出其中的元素1/5/9組成新的列表 # 有列表lst [[1,2,3],[4,5,6],[…

機器人強化學習入門學習筆記(二)

基于上一篇的《機器人強化學習入門學習筆記》,在基于 MuJoCo 的仿真強化學習訓練中,除了 PPO(Proximal Policy Optimization)之外,還有多個主流強化學習算法可用于訓練機器人直行或其他復雜動作。 ?? 一、常見強化學習算法對比(可用于 MuJoCo) 算法類型特點適合場景PP…

用 DuckDB 高效分析 JSON 數據:從入門到實戰

解析 JSON 文件進行分析常常充滿挑戰。無論你是在處理 API 響應、日志文件&#xff0c;還是應用數據&#xff0c;如果沒有合適的工具&#xff0c;分析 JSON 都會非常耗時。 借助 DuckDB&#xff0c;你可以直接用 SQL 查詢復雜的 JSON 文件&#xff0c;無需編寫復雜的解析代碼或…

從貼牌到品牌:出海官網如何讓中國制造“貴”起來?

在全球經濟一體化的當下&#xff0c;中美關稅戰如同一記重錘&#xff0c;給國際貿易格局帶來了巨大震蕩。自貿易摩擦爆發以來&#xff0c;雙方多次調整關稅政策&#xff0c;涉及的商品種類不斷增多&#xff0c;稅率持續攀升&#xff0c;眾多中國企業的出口業務遭受重創&#xf…

react-13react中外部css引入以及style內聯樣式(動態className與動態style)

1. 外部css文件 - 普通引入 1.1 創建一個 CSS 文件&#xff0c;MyComponent.css。 /* MyComponent.css */ .my-class {color: red;font-size: 20px; } 1.2 組件中import引入 import React from react; import ./MyComponent.css; // 引入 CSS 文件function MyComponent() {r…

n8n 與智能體構建:開發自動化 AI 作業的基礎平臺

n8n 是一款開源的自動化流程構建平臺&#xff0c;通過其模塊化節點系統&#xff0c;開發者可以快速實現跨平臺的任務編排、數據集成與智能交互。當 n8n 與大型語言模型&#xff08;LLM&#xff09;結合時&#xff0c;就能構建出具備感知、推理、執行能力的 AI 智能體&#xff0…

14.Spring Boot 3.1.5 集成 Spring Security 進行訪問控制

14.Spring Boot 3.1.5 集成 Spring Security 進行訪問控制 Spring Security 是一個強大且高度可定制的認證和訪問控制框架&#xff0c;專為基于 Spring 的應用程序設計。它為基于 Java EE 的企業應用程序提供了全面的安全解決方案&#xff0c;包括 Web 應用程序安全和方法級安…

Linux學習筆記(二):Linux權限管理

文章目錄 一、Linux下用戶的分類1. Linux下用戶分為兩類&#xff1a;2. 這兩類用戶如何進行切換呢&#xff1f;3. 短暫提權 二、何為權限1. 什么是權限2. Linux的文件后綴意義 三、修改權限1. 設置文件的訪問權限——chmod2. 修改文件擁有者——chown3. 修改文件所屬組——chgr…

學習alpha,第2個alpha

alphas (-1 * ts_corr(rank(ts_delta(log(volume), 2)), rank(((close - open) / open)), 6)) 先分析操作符從左到右 ts_corr: Pearson 相關度量兩個變量之間的線性關系。當變量呈正態分布且關系呈線性時&#xff0c;它最有效。 ts_corr(vwap, close, 20)是一個計算時間序列相…