開發在線商店:基于Vue2+ElementUI的電商平臺前端實踐

Hi,我是布蘭妮甜 !在當今數字化時代,電子商務已成為商業領域的重要組成部分。開發一個功能完善、用戶友好的在線商店應用對于企業拓展市場至關重要。本文將詳細介紹如何使用Vue2框架配合ElementUI組件庫開發一個完整的在線商店應用。


文章目錄

    • 一、項目初始化與配置
      • 1.1 創建Vue2項目
      • 1.2 安裝ElementUI
      • 1.3 項目結構規劃
    • 二、核心功能模塊開發
      • 2.1 用戶認證模塊
      • 2.2 商品展示模塊
      • 2.3 購物車模塊
    • 三、狀態管理(Vuex)
      • 3.1 購物車狀態管理
    • 四、路由配置
    • 五、API封裝與Axios配置
    • 六、優化與部署
      • 6.1 性能優化
      • 6.2 部署配置
    • 七、總結


一、項目初始化與配置

1.1 創建Vue2項目

首先,我們需要使用Vue CLI創建一個新的Vue2項目:

vue create online-store
cd online-store

1.2 安裝ElementUI

在項目目錄中安裝ElementUI:

npm install element-ui -S

然后在main.js中引入ElementUI:

import Vue from 'vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'Vue.use(ElementUI)

1.3 項目結構規劃

src/
├── api/            # API請求封裝
├── assets/         # 靜態資源
├── components/     # 公共組件
├── router/         # 路由配置
├── store/          # Vuex狀態管理
├── utils/          # 工具函數
├── views/          # 頁面組件
├── App.vue         # 根組件
└── main.js         # 入口文件

二、核心功能模塊開發

2.1 用戶認證模塊

登錄/注冊組件

<template><div class="login-container"><el-form :model="loginForm" :rules="loginRules" ref="loginForm"><el-form-item prop="username"><el-input v-model="loginForm.username" placeholder="用戶名"></el-input></el-form-item><el-form-item prop="password"><el-input type="password" v-model="loginForm.password" placeholder="密碼"></el-input></el-form-item><el-button type="primary" @click="handleLogin">登錄</el-button><el-button @click="showRegisterDialog = true">注冊</el-button></el-form><el-dialog title="注冊" :visible.sync="showRegisterDialog"><!-- 注冊表單內容 --></el-dialog></div>
</template><script>
export default {data() {return {loginForm: {username: '',password: ''},loginRules: {username: [{ required: true, message: '請輸入用戶名', trigger: 'blur' }],password: [{ required: true, message: '請輸入密碼', trigger: 'blur' }]},showRegisterDialog: false}},methods: {handleLogin() {this.$refs.loginForm.validate(valid => {if (valid) {// 調用登錄APIthis.$store.dispatch('user/login', this.loginForm).then(() => {this.$router.push('/')this.$message.success('登錄成功')})}})}}
}
</script>

2.2 商品展示模塊

商品列表組件

<template><div class="product-list"><el-row :gutter="20"><el-col :span="6" v-for="product in products" :key="product.id"><el-card :body-style="{ padding: '0px' }" shadow="hover"><img :src="product.image" class="product-image"><div style="padding: 14px;"><h3>{{ product.name }}</h3><div class="price">¥{{ product.price }}</div><div class="bottom"><el-button type="text" @click="showDetail(product)">查看詳情</el-button><el-button type="primary" size="small" @click="addToCart(product)">加入購物車</el-button></div></div></el-card></el-col></el-row><el-pagination@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="pagination.current":page-sizes="[12, 24, 36, 48]":page-size="pagination.size"layout="total, sizes, prev, pager, next, jumper":total="pagination.total"></el-pagination></div>
</template><script>
export default {data() {return {products: [],pagination: {current: 1,size: 12,total: 0}}},created() {this.fetchProducts()},methods: {fetchProducts() {// 調用API獲取商品列表const { current, size } = this.paginationgetProducts({ page: current, pageSize: size }).then(res => {this.products = res.data.itemsthis.pagination.total = res.data.total})},handleSizeChange(val) {this.pagination.size = valthis.fetchProducts()},handleCurrentChange(val) {this.pagination.current = valthis.fetchProducts()},addToCart(product) {this.$store.dispatch('cart/addToCart', product)this.$message.success('已加入購物車')},showDetail(product) {this.$router.push(`/product/${product.id}`)}}
}
</script>

2.3 購物車模塊

購物車組件

<template><div class="cart-container"><el-table :data="cartItems" style="width: 100%"><el-table-column prop="name" label="商品名稱"></el-table-column><el-table-column prop="price" label="單價" width="120"></el-table-column><el-table-column label="數量" width="180"><template slot-scope="scope"><el-input-number v-model="scope.row.quantity" :min="1" @change="updateQuantity(scope.row)"></el-input-number></template></el-table-column><el-table-column label="小計" width="120"><template slot-scope="scope">¥{{ (scope.row.price * scope.row.quantity).toFixed(2) }}</template></el-table-column><el-table-column label="操作" width="120"><template slot-scope="scope"><el-button type="danger" icon="el-icon-delete" circle @click="removeItem(scope.row.id)"></el-button></template></el-table-column></el-table><div class="total-section"><span class="total-amount">總計: ¥{{ totalAmount.toFixed(2) }}</span><el-button type="primary" @click="checkout">結算</el-button></div></div>
</template><script>
export default {computed: {cartItems() {return this.$store.state.cart.items},totalAmount() {return this.cartItems.reduce((total, item) => {return total + (item.price * item.quantity)}, 0)}},methods: {updateQuantity(item) {this.$store.dispatch('cart/updateQuantity', {id: item.id,quantity: item.quantity})},removeItem(id) {this.$store.dispatch('cart/removeItem', id)},checkout() {if (this.cartItems.length === 0) {this.$message.warning('購物車為空')return}this.$router.push('/checkout')}}
}
</script>

三、狀態管理(Vuex)

3.1 購物車狀態管理

// store/modules/cart.js
const state = {items: []
}const mutations = {ADD_ITEM(state, product) {const existingItem = state.items.find(item => item.id === product.id)if (existingItem) {existingItem.quantity++} else {state.items.push({...product,quantity: 1})}},UPDATE_QUANTITY(state, { id, quantity }) {const item = state.items.find(item => item.id === id)if (item) {item.quantity = quantity}},REMOVE_ITEM(state, id) {state.items = state.items.filter(item => item.id !== id)},CLEAR_CART(state) {state.items = []}
}const actions = {addToCart({ commit }, product) {commit('ADD_ITEM', product)},updateQuantity({ commit }, payload) {commit('UPDATE_QUANTITY', payload)},removeItem({ commit }, id) {commit('REMOVE_ITEM', id)},clearCart({ commit }) {commit('CLEAR_CART')}
}export default {namespaced: true,state,mutations,actions
}

四、路由配置

// router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import Home from '../views/Home.vue'
import ProductList from '../views/ProductList.vue'
import ProductDetail from '../views/ProductDetail.vue'
import Cart from '../views/Cart.vue'
import Checkout from '../views/Checkout.vue'
import Login from '../views/Login.vue'Vue.use(Router)const router = new Router({mode: 'history',routes: [{path: '/',name: 'home',component: Home},{path: '/products',name: 'products',component: ProductList},{path: '/product/:id',name: 'product-detail',component: ProductDetail,props: true},{path: '/cart',name: 'cart',component: Cart,meta: { requiresAuth: true }},{path: '/checkout',name: 'checkout',component: Checkout,meta: { requiresAuth: true }},{path: '/login',name: 'login',component: Login}]
})// 路由守衛
router.beforeEach((to, from, next) => {const isAuthenticated = store.getters['user/isAuthenticated']if (to.matched.some(record => record.meta.requiresAuth) {if (!isAuthenticated) {next({ name: 'login', query: { redirect: to.fullPath } })} else {next()}} else {next()}
})export default router

五、API封裝與Axios配置

// utils/request.js
import axios from 'axios'
import { Message } from 'element-ui'const service = axios.create({baseURL: process.env.VUE_APP_BASE_API,timeout: 5000
})// 請求攔截器
service.interceptors.request.use(config => {const token = localStorage.getItem('token')if (token) {config.headers['Authorization'] = `Bearer ${token}`}return config},error => {return Promise.reject(error)}
)// 響應攔截器
service.interceptors.response.use(response => {const res = response.dataif (res.code !== 200) {Message({message: res.message || 'Error',type: 'error',duration: 5 * 1000})return Promise.reject(new Error(res.message || 'Error'))} else {return res}},error => {Message({message: error.message,type: 'error',duration: 5 * 1000})return Promise.reject(error)}
)export default service

六、優化與部署

6.1 性能優化

  1. 組件懶加載
    const ProductList = () => import('../views/ProductList.vue')
    
  2. 路由懶加載
    {
    path: '/products',
    component: () => import('../views/ProductList.vue')
    }
    
  3. CDN引入
    // vue.config.js
    module.exports = {configureWebpack: {externals: {'vue': 'Vue','element-ui': 'ELEMENT'}}
    }
    

6.2 部署配置

// vue.config.js
module.exports = {publicPath: process.env.NODE_ENV === 'production' ? '/online-store/' : '/',outputDir: 'dist',assetsDir: 'static',productionSourceMap: false,devServer: {proxy: {'/api': {target: 'http://your-api-server.com',changeOrigin: true,pathRewrite: {'^/api': ''}}}}
}

七、總結

本文詳細介紹了如何使用Vue2和ElementUI開發一個功能完整的在線商店應用。我們從項目初始化開始,逐步實現了用戶認證、商品展示、購物車管理等核心功能模塊,并介紹了狀態管理、路由配置、API封裝等關鍵技術點。

通過ElementUI豐富的組件庫,我們能夠快速構建出美觀、響應式的用戶界面,而Vue2的響應式特性和組件化開發模式則大大提高了開發效率和代碼可維護性。

希望本文能為開發者提供一個全面的參考,幫助您快速構建自己的在線商店應用。

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

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

相關文章

vue3 隨手筆記9--組件通信方式9/2--自定義事件

一、什么是自定義事件&#xff1f; 自定義事件是 Vue 組件間通信的一種機制。子組件通過 this.$emit(事件名, 數據) 觸發一個事件。父組件監聽這個事件并執行相應的邏輯。 二、基本使用 準備工作 demo 繼續使用筆記8中的 鏈接為demo 在views文件夾下 創建新的文件夾為cust…

深入理解Reactor調試模式:Hooks.onOperatorDebug() vs ReactorDebugAgent.init()

在現代Java開發中&#xff0c;調試Reactor流是確保應用程序性能和穩定性的關鍵步驟。Reactor調試模式提供了多種初始化方法&#xff0c;其中最常用的兩種是Hooks.onOperatorDebug()和ReactorDebugAgent.init()。本文將深入探討這兩種方法的區別&#xff0c;幫助開發者選擇最適合…

QT6 源(151)模型視圖架構里的表格窗體視圖 QTableWidget 篇一:先學習倆屬性以及 public 權限的公共成員函數,

&#xff08;1&#xff09;本篇的內容因為是子類&#xff0c;內容較視圖基類簡單了一些。又因為時間緊迫&#xff0c;不再詳細舉例了。詳細的測試可以滿足好奇心&#xff0c;也可以增強寫代碼的自信心。奈何時間不夠。不完美&#xff0c;就不完美了。以后有機會&#xff0c;再補…

ffmpeg 下載、安裝、配置、基本語法、避坑指南(覆蓋 Windows、macOS、Linux 平臺)

ffmpeg 下載、安裝、配置、基本語法、避坑指南&#xff08;覆蓋 Windows、macOS、Linux 平臺&#xff09; 本文是一篇面向初學者的超詳細 FFmpeg 教程&#xff0c;包括 FFmpeg 下載、安裝、配置、基本語法 與 避坑指南。覆蓋 Windows、macOS、Linux 平臺的安裝方式與 環境變量…

Kotlin 安裝使用教程

一、Kotlin 簡介 Kotlin 是 JetBrains 開發的一種現代、靜態類型的編程語言&#xff0c;完全兼容 Java&#xff0c;主要應用于 Android 開發、后端服務開發、前端 Web 開發&#xff08;Kotlin/JS&#xff09;和多平臺開發&#xff08;Kotlin Multiplatform&#xff09;。 二、…

day08-Elasticsearch

黑馬商城作為一個電商項目&#xff0c;商品的搜索肯定是訪問頻率最高的頁面之一。目前搜索功能是基于數據庫的模糊搜索來實現的&#xff0c;存在很多問題。 首先&#xff0c;查詢效率較低。 由于數據庫模糊查詢不走索引&#xff0c;在數據量較大的時候&#xff0c;查詢性能很…

transformers 筆記:自定義模型(配置+模型+注冊為AutoCLass+本地保存加載)

Transformers 模型設計上是可定制的。每個模型的代碼都包含在 Transformers 倉庫的 model 子文件夾中&#xff08;transformers/src/transformers/models at main huggingface/transformers&#xff09;&#xff0c;每個模型文件夾通常包含&#xff1a; modeling.py&#xff1…

Java工具類,對象List提取某個屬性為List,對象List轉為對象Map其中某個屬性作為Key值

Java工具類package org.common;import lombok.extern.slf4j.Slf4j;import java.util.*; import java.util.stream.Collectors;Slf4j public final class CollectorHelper {/*** param element* param propertyName* param <E>* return*/public static <E> List toL…

ATE FT ChangeKit學習總結-20250630

目錄 一、基本概念 二、主要特點 三、BOM LIST Shuttle Hot Plate Dock Plate Contactor 四、設計要點 五、參考文獻與鏈接 一、基本概念 Change Kit在半導體封裝測試領域中是一個重要的組件,它作為Handler(自動化分類機)的配套治具,在芯片測試過程中發揮著關鍵作…

【網絡協議安全】任務14:路由器DHCP_AAA_TELNET配置

本文檔將詳細介紹在華為 eNSP 仿真環境中&#xff0c;實現路由器 DHCP 服務器功能、AAA 認證以及 TELNET 遠程登錄配置的完整步驟&#xff0c;適用于華為 VRP 系統路由器。 一、配置目標 路由器作為 DHCP 服務器&#xff0c;為局域網內的設備自動分配 IP 地址、子網掩碼、網關…

深度探索:現代翻譯技術的核心算法與實踐(第一篇)

引言:翻譯技術的演進之路 從早期的基于規則的機器翻譯(RBMT)到統計機器翻譯(SMT),再到如今主導行業的神經機器翻譯(NMT),翻譯技術已經走過了漫長的發展道路。現代翻譯系統不僅能夠處理簡單的句子,還能理解上下文、識別領域術語,甚至捕捉微妙的文化差異。 本系列文章將帶…

玩轉Docker | 使用Docker部署NotepadMX筆記應用程序

玩轉Docker | 使用Docker部署NotepadMX筆記應用程序 前言一、NotepadMX介紹工具簡介主要特點二、系統要求環境要求環境檢查Docker版本檢查檢查操作系統版本三、部署NotepadMX服務下載NotepadMX鏡像編輯部署文件創建容器檢查容器狀態檢查服務端口安全設置四、訪問NotepadMX服務訪…

Web前端:not(否定偽類選擇器)

not&#xff08;否定偽類選擇器&#xff09;CSS中的 :not() 選擇器是?個否定偽類選擇器&#xff0c;它?于選擇不符合給定選擇器的元素。這是?種排除特定元素的?法&#xff0c;可以?來簡 化復雜的選擇器&#xff0c;提? CSS 規則的靈活性和精確性。:not() 選擇器的基本語法…

【BTC】比特幣網絡

目錄 一、比特幣網絡架構 1.1 節點加入與離開 二、消息傳播方式 三、交易處理機制 四、網絡傳播問題 五、實際應用問題及解決 本章節講比特幣網絡的工作原理&#xff0c;講解新創建的區塊是如何在比特幣網絡中傳播的。 一、比特幣網絡架構 比特幣工作在應用層&#xff…

Clickhouse 的歷史發展過程

20.5.3 開始支持多線程20.6.3 支持explainmysql 20.8 實時同步mysql&#x1f4cc; ?一、早期版本階段&#xff08;1.1.x系列&#xff09;??版本范圍?&#xff1a;1.1.54245&#xff08;2017-07&#xff09;→ 1.1.54394&#xff08;2018-07&#xff09;?核心特性?&#x…

玩轉n8n工作流教程(一):Windows系統本地部署n8n自動化工作流(n8n中文漢化)

在Windows系統下使用 Docker 本地部署N8N中文版的具體操作&#xff0c;進行了詳盡闡述&#xff0c;玩轉n8n工作流教程系列內容旨在手把手助力從0開始一步一步深入學習n8n工作流。想研究n8n工作流自動化的小伙伴們可以加個關注一起學起來。后續也會持續分享n8n自動化工作流各種玩…

mini-program01の系統認識微信小程序開發

一、官方下載并安裝 1、下載&#xff08;I選了穩定版&#xff09; https://developers.weixin.qq.com/miniprogram/dev/devtools/download.htmlhttps://developers.weixin.qq.com/miniprogram/dev/devtools/download.html 2、安裝&#xff08;A FEW MOMENT LATER&#xff09;…

如何將 Java 項目打包為可執行 JAR 文件

如何將 Java 項目打包為可執行 JAR 文件我將詳細介紹將 Java 項目打包為可執行 JAR 文件的完整流程&#xff0c;包括使用 IDE 和命令行兩種方法。方法一&#xff1a;使用 IntelliJ IDEA 打包步驟 1&#xff1a;配置項目結構打開項目點擊 File > Project Structure在 Project…

【Starrocks 異常解決】-- mysql flink sync to starrocks row error

1、異常信息 flink 1.20 starrocks 3.3.0 mysql 8.0 errorLog: Error: Target column count: 35 doesnt match source value column count: 28. Column separator: \t, Row delimiter: \n. Row: 2025-05-22 6 23400055 214 dssd 1 1 1928 mm2er 360 20000.00000000 1…

Jenkins 使用宿主機的Docker

背景&#xff1a;不想在Jenkins 內部安裝Docker,想直接使用Jenkins服務所在的系統安裝的docker當你在 Jenkins 中執行 docker 命令時&#xff0c;實際上是通過 Docker 客戶端與 Docker 守護進程進行通信。Docker 客戶端和守護進程之間的通信是通過一個名為 /var/run/docker.soc…