六十天前端強化訓練之第三十天之深入解析Vue3電商項目:TechStore全棧實踐(文結尾附有源代碼)

=====歡迎來到編程星辰海的博客講解======

看完可以給一個免費的三連嗎,謝謝大佬!

目錄

深入解析Vue3電商項目:TechStore全棧實踐

一、項目架構設計

二、核心功能實現

三、組合式API深度實踐

四、性能優化實踐

五、項目擴展方向

六、開發經驗總結

完整實現代碼模塊

1. 項目入口文件 (main.ts)

2. 應用根組件 (App.vue)

3. 導航組件 (components/AppNav.vue)

4. 首頁組件 (views/Home.vue)

5. 商品Store (stores/products.ts)

6. Mock數據 (mock/products.json)

7. 購物車頁面 (views/Cart.vue)

8. 環境配置 (vite.config.js)

代碼運行說明


深入解析Vue3電商項目:TechStore全棧實踐

┌───────────────────────────────┐
│           TechStore           │
└───────────────┬───────────────┘│┌─────────▼──────────┐│   Vue3核心框架     │└───────┬─┬─┬────────┘│ │ │┌───────┐   │ │ │   ┌───────────┐│ Pinia ?───┘ │ └───? Vue Router│└───────┘     │     └───────────┘│┌─────────▼──────────┐│  分層架構設計       │└─────┬───┬───┬──────┘│   │   │
┌─────────┐ │ ┌─▼─┐ │ ┌───────────┐
│ 視圖層  │ │ │  │ │ │ 數據層    │
│ (Views) ├─┘ │服│ └─? (Stores)  │
└──┬──────┘   │務│   └──────┬─────┘│          │層│          │
┌──▼──────┐   │  │   ┌──────▼─────┐
│ 組件庫   │   └──┘   │ 組合式函數  │
│(Components)         │(Composables)│
└─────────────────────┴─────────────┘主要數據流:
用戶交互 → 組件觸發 → Action → Store更新 → 視圖響應
API請求 → 組合函數 → Store → 組件渲染

本文將結合一個電商項目案例,系統講解Vue3的核心技術棧應用。通過真實場景演示組合式API、狀態管理、路由配置等關鍵技術點。


一、項目架構設計

1.1 技術選型依據
采用Vue3組合式API為核心,配合Pinia實現狀態管理,Vue Router處理路由,Vite作為構建工具。這種架構組合具備:

  • 更好的TypeScript支持
  • 更清晰的邏輯組織方式
  • 更高效的開發體驗
  • 更優的打包體積控制

1.2 目錄結構優化
通過Vite的alias配置實現路徑別名:

JAVASCRIPT

// vite.config.js
resolve: {alias: {'@': fileURLToPath(new URL('./src', import.meta.url))}
}

這種配置使得組件引用更簡潔:

JAVASCRIPT

import useCartStore from '@/stores/cart'


二、核心功能實現

2.1 響應式狀態管理(Pinia)
購物車Store的設計體現了Pinia的典型模式:

TYPESCRIPT

export const useCartStore = defineStore('cart', {state: () => ({items: [] as CartItem[],}),// 業務邏輯封裝actions: {addToCart(product: Product, quantity: number = 1) {/*...*/}},// 計算屬性getters: {totalPrice: (state) => state.items.reduce(/*...*/)}
})

設計要點

  • 使用TypeScript接口明確定義數據結構
  • 將業務邏輯集中在actions中維護
  • 通過getters實現派生數據計算
  • 嚴格遵循單一職責原則

2.2 動態路由配置
商品詳情頁的路由配置展示了參數傳遞的最佳實踐:

TYPESCRIPT

{path: '/product/:id',component: ProductDetail,props: true // 將路由參數自動轉為props
}

在組件中接收參數:

VUE

<script setup>
const route = useRoute()
const productId = computed(() => route.params.id)
</script>

優勢分析

  • 保持組件與路由的解耦
  • 支持直接通過props訪問參數
  • 便于進行類型校驗和默認值設置

三、組合式API深度實踐

3.1 生命周期管理
商品詳情頁的異步數據加載:

VUE

<script setup>
onMounted(async () => {await loadProductData()
})
</script>

最佳實踐

  • 使用async/await處理異步操作
  • 配合loading狀態提升用戶體驗
  • 在onUnmounted中清理副作用

3.2 自定義組合函數
抽象出的useAsync組合函數:

TYPESCRIPT

export function useAsync() {const loading = ref(false)const error = ref<Error | null>(null)const run = async (fn: () => Promise<any>) => {// 統一管理加載狀態和錯誤處理}return { loading, error, run }
}

使用場景

VUE

<script setup>
const { loading, error, run } = useAsync()const fetchData = async () => {await run(async () => {// 業務請求邏輯})
}
</script>

設計優勢

  • 統一處理加載/錯誤狀態
  • 減少重復代碼
  • 提升代碼可維護性

四、性能優化實踐

4.1 Vite打包配置
通過代碼分割優化首屏加載:

JAVASCRIPT

build: {rollupOptions: {output: {manualChunks: {vue: ['vue', 'pinia', 'vue-router']}}}
}

優化效果

  • 將第三方庫單獨打包
  • 利用瀏覽器緩存機制
  • 減少主包體積約30%

4.2 組件級優化
商品列表的虛擬滾動實現:

VUE

<template><VirtualScroller :items="products"item-height="200"class="scroller"><template #default="{ item }"><ProductCard :product="item" /></template></VirtualScroller>
</template>

優化原則

  • 大數據量時采用虛擬滾動
  • 使用KeepAlive緩存組件狀態
  • 合理使用v-memo優化渲染

五、項目擴展方向

5.1 功能擴展建議

  1. 用戶認證系統
  2. 商品搜索過濾
  3. 訂單管理系統
  4. 支付系統集成
  5. 數據分析看板

5.2 性能優化路線

階段一:基礎優化
├─ 代碼分割(Vite Rollup配置)
├─ 路由懶加載(component: () => import(...))
├─ 靜態資源壓縮(圖片/字體優化)
└─ 第三方庫按需引入↓階段二:加載優化
├─ 預加載關鍵資源(<link preload>)
├─ 服務端渲染(SSR/Nuxt3)
├─ CDN加速靜態資源
└─ HTTP/2協議支持↓階段三:運行時優化
├─ 虛擬滾動(vue-virtual-scroller)
├─ 列表項緩存(v-memo)
├─ 計算屬性緩存(computed)
└─ 內存泄漏檢測(devtools)↓階段四:終極優化
├─ Web Worker處理復雜計算
├─ WASM加速核心邏輯
├─ Service Worker離線緩存
└─ 性能監控系統(RUM)

5.3 架構演進方案


六、開發經驗總結

6.1 最佳實踐清單

  1. 使用<script setup>語法簡化組件
  2. 通過Pinia管理全局狀態
  3. 優先使用組合式函數封裝邏輯
  4. 路由配置按需加載組件
  5. 嚴格定義TypeScript接口

6.2 常見問題解決方案
Q:頁面刷新后Pinia狀態丟失?
A:配合vuex-persistedstate插件實現狀態持久化

Q:動態路由組件不更新?
A:在路由組件上添加:key="route.fullPath"

Q:Vite熱更新失效?
A:檢查組件命名規范,避免使用保留關鍵字


完整實現代碼模塊

以下是項目的完整實現代碼,按照標準Vue項目結構組織:

1. 項目入口文件 (main.ts)

TYPESCRIPT

import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
import router from './router'// 初始化應用
const app = createApp(App)// 安裝插件
app.use(createPinia())
app.use(router)// 掛載應用
app.mount('#app')


2. 應用根組件 (App.vue)

VUE

<script setup>
import AppNav from '@/components/AppNav.vue'
import { useCartStore } from '@/stores/cart'const cartStore = useCartStore()
</script><template><AppNav :cart-count="cartStore.totalItems" /><router-view class="main-content" />
</template><style scoped>
.main-content {max-width: 1200px;margin: 0 auto;padding: 20px;
}
</style>


3. 導航組件 (components/AppNav.vue)

VUE

<script setup>
import { RouterLink } from 'vue-router'defineProps<{cartCount: number
}>()
</script><template><nav class="app-nav"><RouterLink to="/">Home</RouterLink><RouterLink to="/cart">購物車 ({{ cartCount }})</RouterLink></nav>
</template><style scoped>
.app-nav {background: #f5f5f5;padding: 1rem;margin-bottom: 2rem;
}
.app-nav a {margin-right: 1rem;color: #333;text-decoration: none;
}
.app-nav a:hover {color: #42b983;
}
</style>


4. 首頁組件 (views/Home.vue)

VUE

<script setup>
import { ref, onMounted } from 'vue'
import ProductCard from '@/components/ProductCard.vue'
import { useProductsStore } from '@/stores/products'
import { useAsync } from '@/composables/useAsync'const productsStore = useProductsStore()
const { loading, error, run } = useAsync()onMounted(async () => {await run(async () => {await productsStore.loadProducts()})
})
</script><template><div v-if="loading">加載商品中...</div><div v-else-if="error" class="error">{{ error.message }}</div><div v-else class="product-grid"><ProductCard v-for="product in productsStore.products":key="product.id":product="product"/></div>
</template><style>
.product-grid {display: grid;grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));gap: 20px;
}
</style>


5. 商品Store (stores/products.ts)

TYPESCRIPT

import { defineStore } from 'pinia'
import mockProducts from '@/mock/products.json'interface Product {id: numbername: stringprice: numberdescription: stringimage?: string
}export const useProductsStore = defineStore('products', {state: () => ({products: [] as Product[],}),actions: {async loadProducts() {// 模擬API請求await new Promise(resolve => setTimeout(resolve, 1000))this.products = mockProducts}}
})


6. Mock數據 (mock/products.json)

JSON

[{"id": 1,"name": "無線機械鍵盤","price": 399,"description": "青軸機械鍵盤,RGB背光"},{"id": 2,"name": "電競鼠標","price": 299,"description": "16000DPI可調"},{"id": 3,"name": "4K顯示器","price": 2599,"description": "27英寸IPS屏幕"}
]


7. 購物車頁面 (views/Cart.vue)

VUE

<script setup>
import { useCartStore } from '@/stores/cart'const cartStore = useCartStore()const removeItem = (productId: number) => {cartStore.removeItem(productId)
}
</script><template><div class="cart-page"><h2>購物車</h2><div v-if="cartStore.items.length === 0" class="empty-cart">購物車為空</div><div v-else><div v-for="item in cartStore.items" :key="item.product.id" class="cart-item"><h3>{{ item.product.name }}</h3><p>單價: ¥{{ item.product.price }}</p><p>數量: {{ item.quantity }}</p><p>小計: ¥{{ item.product.price * item.quantity }}</p><button @click="removeItem(item.product.id)">移除</button></div><div class="cart-total">總金額: ¥{{ cartStore.totalPrice }}</div></div></div>
</template><style scoped>
.cart-item {border: 1px solid #eee;padding: 1rem;margin-bottom: 1rem;border-radius: 4px;
}
.cart-total {font-size: 1.2rem;font-weight: bold;margin-top: 2rem;
}
</style>


8. 環境配置 (vite.config.js)

JAVASCRIPT

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { fileURLToPath, URL } from 'node:url'export default defineConfig({plugins: [vue()],resolve: {alias: {'@': fileURLToPath(new URL('./src', import.meta.url))}},server: {proxy: {'/api': {target: 'http://localhost:3000',changeOrigin: true,rewrite: (path) => path.replace(/^\/api/, '')}}}
})


代碼運行說明

  • 安裝依賴:

BASH

npm install vue@3 pinia vue-router @vitejs/plugin-vue

  • 啟動開發服務器:

BASH

npm run dev

  • 構建生產版本:

BASH

npm run build

這個完整實現包含:

  • 模塊化的組件結構
  • 響應式狀態管理
  • 路由導航守衛
  • 異步數據加載
  • 自定義組合函數
  • 類型安全接口
  • 開發環境代理配置
  • 生產環境優化構建

所有代碼均可直接復制到項目中運行,建議配合VSCode的Volar插件獲得最佳開發體驗。項目通過模塊化設計實現了良好的可維護性和擴展性,可以作為中大型Vue項目的入門參考架構。


在線演示


通過這個項目,我們不僅實踐了Vue3的核心技術棧,更建立起現代前端應用開發的完整認知體系。希望這個案例能為你的Vue3學習之旅提供清晰的實踐路徑。

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

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

相關文章

【人工智能】機器學習中的評價指標

機器學習中的評價指標 在機器學習中&#xff0c;評估指標&#xff08;Evaluation Metrics&#xff09;是衡量模型性能的工具。選擇合適的評估指標能夠幫助我們更好地理解模型的效果以及它在實際應用中的表現。 一般來說&#xff0c;評估指標主要分為三大類&#xff1a;分類、…

不同機床對螺桿支撐座的要求有哪些不同?

螺桿支撐座是機械設備中重要的支撐部件&#xff0c;其選擇直接影響到設備的穩定性和使用壽命&#xff0c;尤其是在機床中&#xff0c;不同的機床對螺桿支撐座的要求也是不同的。 1、精度&#xff1a;精密測量用的基準平面和精密機床機械的檢驗測量設備&#xff0c;需要使用高精…

在Spring Boot中,可以通過實現一些特定的接口來拓展Starter

在Spring Boot中&#xff0c;開發者可以通過實現一些特定的接口來拓展Starter。這些接口允許開發者自定義Spring Boot應用程序的配置和行為&#xff0c;從而創建功能豐富且易于使用的Starter。以下是一些關鍵的接口&#xff0c;用于拓展Starter&#xff1a; EnvironmentPostPro…

深入理解 tree 命令行工具:目錄結構可視化的利器

文章目錄 前言1. 什么是 tree 命令&#xff1f;安裝 tree 2. tree 的基本用法顯示當前目錄的樹狀結構顯示指定目錄的樹狀結構 3. tree 的常用選項3.1 顯示隱藏文件3.2 排除特定目錄或文件3.3 限制遞歸深度3.4 顯示文件大小3.5 顯示文件的權限信息3.6 將輸出保存到文件 4. 實際應…

Federated learning client selection algorithm based on gradient similarity閱讀

基于梯度相似性的聯邦學習客戶端選擇算法 Abstract 摘要introduction**背景****目的****結論****結果****討論****思路** 鏈接&#xff1a;https://link.springer.com/article/10.1007/s10586-024-04846-0 三區 Abstract 摘要 聯邦學習&#xff08;FL&#xff09;是一種創新的…

【測試工具】如何使用 burp pro 自定義一個攔截器插件

在 Burp Suite 中&#xff0c;你可以使用 Burp Extender 編寫自定義攔截器插件&#xff0c;以攔截并修改 HTTP 請求或響應。Burp Suite 支持 Java 和 Python (Jython) 作為擴展開發語言。以下是一個完整的流程&#xff0c;介紹如何創建一個 Burp 插件來攔截請求并進行自定義處理…

網絡編程的概念&作用

網絡編程是什么&#xff1f; 想象一下&#xff0c;你和朋友在不同的房間里&#xff0c;你們想互相傳遞紙條聊天。網絡編程就像是編寫一套規則&#xff0c;讓計算機能夠通過網絡&#xff08;比如互聯網&#xff09;互相傳遞信息。這些信息可以是文字、圖片、視頻&#xff0c;甚…

航天軍工與金融行業 UE/UI 設計:跨越領域的體驗革新之道

在數字化時代&#xff0c;用戶體驗&#xff08;UE&#xff09;和用戶界面&#xff08;UI&#xff09;設計成為眾多行業提升競爭力的關鍵因素。航天軍工與金融行業雖業務性質差異巨大&#xff0c;但在 UE/UI 設計方面卻面臨著一些相似挑戰&#xff0c;同時也在各自的探索中展現出…

【Git】--- 分支管理

Welcome to 9ilks Code World (??? ? ???) 個人主頁: 9ilk (??? ? ???) 文章專欄&#xff1a; Git 本篇博客我們來介紹Git的一個重要功能之一 ---- 分支。我們將講解關于分支的各種操作&#xff0c;以及如何幫助我們進行開發。 &#x1f3e0; 理解分支…

純血鴻蒙:中國操作系統自主創新的里程碑

引言&#xff1a;破局者登場 2024 年 10 月&#xff0c;搭載純血鴻蒙操作系統&#xff08;HarmonyOS NEXT&#xff09;的華為 Mate 70 系列正式發布&#xff0c;首日預約量突破 330 萬。這場現象級熱度的背后&#xff0c;不僅是消費者對硬件創新的期待&#xff0c;更是中國科技…

二造考試的備考過程中如何保持良好的心態?

在二級造價師考試的備考過程中&#xff0c;保持良好的心態至關重要&#xff0c;以下是一些有效的方法&#xff1a; 樹立正確的考試觀念 )認識到二級造價師考試是職業生涯中的一個重要環節&#xff0c;但不是唯一的決定因素。把它看作是提升自己專業能力、豐富知識儲備的機會&am…

Vue3前端開發:組件化設計與狀態管理

Vue3前端開發&#xff1a;組件化設計與狀態管理 一、Vue3組件化設計 組件基本概念與特點 是一款流行的JavaScript框架&#xff0c;它支持組件化設計&#xff0c;這意味著我們可以將頁面分解成多個獨立的組件&#xff0c;每個組件負責一部分功能&#xff0c;通過組件的嵌套和復用…

動手學深度學習11.9. Adadelta-筆記練習(PyTorch)

以下內容為結合李沐老師的課程和教材補充的學習筆記&#xff0c;以及對課后練習的一些思考&#xff0c;自留回顧&#xff0c;也供同學之人交流參考。 本節課程地址&#xff1a;72 優化算法【動手學深度學習v2】_嗶哩嗶哩_bilibili 本節教材地址&#xff1a;11.9. Adadelta —…

Android Audio基礎(13)——audiomixer

在 Android 平臺上&#xff0c;音頻混合器 AudioMixer 主要用在 AudioFlinger 里&#xff0c;將多路音頻源數據混音&#xff08;包括混音、音量處理、重采樣及處理聲道等&#xff09;。位于 framework 的音頻處理模庫 libaudioprocessing&#xff08;frameworks/av/media/libau…

【React】使用Swiper報錯`Swiper` needs at least one child

問題 聊天頁面的表情面板&#xff0c;滑動效果使用了ant design mobile的Swiper。 原代碼中&#xff0c;Swiper 組件在 isShow 為 false 時渲染的是 <></>&#xff08;空元素&#xff09;&#xff0c;控制臺警告Swiper needs at least one child&#xff0c;Swip…

Matlab教程001:軟件介紹和界面使用

1.1 軟件介紹 1.1.1 Matlab的介紹 MATLAB&#xff08;MATrix LABoratory&#xff09;是一款由 MathWorks 公司開發的高級編程語言和交互式環境&#xff0c;廣泛用于 科學計算、數據分析、機器學習、工程建模、仿真和信號處理 等領域。 1.1.2 主要應用領域 數據分析與可視化…

藍橋杯算法實戰分享:算法進階之路與實戰技巧

引言 藍橋杯作為國內極具影響力的程序設計競賽&#xff0c;為眾多編程愛好者和專業人才提供了展示自我的舞臺。參與藍橋杯不僅能檢驗自身編程水平&#xff0c;還能拓寬技術視野&#xff0c;為未來職業發展積累寶貴經驗。本文將結合歷年真題與參賽經驗&#xff0c;全面分享藍橋…

Android Compose 層疊布局(ZStack、Surface)源碼深度剖析(十三)

Android Compose 層疊布局&#xff08;ZStack、Surface&#xff09;源碼深度剖析 一、引言 在 Android 應用開發領域&#xff0c;用戶界面&#xff08;UI&#xff09;的設計與實現一直是至關重要的環節。隨著技術的不斷演進&#xff0c;Android Compose 作為一種全新的聲明式…

MongoDB 面試備戰指南

MongoDB 面試備戰指南 一、基礎概念 1. MongoDB是什么類型的數據庫&#xff1f;和關系型數據庫有什么區別&#xff1f; 答案&#xff1a; MongoDB是文檔型NoSQL數據庫&#xff0c;核心區別&#xff1a; 數據模型&#xff1a;存儲JSON-like文檔&#xff08;動態schema&#xf…

毫米波雷達標定(2)

1. 前言 前面文章中介紹了產線上毫米波雷達的標定原理和流程,這篇文章則主要介紹其在線標定方法。相對于產線標定,在線標定具備使用自然場景而不是依賴特定標靶的優點,但因此其標定精度會相對差一點。在線標定一般應用于售出產品的維護場景,如果其標定結果精度可以滿足使用…