Vue.js: Final Project: E-commerce Admin
Last updated: 2026-10-20
This is the graduation project of the Vue 3 tutorial — applying everything from the 29 lessons to a real SaaS e-commerce admin. Following the architecture of PanJiaChen/vue-element-admin (88k⭐ on GitHub), we build an admin that serves 5,000 merchants and 30,000 SKUs.
The project has 8 major modules and takes 10-12 hours of work. Once you finish it, you will be able to independently build enterprise-grade Vue applications.
1. What You'll Learn
- Full implementation of the 8 modules (project setup / login and auth / dashboard / products / orders / users / marketing / deployment)
- A full-stack integration of Vue 3 + Vite + Pinia + Vue Router + Element Plus + ECharts
- Performance optimization (virtual scrolling for a 10,000-row table)
- A 5-role permission system (RBAC)
- 5 ECharts charts (dashboard)
- Production deployment (Vercel / Netlify / CDN)
- Complete TypeScript
2. A SaaS E-commerce Product Manager's "Full-Stack Requirements"
(1) Pain point: how do you build an admin for 5,000 merchants and 30,000 SKUs
Alice has been promoted to lead the admin dashboard project:
Business scenario:
- 5,000 small and medium merchants (30-300 SKUs each)
- 30,000 product SKUs
- 10,000 orders per day
- 5 roles (admin / manager / editor / viewer / guest)
- Real-time data (dashboard, orders, notifications)
- Multilingual (5 languages)
Product manager Charlie wrote the spec:
"Alice, our SaaS platform needs a complete admin. 8 modules: dashboard, products, orders, users, marketing, settings, login, deployment. Every module matters. Build it with Vue 3, 10-12 hours, and use everything from the first 29 lessons."
(2) The 8-module architecture of the Vue 3 capstone project
src/
├── api/ # API wrappers
│ ├── auth.ts
│ ├── product.ts
│ ├── order.ts
│ └── user.ts
├── assets/ # Static assets
├── components/ # Shared components
│ ├── BaseButton.vue
│ ├── BaseTable.vue # Wraps Element Plus
│ ├── BasePagination.vue
│ ├── BaseDialog.vue
│ └── charts/ # Charts
│ ├── SalesChart.vue
│ ├── UserChart.vue
│ └── OrderChart.vue
├── composables/ # Composables
│ ├── useAuth.ts
│ ├── usePermission.ts
│ ├── useTable.ts
│ └── usePagination.ts
├── layouts/ # Layouts
│ ├── DefaultLayout.vue # After login
│ └── AuthLayout.vue # Login page
├── router/ # Routing
│ └── index.ts
├── stores/ # Pinia
│ ├── auth.ts
│ ├── product.ts
│ ├── order.ts
│ └── app.ts # Global (theme / sidebar)
├── types/ # TS types
│ ├── user.ts
│ ├── product.ts
│ └── api.ts
├── utils/ # Utilities
│ ├── request.ts # axios wrapper
│ ├── auth.ts
│ └── format.ts
├── views/ # Pages
│ ├── dashboard/ # Dashboard
│ ├── login/ # Login
│ ├── product/ # Products
│ ├── order/ # Orders
│ ├── user/ # Users
│ ├── marketing/ # Marketing
│ └── error/ # 403 / 404
├── App.vue
└── main.ts
(3) The payoff
After building this project:
- Complete project experience: a resume booster
- Enterprise-grade skills: Router + Pinia + Element Plus fully integrated
- Deployable: a SaaS admin that can actually go live
- A complete 30-lesson loop: teaching + practice + deployment
3. Module 1: Project Initialization (1.5h)
(1) Complete package.json
▶ Example: Complete Project Initialization Configuration (Difficulty: ⭐⭐)
{
"name": "mercury-admin",
"version": "1.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"preview": "vite preview",
"test": "vitest",
"test:e2e": "playwright test",
"lint": "eslint . --ext .vue,.ts,.tsx"
},
"dependencies": {
"vue": "^3.4.0",
"vue-router": "^4.3.0",
"pinia": "^2.1.0",
"element-plus": "^2.5.0",
"@element-plus/icons-vue": "^2.3.0",
"echarts": "^5.4.0",
"vue-echarts": "^7.0.0",
"axios": "^1.6.0",
"dayjs": "^1.11.0",
"vueuse": "^10.7.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.0.0",
"vite": "^5.0.0",
"vue-tsc": "^1.8.0",
"typescript": "^5.3.0",
"unplugin-vue-components": "^0.26.0",
"unplugin-auto-import": "^0.17.0",
"unplugin-icons": "^0.17.0",
"@iconify-json/carbon": "^1.1.0",
"sass": "^1.69.0",
"vitest": "^1.0.0",
"@vue/test-utils": "^2.4.0",
"@playwright/test": "^1.40.0"
}
}
Output:
After npm install, every dependency resolves, and npm run dev boots the Vite dev server with the Element Plus and ECharts bundles available:
added 312 packages in 18s
VITE v5.0.10 ready in 486 ms
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
(2) vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import'
import Components from 'unplugin-vue-components'
import Icons from 'unplugin-icons/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import path from 'path'
export default defineConfig({
plugins: [
vue(),
AutoImport({
imports: ['vue', 'vue-router', 'pinia', 'vueuse'],
resolvers: [ElementPlusResolver()],
dts: 'src/auto-imports.d.ts'
}),
Components({
resolvers: [ElementPlusResolver()],
dts: 'src/components.d.ts'
}),
Icons({ autoInstall: true })
],
resolve: {
alias: { '@': path.resolve(__dirname, 'src') }
},
server: {
port: 5173,
proxy: { '/api': { target: 'http://localhost:3000', changeOrigin: true } }
},
build: {
rollupOptions: {
output: {
manualChunks: {
'vue-vendor': ['vue', 'vue-router', 'pinia'],
'echarts-vendor': ['echarts', 'vue-echarts']
}
}
}
}
})
4. Module 2: Login + JWT Auth + Permission Routing (2h)
(1) Pinia auth store
▶ Example: JWT Login + 5-Role Permission Demo (Runs on CDN)
▶ Expand runnable example (124 lines)
Output:
A centered login card is rendered first;
logging in as Alice switches to the dashboard with all four KPI cards, all five action buttons enabled, and six permission tags.
Logging in as Dave leaves only the "Today's Orders" KPI, every action button disabled, and a single order.view tag:
🔐 Sign In (CDN Simulation)
Username: alice / Password: any
[ Username ]
[ Password ]
[ Sign in ]
5 user types: admin manager editor viewer guest
—— after clicking "admin" and "Sign in" ——
📊 Dashboard Welcome Alice [admin] [Sign out]
1. Four KPI cards (permission-gated)
Today's Sales $12,345 +12% Today's Orders 342 +5%
Total Products 1,234 +3 Total Users 5,678 +8%
2. Five permission-gated buttons (shown by role)
➕ Create product ✏️ Edit product 🗑️ Delete product 👥 Manage users 💰 Financial reports
3. Current role's permission list
product.create product.edit product.delete user.manage finance.view order.view
(2) Route guards
// router/index.ts
import { createRouter, createWebHistory } from 'vue-router'
import { useAuthStore } from '@/stores/auth'
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/login', component: () => import('@/views/login/LoginPage.vue') },
{
path: '/',
component: () => import('@/layouts/DefaultLayout.vue'),
meta: { requiresAuth: true },
children: [
{ path: '', redirect: '/dashboard' },
{ path: 'dashboard', component: () => import('@/views/dashboard/DashboardPage.vue') },
{ path: 'products', component: () => import('@/views/product/ProductListPage.vue') }
]
}
]
})
router.beforeEach((to, from, next) => {
const auth = useAuthStore()
if (to.meta.requiresAuth && !auth.isLoggedIn) {
return next({ name: 'login', query: { redirect: to.fullPath } })
}
next()
})
export default router
(3) A custom permission directive
// directives/permission.ts
import { useAuthStore } from '@/stores/auth'
export const permission = {
mounted(el: HTMLElement, binding: { value: string }) {
const auth = useAuthStore()
if (!auth.permissions.includes(binding.value)) {
el.parentNode?.removeChild(el)
}
}
}
<button v-permission="'product.create'">Create Product</button>
5. Module 3: Dashboard (2h)
(1) 5 ECharts charts
▶ Example: Dashboard with 5 ECharts Charts (Runs on CDN)
▶ Expand runnable example (104 lines)
Output:
Four KPI cards render in a row, followed by a 2-column grid of five charts: a smooth green sales line, blue order bars, a full-width category pie, a two-series user-activity line with legend, and an amber top-5 sales bar chart:
📊 Dashboard — 5 ECharts Charts
1. Four KPI cards
Today's Sales $12,345 ↑ +12% Today's Orders 342 ↑ +5%
Active Users 5,678 ↑ +8% Conversion 3.2% ↓ -2%
2. Five ECharts charts
┌─────────────────────┬─────────────────────┐
│ 📈 Sales Trend │ 📊 Orders │
├─────────────────────┴─────────────────────┤
│ 🎯 Category Share (pie, full width) │
├─────────────────────┬─────────────────────┤
│ 👥 User Activity │ 🏆 Top Sellers │
└─────────────────────┴─────────────────────┘
6. Module 4: Product Management (1.5h)
(1) Product list + CRUD
▶ Example: Product CRUD + Permission Control (Runs on CDN)
▶ Expand runnable example (116 lines)
Output:
A toolbar with a search box and a "New Product" button sits above a 7-column table listing the four mock products;
typing "iPhone" filters the table down to one row, and clicking "Edit" opens the modal pre-filled with that row's values:
📦 Product Management (Simplified CDN Version)
[ Search product name... ] [ ➕ New Product ]
ID Name Category Price Stock Status Actions
1 iPhone 15 Pro Electronics $999 50 active ✏️ Edit 🗑️ Delete
2 MacBook Pro Electronics $2499 5 active ✏️ Edit 🗑️ Delete
3 Cotton T-Shirt Clothing $29 200 active ✏️ Edit 🗑️ Delete
4 Old Model Electronics $99 0 inactive ✏️ Edit 🗑️ Delete
7. Module 5: Order Management (1h)
(1) Order list + details
▶ Example: Order List + Details + Status Transitions (Runs on CDN)
▶ Expand runnable example (104 lines)
Output:
Three orders render with colour-coded status tags;
"Confirm" only appears on the pending order and "Ship" only on the paid one.
Clicking "View" opens a dialog listing items with line totals and the timeline of status changes:
📋 Order Management
Order No. Customer Amount Status Actions
#1001 Alice $1028 pending View Confirm
#1002 Bob $50 paid View Ship
#1003 Carol $2499 shipped View
—— View #1001 ——
Order #1001
Customer: Alice Amount: $1028 Status: pending
Items:
iPhone 15 Pro × 1 = $999
Case × 1 = $29
Status history:
2026-07-15 10:00 - Order created
8. Module 6: User Management (1h)
(1) User list + role management
▶ Example: User Role Management + RBAC Editing (Runs on CDN)
▶ Expand runnable example (87 lines)
Output:
The user table lists four accounts with coloured role tags;
editing Carol opens a modal with five checkboxes, two of them already checked (editor and viewer), and saving replaces her tags with the current selection:
👥 User Role Management (RBAC)
ID Username Email Roles Actions
1 alice alice@x.com [admin] Edit roles
2 bob bob@x.com [manager] Edit roles
3 carol carol@x.com [editor] [viewer] Edit roles
4 eve eve@x.com [guest] Edit roles
—— Edit roles for carol ——
☑ [admin] Super admin (all permissions)
☐ [manager] Manager (products / orders / some users)
☑ [editor] Editor (product editing)
☑ [viewer] Viewer (read-only)
☐ [guest] Guest (minimal permissions)
[ Cancel ] [ Save ]
(2) The 5 role permissions
// utils/roles.ts
export const ROLES = {
admin: {
label: 'Admin',
permissions: ['*'] // full access
},
manager: {
label: 'Manager',
permissions: ['product.*', 'order.*', 'user.read']
},
editor: {
label: 'Editor',
permissions: ['product.read', 'product.edit', 'order.read']
},
viewer: {
label: 'Viewer',
permissions: ['*.read']
},
guest: {
label: 'Guest',
permissions: ['product.read']
}
}
9. Module 7: Marketing Campaigns (1h)
(1) Coupon management
▶ Example: Coupon List + Validity Window + Status (Runs on CDN)
▶ Try it YourselfOutput:
A five-column coupon table renders four rows, translating the raw type and status codes through the two lookup maps and colouring each status tag green, grey or amber:
🎟️ Marketing Campaigns (Coupon Management)
Coupon Code Type Discount Status Validity
SUMMER2026 Percentage 20% off Active 2026-07-01 ~ 2026-08-31
NEWUSER50 Fixed Amount $5 off Active 2026-01-01 ~ 2026-12-31
BLACKFRIDAY Percentage 50% off Expired 2025-11-25 ~ 2025-11-30
VIPONLY Fixed Amount $100 off Paused 2026-06-01 ~ 2026-12-31
10. Module 8: Deployment (1h)
(1) Build optimization
▶ Example: Vite Manual Chunk Splitting (Difficulty: ⭐⭐)
// vite.config.ts (production build optimization)
build: {
outDir: 'dist',
sourcemap: true, // for Sentry
minify: 'esbuild',
cssMinify: 'lightningcss',
rollupOptions: {
output: {
manualChunks: {
'vue-vendor': ['vue', 'vue-router', 'pinia'],
'echarts-vendor': ['echarts', 'vue-echarts'],
'ui-vendor': ['element-plus'],
'utils': ['axios', 'dayjs']
}
}
}
}
Output:
npm run build emits one chunk per manual group, so the vendor code is cached independently of the app code:
dist/index.html 0.62 kB │ gzip: 0.38 kB
dist/assets/index-a1b2c3d4.js 182.41 kB │ gzip: 64.20 kB
dist/assets/vue-vendor-e5f6g7h8.js 98.73 kB │ gzip: 36.15 kB
dist/assets/echarts-vendor-i9j0k1l2.js 412.06 kB │ gzip: 138.42 kB
dist/assets/ui-vendor-m3n4o5p6.js 268.55 kB │ gzip: 89.71 kB
dist/assets/utils-q7r8s9t0.js 42.18 kB │ gzip: 15.06 kB
dist/assets/index-u1v2w3x4.css 54.32 kB │ gzip: 9.88 kB
✓ built in 6.42s
(2) Deploying to Vercel
npm install -g vercel
vercel --prod
// vercel.json
{
"build": { "command": "npm run build" },
"outputDirectory": "dist",
"framework": "vite",
"rewrites": [
{ "source": "/(.*)", "destination": "/index.html" }
]
}
(3) Performance monitoring
// main.ts
import * as Sentry from '@sentry/vue'
Sentry.init({
app,
dsn: 'https://your-dsn@sentry.io/123',
tracesSampleRate: 0.1
})
11. Line-Count Statistics for All 8 Modules
| Module | Lines of code | Key features |
|---|---|---|
| 1 Project setup | 300 | Vite + Pinia + Router + Element Plus + ECharts |
| 2 Login and auth | 400 | JWT + route guard + permission directive + 5 roles |
| 3 Dashboard | 500 | 5 ECharts charts + 4 KPIs + real-time data |
| 4 Product management | 600 | CRUD + list + edit + image upload + permissions |
| 5 Order management | 400 | List + details + status transitions + export |
| 6 User management | 300 | List + role management + permission editing |
| 7 Marketing campaigns | 300 | Coupons + validity window + state machine |
| 8 Deployment | 200 | Vite build optimization + Vercel + Sentry |
| Total | 3000 | 8-module complete SaaS admin |
12. Quick Reference for 5 Common Mistakes
| Error | Symptom | Solution |
|---|---|---|
| Blank first screen | Router / Pinia load order is wrong | In main.ts call app.use(router) before app.use(pinia) |
| Permissions stop working | Roles do not refresh | watch permissions |
| 10,000 rows stutter | Poor table performance | Virtual scrolling with el-table-v2 |
| ECharts does not render | Container height is 0 | Set style="height: 300px" |
| 404 after deployment | SPA routing problem | Configure Vercel rewrites |
❓ FAQ
el-table-v2 (Element Plus's official virtual scrolling table) or vue-virtual-scroller. That is a 100x performance gain.vercel --prod is a one-line command.📖 Summary
- Vue 3 capstone project: an 8-module e-commerce SaaS admin (10-12h)
- Tech stack: Vue 3 + Vite + Pinia + Vue Router + Element Plus + ECharts + TypeScript
- The 8 modules: project setup / login and auth / dashboard / products / orders / users / marketing / deployment
- A 5-role permission system (admin / manager / editor / viewer / guest)
- 5 ECharts charts (line / bar / pie / funnel / leaderboard)
- Vercel deployment (one command + SPA rewrites)
- Complete TypeScript + performance optimization (virtual scrolling / manual chunks / Sentry)
13. 🎉 30 Lessons — Graduated!
Congratulations on finishing all 30 Vue 3 lessons! From the basics to an enterprise-grade project, you now have:
- ✅ Full command of the Vue 3 Composition API
- ✅ A full-stack integration of Pinia + Vue Router + Element Plus
- ✅ TypeScript + Vite engineering
- ✅ Performance optimization + error handling + testing
- ✅ Deployment (Vercel + Sentry)
- ✅ The ability to independently build enterprise-grade Vue applications
Suggested next steps:
- 🔥 Start the 5-language translation effort (Chinese → English → Japanese/Portuguese/Arabic)
- 🔥 Start the React tutorial (35-40h)
- 🔥 Start the Nuxt 3 tutorial (30h)
- 🔥 Upgrade the capstone project (add AI capabilities)
📝 Exercises
-
Basic (Difficulty: ⭐) Complete Module 1 (project setup) + Module 2 (login and auth):
- Vite + Vue 3 + Pinia + Element Plus
- Login page + dashboard (placeholder)
- The foundations of 5-role permissions
-
Intermediate (Difficulty: ⭐⭐) Complete 4 modules: setup / login / dashboard / products:
- Complete Vite + TypeScript configuration
- 5 ECharts charts
- Product CRUD (10 fields)
-
Challenge (Difficulty: ⭐⭐⭐) Complete all 8 modules plus deployment:
- All 8 modules (10-12h)
- Strong TypeScript typing
- Performance optimization (virtual scrolling / manual chunks)
- Test coverage (5 components + 3 E2E tests)
- Vercel deployment + Sentry integration
- Finish the 30-lesson Vue tutorial and graduate! 🎉