2025年了,还在用 UniApp 写小程序?用 Vue3 + Vite 10分钟撸出商城小程序UI(附完整源码)
🔥 本文已收录至「Vue3实战系列」专栏 | 阅读本文约 8 分钟 | 文末获取完整源码
大家好,我是老李 👋
做前端这几年,见过太多同学为了写小程序 UI 就去啃 UniApp 文档,配环境配到想哭。
其实对于纯前端展示型的小程序 UI,完全没必要用 UniApp!
今天给你分享一套用 Vue3 + Vite 写的移动端商城小程序 UI 源码,5个核心页面,全部可以直接运行,无需后台、无需配置微信账号,开箱即用。
🎬 先看效果,再谈技术
效果不好看?直接划走,我不怪你 😄
| 页面 | 核心亮点 |
|---|---|
| 🏠 首页 | 搜索栏 + 自动轮播 Banner + 分类入口 + 热销商品双列网格 |
| 📂 分类页 | 左侧导航联动 + 右侧商品列表,10个类目实时切换 |
| 🛍️ 商品详情 | SKU 颜色/尺码选择器 + 数量控制 + 底部加购/立即购买 |
| 🛒 购物车 | Pinia 全局状态 + 全选/单选/删除 + 结算栏动态计算 |
| 👤 个人中心 | 渐变用户头部 + 订单状态栏 + 功能菜单 |
整体风格:红色主题(#e93323),手机壳模拟器包裹,截图即可上架/演示
🤔 为什么不用 UniApp?
这是个好问题,必须说清楚。
UniApp 是为真实发布到小程序/App 设计的框架,有自己的编译器和运行时。
如果你的目标是:
- 💼 做作品集
- 🎓 毕业设计参考
- 💰 接外包做 UI 方案
- 📦 出售/展示 UI 模板
那 Vue3 + Vite 才是最佳选择:
UniApp: 配 HBuilderX → 开 AppID → 真机调试 → 改编译错误 → 崩溃...
Vue3: npm install → npm run dev → 浏览器打开,搞定 ✅
本项目构建后的产物,同样可以通过 web-view 嵌入微信小程序,几乎零改动。
🛠️ 技术栈一览
Vue 3.4 —— 核心框架(Composition API + <script setup>)
Vite 5 —— 极速构建工具(冷启动 < 1s)
TypeScript 5 —— 类型安全,IDE 智能提示
Vue Router 4 —— 路由管理,懒加载分包
Pinia 2 —— 状态管理(购物车 / 用户信息)
SCSS —— 样式预处理,全局变量注入
无任何 UI 组件库依赖,手写组件 = 体积轻、自由度高
📁 项目结构
shop-basic/
├── src/
│ ├── pages/
│ │ ├── index/ # 首页
│ │ ├── category/ # 分类页
│ │ ├── goods/ # 商品详情
│ │ ├── cart/ # 购物车
│ │ └── user/ # 个人中心
│ ├── stores/
│ │ └── cart.ts # Pinia 购物车 Store
│ ├── router/
│ │ └── index.ts
│ ├── styles/
│ │ └── variables.scss # 全局 SCSS 变量
│ └── App.vue # Phone Shell 容器
├── vite.config.ts
└── package.json
🔑 核心代码片段
1. 手机壳模式(让截图更专业)
这是整个项目最妙的设计——把 App 渲染在一个仿 iPhone 12 的手机壳里:
<!-- App.vue -->
<template>
<div class="app-container">
<div class="phone-shell">
<div class="status-bar">
<span>9:41</span>
<span>📶 🔋</span>
</div>
<div class="page-content">
<router-view />
</div>
<TabBar />
</div>
</div>
</template>
<style lang="scss">
.app-container {
background: linear-gradient(135deg, #1a1a2e, #16213e);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.phone-shell {
width: 390px;
height: 844px;
background: #fff;
border-radius: 40px;
overflow: hidden;
box-shadow: 0 30px 80px rgba(0, 0, 0, .6);
display: flex;
flex-direction: column;
}
</style>
效果:截图直接是「小程序 + 背景」的完整演示图,适合闲鱼/Portfolio 展示。
2. Pinia 购物车(核心状态管理)
很多同学写购物车用 Vuex,又复杂又啰嗦。用 Pinia + Composition API 写法极简:
// src/stores/cart.ts
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
export interface CartItem {
id: number
goodsId: number
title: string
price: number
quantity: number
sku: string // "黑色 / XL"
checked: boolean
}
export const useCartStore = defineStore('cart', () => {
const cartList = ref<CartItem[]>([])
// 计算属性
const totalCount = computed(() =>
cartList.value.reduce((sum, item) => sum + item.quantity, 0)
)
const checkedItems = computed(() =>
cartList.value.filter(item => item.checked)
)
const totalPrice = computed(() =>
checkedItems.value.reduce((sum, item) => sum + item.price * item.quantity, 0)
)
const isAllChecked = computed(() =>
cartList.value.length > 0 && cartList.value.every(item => item.checked)
)
// 加入购物车(自动合并同 SKU)
function addItem(goodsId: number, color: string, size: string, qty: number) {
const sku = `${color} / ${size}`
const existing = cartList.value.find(
i => i.goodsId === goodsId && i.sku === sku
)
if (existing) {
existing.quantity += qty // 已有 → 加数量
} else {
cartList.value.push({
id: Date.now(),
goodsId, title: '...', price: 89,
quantity: qty, sku, checked: true
})
}
}
// 全选 / 全不选
function toggleCheckAll() {
const next = !isAllChecked.value
cartList.value.forEach(item => { item.checked = next })
}
// 删除已勾选商品
function removeChecked() {
cartList.value = cartList.value.filter(item => !item.checked)
}
return {
cartList, totalCount, totalPrice,
isAllChecked, checkedItems,
addItem, toggleCheckAll, removeChecked
}
})
这段代码直接复制到你的项目里就能用,零配置。
3. SCSS 主题色变量
改主题色只要改一个文件,全局生效:
// src/styles/variables.scss
$primary: #e93323; // 主题红(经典电商色)
$primary-light: #ff6b5b;
$primary-dark: #c0281a;
$bg: #f5f5f5;
$text-primary: #333;
$text-secondary: #666;
$text-hint: #999;
$border: #f0f0f0;
$white: #fff;
在 vite.config.ts 中全局注入,无需每个 vue 文件手动 import:
// vite.config.ts
export default defineConfig({
css: {
preprocessorOptions: {
scss: {
additionalData: `@import "@/styles/variables.scss";`
}
}
}
})
4. 路由懒加载配置
// src/router/index.ts
import { createRouter, createWebHistory } from 'vue-router'
export default createRouter({
history: createWebHistory(),
routes: [
{ path: '/', component: () => import('@/pages/index/index.vue') },
{ path: '/category', component: () => import('@/pages/category/index.vue') },
{ path: '/goods/:id', component: () => import('@/pages/goods/detail.vue') },
{ path: '/cart', component: () => import('@/pages/cart/index.vue') },
{ path: '/user', component: () => import('@/pages/user/index.vue') },
],
})
全部使用动态 import() 懒加载,Vite 构建时自动分包,首屏加载速度更快。
▶️ 快速运行
# 克隆 / 解压后
cd shop-basic
# 安装依赖
npm install
# 启动开发服务器(默认 http://localhost:5173)
npm run dev
# 构建生产版本
npm run build
运行成功后,浏览器打开即可看到手机壳效果。
📦 源码包含内容
拿到源码后你得到的是:
- ✅ 5 个完整页面,无占位符,全部有真实 Mock 数据
- ✅ Pinia 购物车(加购 / 删除 / 全选 / 结算)
- ✅ SCSS 主题色变量系统(改一处,全局生效)
- ✅ Phone Shell 模拟器 UI(截图即演示图)
- ✅ Vite 5 + Vue 3.4 + TypeScript 5 最新版本
- ✅ 注释完善,代码规范,适合二次开发
❌ 不包含: 后台管理系统、数据库、接口服务(纯前端 UI,数据为 Mock)
🤑 适合哪些人?
| 用途 | 说明 |
|---|---|
| 🎓 毕业设计 | 作为前端 UI 部分,接上 SpringBoot / Node 后台即完整项目 |
| 💼 作品集 | 做完整 UI 截图,放简历/牛客/GitHub |
| 🧑💻 前端学习 | 参考 Pinia、Vue Router、SCSS 变量的实际用法 |
| 💰 接外包 | 快速出 UI 方案给客户确认,再接后端开发 |
| 📱 小程序发布 | 用 web-view 嵌套本 H5,或改造为 uni-app 项目 |
💬 关于我
我是源码老李,专注 Vue3 / React 移动端 UI 开发。
手里有几套整理好的源码,包括:
- 🛍️ 通用商城小程序 UI(就是本文这套)
- 🏷️ 淘宝客优惠券 / 返利聚合小程序
- 🎓 知识付费课程小程序(含视频播放页)
🐟 闲鱼搜索「源码老李」即可找到全部源码
价格透明,支持毕设答辩、二次开发咨询,买了不满意可以退。
✍️ 写在最后
这套项目的核心价值,不是代码本身,而是一种快速原型验证的思路:
- 先用 Vue3 + Vite 做纯前端 UI,用 Mock 数据跑通所有交互
- 确认 UI 没问题,再接入后端 API 替换 Mock
- 最终用 web-view 或 uni-app 包装发布
这个思路比"上来就配小程序账号 + 真机调试"省了至少一半的时间。
如果这篇文章对你有帮助,点个赞 👍 再走吧! 你的支持是我继续分享的动力 🙏
🏷️ 标签:
Vue3ViteTypeScriptPinia小程序商城源码毕业设计SCSS移动端UI前端源码