【vue3】購物車實戰:從狀態管理到用戶體驗的全流程實現

在電商項目中,購物車是核心功能之一,需要兼顧數據一致性、用戶體驗和邏輯復雜度。

本文結合 Vue3 + Pinia 技術棧,詳細講解如何實現一個高效且易用的購物車系統,重點剖析?添加購物車?和?頭部購物車預覽?的核心邏輯與實現細節。

一、技術選型與核心思路

1. 技術棧選擇

  • 狀態管理:使用?Pinia?實現購物車數據的集中管理,支持持久化存儲(通過?pinia-plugin-persistedstate),確保刷新頁面數據不丟失。
  • 組件庫:基于 Element Plus 實現表單、按鈕等交互組件,結合自定義 CSS 實現懸浮層動畫和復雜布局。
  • 接口交互:通過 Axios 封裝購物車相關接口,區分登錄 / 未登錄狀態,實現本地臨時存儲與服務器數據的無縫切換。

2. 核心設計思路

  • 雙模式處理:未登錄用戶將購物車數據暫存于本地 Pinia,登錄后同步至服務器;已登錄用戶直接操作服務器接口,保證數據一致性。
  • 響應式渲染:利用 Pinia 的響應式特性,購物車數據變化時自動更新組件視圖,無需手動操作 DOM。
  • 用戶體驗優化:通過懸浮層動畫、漸變顯示刪除按鈕、實時計算總價等細節,提升交互流暢度。

二、添加購物車:分場景數據處理

1. Pinia 狀態定義與 Action 封裝

在?cartStore.js?中定義購物車狀態?cartList,并封裝?addCart?方法處理添加邏輯:

// src/stores/cartStore.js
import { defineStore, ref, computed } from 'pinia';
import { useUserStore } from './userStore';
import { insertCartAPI } from '@/apis/cart';export const useCartStore = defineStore('cart', () => {const userStore = useUserStore();const isLogin = computed(() => userStore.userInfo.token); // 判斷登錄狀態const cartList = ref([]); // 購物車商品列表// 添加購物車(核心邏輯)const addCart = async (goods) => {const { skuId, count } = goods;if (isLogin.value) {// 已登錄:調用接口添加至服務器購物車await insertCartAPI({ skuId, count });updateNewList(); // 同步最新購物車數據} else {// 未登錄:本地處理(存在則數量+1,否則新增)const item = cartList.value.find((item) => item.skuId === skuId);if (item) {// 找到了item.count++} else {// 沒找到cartList.value.push(goods)}}};// 獲取最新購物車列表(登錄狀態專用)const updateNewList = async () => {const res = await findNewCartListAPI(); // 接口調用cartList.value = res.result;};return { cartList, addCart, updateNewList };
}, { persist: true }); // 啟用持久化存儲,數據自動同步至 localStorage

2. 接口封裝與調用

在?cart.js?中定義添加購物車的接口,遵循 RESTful 規范:

// src/apis/cart.js
import request from '@/utils/http';// 加入購物車接口(登錄狀態)
export const insertCartAPI = ({ skuId, count }) => {return request({url: '/member/cart',method: 'POST',data: { skuId, count },});
};

3. 組件觸發添加操作

在商品詳情頁或按鈕點擊事件中,構造商品對象并調用?addCart

// 示例:商品詳情頁添加按鈕
const handleAddToCart = () => {const goods = {skuId: product.skuId, // 商品唯一標識count: 1, // 默認添加數量name: product.name,price: product.price,picture: product.mainPictures[0], // 主圖attrsText: product.specsText, // 規格信息(如顏色、尺碼)selected: true, // 默認選中該商品};const cartStore = useCartStore();cartStore.addCart(goods); // 觸發添加邏輯
};

三、頭部購物車預覽:懸浮層交互與數據渲染

1. 組件結構與數據綁定

通過?HeadCart.vue?實現頁面頭部的購物車圖標懸浮層,實時展示購物車商品列表:

<!-- src/components/HeadCart.vue -->
<script setup>
import { useCartStore } from '@/stores/cartStore';
const cartStore = useCartStore();
</script><template><div class="cart"><!-- 購物車圖標與未讀數量 --><a class="curr" href="javascript:;"><i class="iconfont icon-cart"></i><em>{{ cartStore.cartList.length }}</em> <!-- 實時顯示商品總數 --></a><!-- 懸浮層(鼠標懸停顯示) --><div class="layer"><div class="list"><!-- 商品列表循環渲染 --><div class="item" v-for="item in cartStore.cartList" :key="item.skuId"><RouterLink to="/cartlist"> <!-- 點擊跳轉購物車詳情頁 --><img :src="item.picture" alt="" /> <!-- 商品圖片 --><div class="center"><p class="name ellipsis-2">{{ item.name }}</p> <!-- 商品名稱 --><p class="attr ellipsis">{{ item.attrsText }}</p> <!-- 規格信息 --></div><div class="right"><p class="price">&yen;{{ item.price }}</p> <!-- 單價 --><p class="count">x{{ item.count }}</p> <!-- 數量 --></div></RouterLink><!-- 刪除按鈕(懸停顯示) --><i class="iconfont icon-close-new" @click="cartStore.delCart(item.skuId)"></i></div></div><!-- 底部操作欄 --><div class="foot"><div class="total"><p>共 {{ cartStore.allCount }} 件商品</p> <!-- 總數量(計算屬性) --><p>&yen; {{ cartStore.allPrice.toFixed(2) }}</p> <!-- 總價(計算屬性) --></div><el-button @click="$router.push('/cartlist')">去購物車結算</el-button></div></div></div>
</template>

2. 計算屬性:實時統計數據

在?cartStore.js?中通過?computed?實現總數量和總價的實時計算:

// cartStore.js 補充計算屬性
const allCount = computed(() => cartList.value.reduce((acc, item) => acc + item.count, 0)
); // 總商品數(各商品數量累加)const allPrice = computed(() => cartList.value.reduce((acc, item) => acc + item.count * item.price, 0)
); // 總價(數量×單價累加)

3. 刪除功能:本地與接口雙模式處理

在?cartStore.js?中封裝?delCart?方法,根據登錄狀態執行不同邏輯:

// cartStore.js 刪除邏輯
const delCart = async (skuId) => {if (isLogin.value) {// 已登錄:調用接口刪除(支持批量刪除)await delCartAPI([skuId]); // 傳遞商品ID數組updateNewList(); // 刷新購物車列表} else {// 未登錄:本地刪除(通過下標移除)const idx = cartList.value.findIndex((item) => item.skuId === skuId);cartList.value.splice(idx, 1);}
};

4. 樣式實現:懸浮層動畫與細節優化

通過 SCSS 實現懸浮層的漸變顯示、刪除按鈕懸停顯示等效果:

/* 懸浮層初始隱藏,懸停時漸變顯示 */
.cart .layer {opacity: 0;transform: translateY(-200px) scale(1, 0); /* 向上偏移并縮放隱藏 */transition: all 0.4s 0.2s; /* 動畫過渡 */&:hover {opacity: 1;transform: none; /* 恢復原位 */}
}/* 刪除按鈕默認隱藏,懸停商品時顯示 */
.item i {opacity: 0;transition: all 0.5s;&:hover {cursor: pointer;}
.item:hover i { opacity: 1; }/* 滾動條樣式自定義 */
.list {overflow: auto;&::-webkit-scrollbar-thumb {background: #eee;border-radius: 10px;}
}

四、核心技術點總結

1. Pinia 狀態管理優勢

  • 響應式:通過?ref?定義的?cartList?自動觸發組件重新渲染,無需手動調用?forceUpdate
  • 持久化:配置?persist: true?后,數據自動存儲至?localStorage,刷新頁面或重啟瀏覽器后數據依然存在。
  • 模塊化:將購物車相關的?stateactioncomputed?集中在?cartStore?中,方便后續擴展(如合并登錄前后的購物車數據)。

2. 登錄與未登錄邏輯分離

  • 未登錄:所有操作(添加、刪除)均在本地?cartList?中進行,避免無效的網絡請求,提升離線體驗。
  • 已登錄:通過接口與服務器交互,確保多設備數據同步,同時在操作后刷新本地列表,保持數據一致。

3. 用戶體驗細節

  • 實時反饋:頭部懸浮層實時顯示商品總數和總價,無需跳轉頁面即可查看購物車狀態。
  • 交互動畫:懸浮層的漸變顯示和刪除按鈕的漸顯效果,增強操作反饋,減少用戶認知成本。
  • 響應式布局:通過彈性盒子(Flex)和百分比單位,確保懸浮層在不同屏幕尺寸下正常顯示。

五、總結與實現效果

頭部購物車添加刪除

本文通過?Pinia 狀態管理?和?分場景邏輯處理,實現了一個健壯且易用的購物車系統。后續可進一步擴展以下功能:

  1. 全選與單選功能:通過?selected?字段標記商品選中狀態,結合計算屬性實現全選邏輯。
  2. 數量增減組件:使用 Element Plus 的?InputNumber?組件,支持用戶直接修改購物車商品數量。
  3. 合并購物車:用戶登錄后,將本地臨時購物車數據與服務器數據合并,避免重復添加。

購物車功能的核心在于?數據一致性?和?用戶體驗?的平衡,通過合理的狀態管理和清晰的邏輯分層,能夠有效降低開發復雜度,提升項目可維護性。

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

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

相關文章

卡洛詩西餐廳,以“中式西餐”為核心戰略

在餐飲市場的激烈競爭中&#xff0c;“本土化”是許多國際餐飲品牌難以跨越的鴻溝——要么因水土不服黯然退場&#xff0c;要么因過度妥協失去特色。然而&#xff0c;卡洛詩以“中式西餐”為核心戰略&#xff0c;將西餐與國內飲食文化深度融合&#xff0c;不僅破解了西餐本土化…

28-29【動手學深度學習】批量歸一化 + ResNet

1. 批量歸一化 1.1 原理 當神經網絡比較深的時候會發現&#xff1a;數據在下面&#xff0c;損失函數在上面&#xff0c;這樣會出現什么問題&#xff1f; 正向傳遞的時候&#xff0c;數據是從下往上一步一步往上傳遞反向傳遞的時候&#xff0c;數據是從上面往下傳遞&#xff0…

【Linux網絡】Http服務優化 - 增加請求后綴、狀態碼描述、重定向、自動跳轉及注冊多功能服務

&#x1f4e2;博客主頁&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;博客倉庫&#xff1a;https://gitee.com/JohnKingW/linux_test/tree/master/lesson &#x1f4e2;歡迎點贊 &#x1f44d; 收藏 ?留言 &#x1f4dd; 如有錯誤敬請指正&#xff01; &…

AIGC(生成式AI)試用 32 -- AI做軟件程序測試 3

總結之前的AI做程序測試過程&#xff0c;試圖優化提問方式&#xff0c;整合完成的AI程序測試提問&#xff0c;探索更多可能的AI測試 AIGC&#xff08;生成式AI&#xff09;試用 30 -- AI做軟件程序測試 1 AIGC&#xff08;生成式AI&#xff09;試用 31 -- AI做軟件程序…

C語言實現迪杰斯特拉算法進行路徑規劃

使用C語言實現迪杰斯特拉算法進行路徑規劃 迪杰斯特拉算法是一種用于尋找加權圖中最短路徑的經典算法。它特別適合用于計算從一個起點到其他所有節點的最短路徑&#xff0c;前提是圖中的邊權重為非負數。 一、迪杰斯特拉算法的基本原理 迪杰斯特拉算法的核心思想是“貪心法”…

引領印尼 Web3 變革:Mandala Chain 如何助力 1 億用戶邁向數字未來?

當前 Web3 的發展正處于關鍵轉折點&#xff0c;行業亟需吸引新用戶以推動 Web3 的真正大規模采用。然而&#xff0c;大規模采用面臨著核心挑戰&#xff1a;數據泄露風險、集中存儲的安全漏洞、跨系統互操作性障礙&#xff0c;以及低效的服務訪問等問題。如何才能真正突破這些瓶…

WebSocket是h5定義的,雙向通信,節省資源,更好的及時通信

瀏覽器和服務器之間的通信更便利&#xff0c;比http的輪詢等效率提高很多&#xff0c; WebSocket并不是權限的協議&#xff0c;而是利用http協議來建立連接 websocket必須由瀏覽器發起請求&#xff0c;協議是一個標準的http請求&#xff0c;格式如下 GET ws://example.com:3…

Kaamel白皮書:IoT設備安全隱私評估實踐

1. IoT安全與隱私領域的現狀與挑戰 隨著物聯網技術的快速發展&#xff0c;IoT設備在全球范圍內呈現爆發式增長。然而&#xff0c;IoT設備帶來便捷的同時&#xff0c;也引發了嚴峻的安全與隱私問題。根據NSF&#xff08;美國國家科學基金會&#xff09;的研究表明&#xff0c;I…

php安裝swoole擴展

PHP安裝swoole擴展 Swoole官網 安裝準備 安裝前必須保證系統已經安裝了下列軟件 4.8 版本需要 PHP-7.2 或更高版本5.0 版本需要 PHP-8.0 或更高版本6.0 版本需要 PHP-8.1 或更高版本gcc-4.8 或更高版本makeautoconf 安裝Swool擴展 安裝官方文檔安裝后需要再php.ini中增加…

服務器傳輸數據存儲數據建議 傳輸慢的原因

一、JSON存儲的局限性 1. 性能瓶頸 全量讀寫&#xff1a;JSON文件通常需要整體加載到內存中才能操作&#xff0c;當數據量大時&#xff08;如幾百MB&#xff09;&#xff0c;I/O延遲和內存占用會顯著增加。 無索引機制&#xff1a;查找數據需要遍歷所有條目&#xff08;時間復…

Android四大核心組件

目錄 一、為什么需要四大組件&#xff1f; 二、Activity&#xff1a;看得見的界面 核心功能 生命周期圖解 代碼示例 三、Service&#xff1a;看不見的勞動者 兩大類型 生命周期對比 注意陷阱 四、BroadcastReceiver&#xff1a;消息傳遞專員 兩種注冊方式 廣播類型 …

「Mac暢玩AIGC與多模態01」架構篇01 - 展示層到硬件層的架構總覽

一、概述 AIGC&#xff08;AI Generated Content&#xff09;系統由多個結構層級組成&#xff0c;自上而下涵蓋交互界面、API 通信、模型推理、計算框架、底層驅動與硬件支持。本篇梳理 AIGC 應用的六層體系結構&#xff0c;明確各組件在系統中的職責與上下游關系&#xff0c;…

[MERN 項目實戰] MERN Multi-Vendor 電商平臺開發筆記(v2.0 從 bug 到結構優化的工程記錄)

[MERN 項目實戰] MERN Multi-Vendor 電商平臺開發筆記&#xff08;v2.0 從 bug 到結構優化的工程記錄&#xff09; 其實之前沒想著這么快就能把 2.0 的筆記寫出來的&#xff0c;之前的預期是&#xff0c;下一個階段會一直維持到將 MERN 項目寫完&#xff0c;畢竟后期很多東西都…

互斥量函數組

頭文件 #include <pthread.h> pthread_mutex_init 函數原型&#xff1a; int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr); 函數參數&#xff1a; mutex&#xff1a;指向要初始化的互斥量的指針。 attr&#xf…

互聯網的下一代脈搏:深入理解 QUIC 協議

互聯網的下一代脈搏&#xff1a;深入理解 QUIC 協議 互聯網是現代社會的基石&#xff0c;而數據在其中高效、安全地傳輸是其運轉的關鍵。長期以來&#xff0c;傳輸層的 TCP&#xff08;傳輸控制協議&#xff09;一直是互聯網的主力軍。然而&#xff0c;隨著互聯網應用場景的日…

全球城市范圍30米分辨率土地覆蓋數據(1985-2020)

Global urban area 30 meter resolution land cover data (1985-2020) 時間分辨率年空間分辨率10m - 100m共享方式保護期 277 天 5 時 42 分 9 秒數據大小&#xff1a;8.98 GB數據時間范圍&#xff1a;1985-2020元數據更新時間2024-01-11 數據集摘要 1985~2020全球城市土地覆…

【Vue】單元測試(Jest/Vue Test Utils)

個人主頁&#xff1a;Guiat 歸屬專欄&#xff1a;Vue 文章目錄 1. Vue 單元測試簡介1.1 為什么需要單元測試1.2 測試工具介紹 2. 環境搭建2.1 安裝依賴2.2 配置 Jest 3. 編寫第一個測試3.1 組件示例3.2 編寫測試用例3.3 運行測試 4. Vue Test Utils 核心 API4.1 掛載組件4.2 常…

數據湖的管理系統管什么?主流產品有哪些?

一、數據湖的管理系統管什么&#xff1f; 數據湖的管理系統主要負責管理和優化存儲在數據湖中的大量異構數據&#xff0c;確保這些數據能夠被有效地存儲、處理、訪問和治理。以下是數據湖管理系統的主要職責&#xff1a; 數據攝入管理&#xff1a;管理系統需要支持從多種來源&…

英文中日期讀法

英文日期的讀法和寫法因地區&#xff08;英式英語與美式英語&#xff09;和正式程度有所不同&#xff0c;以下是詳細說明&#xff1a; 一、日期格式 英式英語 (日-月-年) 寫法&#xff1a;1(st) January 2023 或 1/1/2023讀法&#xff1a;"the first of January, twenty t…

衡量矩陣數值穩定性的關鍵指標:矩陣的條件數

文章目錄 1. 定義2. 為什么要定義條件數&#xff1f;2.1 分析線性系統 A ( x Δ x ) b Δ b A(x \Delta x) b \Delta b A(xΔx)bΔb2.2 分析線性系統 ( A Δ A ) ( x Δ x ) b (A \Delta A)(x \Delta x) b (AΔA)(xΔx)b2.3 定義矩陣的條件數 3. 性質及幾何意義3…