2026/4/4 13:26:27
网站建设
项目流程
1号店网站网页特效,系统软件开发,做国际贸易如何建网站,网站设计理念在前端开发领域#xff0c;电商项目是综合考察 Vue 全家桶技术栈的经典场景。本文将从实战角度出发#xff0c;基于 Vue 2#xff08;兼顾 Vue 3 适配思路#xff09;#xff0c;完整讲解如何用 Vuex 做状态管理、Vue Router 实现路由控制#xff0c;搭建电商项目的核心功…在前端开发领域电商项目是综合考察 Vue 全家桶技术栈的经典场景。本文将从实战角度出发基于 Vue 2兼顾 Vue 3 适配思路完整讲解如何用 Vuex 做状态管理、Vue Router 实现路由控制搭建电商项目的核心功能模块包括商品列表、详情、购物车、登录鉴权等帮你打通 Vue 全家桶在电商场景的落地应用。一、项目初始化与技术选型1. 技术栈确定核心框架Vue 2示例代码/ Vue 3 Composition API附适配说明路由Vue Router 3Vue2/ 4Vue3状态管理Vuex 3Vue2/ PiniaVue3 替代方案构建工具Vue CLI快速搭建项目辅助Axios接口请求、CSS 预处理器Scss2. 项目初始化# 安装Vue CLI npm install -g vue/cli # 创建项目 vue create ecommerce-demo # 选择Manually select features勾选Router、Vuex、CSS Pre-processors等 # 进入项目 cd ecommerce-demo # 安装axios npm install axios --save初始化完成后项目核心目录结构如下ecommerce-demo/ ├── src/ │ ├── api/ # 接口请求封装 │ ├── components/ # 公共组件商品卡片、导航栏等 │ ├── pages/ # 页面组件首页、详情页、购物车等 │ ├── router/ # 路由配置 │ ├── store/ # Vuex状态管理 │ ├── App.vue # 根组件 │ └── main.js # 入口文件二、Vue Router电商路由体系搭建电商项目的路由需满足「页面跳转、参数传递、登录鉴权、路由懒加载」核心需求以下是完整实现方案。1. 路由配置router/index.jsimport Vue from vue import Router from vue-router Vue.use(Router) // 路由懒加载优化首屏加载速度 const Home () import(/pages/Home) const GoodsDetail () import(/pages/GoodsDetail) const Cart () import(/pages/Cart) const Login () import(/pages/Login) const Order () import(/pages/Order) const router new Router({ mode: history, // 去除URL中的# routes: [ { path: /, name: Home, component: Home, meta: { title: 首页 - 电商商城 } }, { path: /goods/:id, // 动态路由传递商品ID name: GoodsDetail, component: GoodsDetail, meta: { title: 商品详情 - 电商商城 } }, { path: /cart, name: Cart, component: Cart, meta: { title: 购物车 - 电商商城, requireAuth: true // 需要登录鉴权 } }, { path: /order, name: Order, component: Order, meta: { title: 订单结算 - 电商商城, requireAuth: true } }, { path: /login, name: Login, component: Login, meta: { title: 登录 - 电商商城 } }, // 404路由 { path: *, redirect: / } ] }) // 路由守卫登录鉴权 router.beforeEach((to, from, next) { // 设置页面标题 if (to.meta.title) { document.title to.meta.title } // 校验登录状态 const isLogin localStorage.getItem(token) if (to.meta.requireAuth !isLogin) { next({ path: /login, query: { redirect: to.fullPath } }) // 记录跳转前路由 } else { next() } }) export default router2. 路由使用示例首页跳转商品详情template div classgoods-list div classgoods-item v-forgoods in goodsList :keygoods.id clicktoGoodsDetail(goods.id) img :srcgoods.img alt p{{ goods.name }}/p span¥{{ goods.price }}/span /div /div /template script export default { data() { return { goodsList: [/* 商品数据 */] } }, methods: { toGoodsDetail(id) { this.$router.push({ path: /goods/${id} }) } } } /script登录页跳转回原路由template div classlogin input v-modelusername placeholder用户名 input v-modelpassword typepassword placeholder密码 button clicklogin登录/button /div /template script export default { data() { return { username: , password: } }, methods: { async login() { // 模拟登录请求 const res await this.$api.login({ username: this.username, password: this.password }) if (res.code 200) { localStorage.setItem(token, res.token) // 跳回登录前的路由若无则跳首页 const redirect this.$route.query.redirect || / this.$router.push(redirect) } } } } /script三、Vuex电商核心状态管理电商项目中购物车、用户信息、商品列表等状态需要跨组件共享Vuex 是最佳解决方案。以下是模块化的 Vuex 配置按功能拆分模块降低耦合。1. Vuex 核心配置store/index.jsimport Vue from vue import Vuex from vuex import goods from ./modules/goods // 商品模块 import cart from ./modules/cart // 购物车模块 import user from ./modules/user // 用户模块 Vue.use(Vuex) export default new Vuex.Store({ modules: { goods, cart, user }, // 严格模式开发环境开启生产环境关闭 strict: process.env.NODE_ENV ! production })2. 模块实现购物车store/modules/cart.js购物车是电商核心需实现「添加、删除、修改数量、全选、计算总价」功能// 本地存储封装持久化购物车数据 const getCartFromLocal () { return JSON.parse(localStorage.getItem(cart) || []) } export default { namespaced: true, // 开启命名空间避免模块间命名冲突 state: { cartList: getCartFromLocal() // 购物车列表 }, getters: { // 计算购物车商品总数 cartTotalCount: (state) { return state.cartList.reduce((total, item) total item.count, 0) }, // 计算购物车总价 cartTotalPrice: (state) { return state.cartList.reduce((total, item) { return total item.price * item.count }, 0).toFixed(2) }, // 判断是否全选 isAllChecked: (state) { return state.cartList.length 0 state.cartList.every(item item.checked) } }, mutations: { // 添加商品到购物车 ADD_TO_CART(state, goods) { // 查找是否已存在该商品 const existGoods state.cartList.find(item item.id goods.id) if (existGoods) { // 存在则数量1 existGoods.count 1 } else { // 不存在则添加默认选中 state.cartList.push({ ...goods, count: 1, checked: true }) } // 同步到本地存储 localStorage.setItem(cart, JSON.stringify(state.cartList)) }, // 修改商品数量 CHANGE_GOODS_COUNT(state, { id, count }) { const goods state.cartList.find(item item.id id) if (goods) { goods.count count localStorage.setItem(cart, JSON.stringify(state.cartList)) } }, // 切换商品选中状态 TOGGLE_GOODS_CHECKED(state, id) { const goods state.cartList.find(item item.id id) if (goods) { goods.checked !goods.checked localStorage.setItem(cart, JSON.stringify(state.cartList)) } }, // 全选/取消全选 TOGGLE_ALL_CHECKED(state, isChecked) { state.cartList.forEach(item { item.checked isChecked }) localStorage.setItem(cart, JSON.stringify(state.cartList)) }, // 删除购物车商品 DELETE_GOODS_FROM_CART(state, id) { state.cartList state.cartList.filter(item item.id ! id) localStorage.setItem(cart, JSON.stringify(state.cartList)) } }, actions: { // 异步添加商品可扩展先请求库存再添加 addToCart({ commit }, goods) { return new Promise((resolve) { // 模拟库存校验 setTimeout(() { commit(ADD_TO_CART, goods) resolve(添加成功) }, 500) }) } } }3. 模块实现商品store/modules/goods.jsimport api from /api export default { namespaced: true, state: { goodsList: [], // 商品列表 currentGoods: null // 当前选中商品详情 }, mutations: { SET_GOODS_LIST(state, list) { state.goodsList list }, SET_CURRENT_GOODS(state, goods) { state.currentGoods goods } }, actions: { // 获取商品列表 async getGoodsList({ commit }) { const res await api.getGoodsList() commit(SET_GOODS_LIST, res.data) }, // 获取商品详情 async getGoodsDetail({ commit }, id) { const res await api.getGoodsDetail(id) commit(SET_CURRENT_GOODS, res.data) } } }4. Vuex 在组件中的使用商品详情页添加购物车template div classgoods-detail v-ifcurrentGoods img :srccurrentGoods.img alt h2{{ currentGoods.name }}/h2 p¥{{ currentGoods.price }}/p button clickaddToCart加入购物车/button /div /template script import { mapActions, mapState } from vuex export default { created() { // 获取商品详情 this.getGoodsDetail(this.$route.params.id) }, computed: { ...mapState(goods, [currentGoods]) }, methods: { ...mapActions(goods, [getGoodsDetail]), ...mapActions(cart, [addToCart]), addToCart() { this.addToCart(this.currentGoods).then(msg { this.$message.success(msg) // 假设引入了ElementUI的消息提示 }) } } } /script购物车页面使用 Vuex 数据template div classcart div classcart-item v-foritem in cartList :keyitem.id input typecheckbox v-modelitem.checked change$store.commit(cart/TOGGLE_GOODS_CHECKED, item.id) img :srcitem.img alt p{{ item.name }}/p button clickchangeCount(item.id, item.count - 1) :disableditem.count 1-/button span{{ item.count }}/span button clickchangeCount(item.id, item.count 1)/button span¥{{ (item.price * item.count).toFixed(2) }}/span button clickdeleteGoods(item.id)删除/button /div div classcart-footer input typecheckbox v-modelisAllChecked change$store.commit(cart/TOGGLE_ALL_CHECKED, isAllChecked) 全选 span总价¥{{ cartTotalPrice }}/span button clicktoOrder :disabledcartTotalCount 0去结算/button /div /div /template script import { mapState, mapGetters } from vuex export default { computed: { ...mapState(cart, [cartList]), ...mapGetters(cart, [cartTotalCount, cartTotalPrice, isAllChecked]) }, methods: { changeCount(id, count) { this.$store.commit(cart/CHANGE_GOODS_COUNT, { id, count }) }, deleteGoods(id) { this.$store.commit(cart/DELETE_GOODS_FROM_CART, id) }, toOrder() { this.$router.push(/order) } } } /script四、核心功能整合与优化1. 接口请求封装api/index.jsimport axios from axios // 创建axios实例 const service axios.create({ baseURL: process.env.VUE_APP_BASE_API, // 环境变量配置接口前缀 timeout: 5000 }) // 请求拦截器添加token 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.data if (res.code ! 200) { // 统一错误提示 console.error(res.msg || 请求失败) return Promise.reject(res) } else { return res } }, error { console.error(接口请求错误, error) return Promise.reject(error) } ) // 封装接口方法 export default { // 商品列表 getGoodsList() { return service.get(/goods/list) }, // 商品详情 getGoodsDetail(id) { return service.get(/goods/detail/${id}) }, // 登录 login(data) { return service.post(/user/login, data) } }2. Vue3 Pinia 适配思路若使用 Vue3推荐用 Pinia 替代 Vuex核心改动如下// store/cart.jsPinia import { defineStore } from pinia export const useCartStore defineStore(cart, { state: () ({ cartList: JSON.parse(localStorage.getItem(cart) || []) }), getters: { cartTotalCount: (state) state.cartList.reduce((t, i) t i.count, 0), cartTotalPrice: (state) state.cartList.reduce((t, i) t i.price * i.count, 0).toFixed(2), isAllChecked: (state) state.cartList.length state.cartList.every(i i.checked) }, actions: { addToCart(goods) { const exist this.cartList.find(i i.id goods.id) if (exist) exist.count else this.cartList.push({ ...goods, count: 1, checked: true }) localStorage.setItem(cart, JSON.stringify(this.cartList)) }, // 其他方法... } }) // 组件中使用 import { useCartStore } from /store/cart export default { setup() { const cartStore useCartStore() const addToCart (goods) { cartStore.addToCart(goods) } return { addToCart, cartStore } } }3. 性能优化点路由懒加载已在路由配置中实现减少首屏加载体积购物车数据持久化通过 localStorage 同步刷新后数据不丢失防抖 / 节流商品列表搜索、数量修改等场景添加防抖避免频繁请求 / 更新虚拟列表商品列表数据量大时使用 vue-virtual-scroller 优化渲染性能接口缓存商品详情等高频访问接口添加缓存避免重复请求。五、总结本文基于 VueVuexVue Router 完成了电商项目核心功能的落地涵盖「路由管控、状态管理、跨组件通信、登录鉴权、购物车核心逻辑」等关键场景。核心要点Vue Router 通过动态路由、路由守卫实现页面跳转与权限控制Vuex 模块化设计降低状态管理耦合getters 处理派生状态mutations 同步修改状态actions 处理异步逻辑结合本地存储实现状态持久化提升用户体验Vue3 场景下可无缝切换为 PiniaVue Router 4核心逻辑一致。在此基础上可进一步扩展「订单管理、支付对接、商品分类、搜索筛选」等功能或结合 ElementUI/vant 等 UI 库完善界面最终形成完整的电商前端解决方案。