PC管理后台
2026/3/20大约 4 分钟
PC 管理后台技术详解
技术栈
| 技术 | 版本 | 用途 |
|---|---|---|
| Vue | 3.5.11 | 前端框架 |
| TypeScript | 5.6.2 | 类型安全 |
| Vite | 5.4.8 | 构建工具 |
| Ant Design Vue | 4.2.5 | UI 组件库 |
| Pinia | 2.2.2 | 状态管理 |
| Vue Router | 4.4.5 | 路由管理 |
| Vben Admin Pro | 5.3.2 | 管理后台框架 |
项目结构
salted-fish-web/
├── apps/
│ └── web-antd/ # 主应用 (Ant Design 版本)
│ ├── src/
│ │ ├── api/ # API 请求模块
│ │ │ └── core/ # 核心接口
│ │ ├── components/ # 业务组件
│ │ ├── layouts/ # 布局组件
│ │ ├── router/ # 路由配置
│ │ │ └── routes/ # 路由定义
│ │ ├── store/ # Pinia 状态
│ │ ├── utils/ # 工具函数
│ │ ├── views/ # 页面组件
│ │ ├── App.vue # 根组件
│ │ └── main.ts # 入口文件
│ ├── vite.config.mts # Vite 配置
│ ├── tsconfig.json # TS 配置
│ └── package.json # 应用依赖
├── packages/ # 共享包
│ ├── @core/ # 核心工具库
│ │ ├── base/ # 基础工具
│ │ ├── composables/ # 组合式函数
│ │ └── shared/ # 共享模块
│ ├── effects/ # 副作用模块
│ │ ├── hooks/ # 全局 Hooks
│ │ ├── layouts/ # 布局效果
│ │ └── request/ # 请求模块
│ └── business/ # 业务组件
├── scripts/ # 构建脚本
├── pnpm-workspace.yaml # Monorepo 配置
├── turbo.json # Turbo 构建配置
└── package.json # 根依赖
核心框架 - Vben Admin
Vben Admin 是一个开箱即用的企业级管理后台框架:
特性
- TypeScript 全覆盖:完整的类型定义
- Monorepo 架构:基于 pnpm workspace
- 现代构建:Vite + Turbo 加速
- 权限管理:细粒度的菜单和按钮权限
- 主题定制:支持暗黑模式和主题切换
- 国际化:内置 i18n 多语言支持
目录约定
views/
├── _core/ # 核心页面 (登录、错误页等)
├── dashboard/ # 仪表板
├── goods/ # 商品管理
├── publish/ # 发布管理
├── template/ # 模板管理
└── user-manage/ # 用户管理
API 模块设计
目录结构
src/api/
└── core/
├── auth.ts # 认证接口
├── user.ts # 用户接口
├── product.ts # 商品接口
├── goods-content.ts # 商品内容
├── goods-images.ts # 商品图片
├── goods-tags.ts # 商品标签
├── publish.ts # 发布接口
├── template.ts # 模板接口
├── cate.ts # 分类接口
├── regional.ts # 区域接口
├── run-config.ts # 运行配置
└── menu.ts # 菜单接口
请求封装示例
// api/core/product.ts
import { requestClient } from '#/api/request';
// 获取商品列表
export function getProductList(params: ProductListParams) {
return requestClient.get<ProductListResult>('/api/products/', { params });
}
// 创建商品
export function createProduct(data: ProductCreateData) {
return requestClient.post('/api/products/', data);
}
// 更新商品
export function updateProduct(id: number, data: ProductUpdateData) {
return requestClient.put(`/api/products/${id}/`, data);
}
// 删除商品
export function deleteProduct(id: number) {
return requestClient.delete(`/api/products/${id}/`);
}
路由配置
路由结构
// router/routes/index.ts
export const routes: RouteRecordRaw[] = [
{
path: '/',
component: BasicLayout,
redirect: '/dashboard',
children: [
{
path: 'dashboard',
name: 'Dashboard',
component: () => import('@/views/dashboard/index.vue'),
meta: { title: '仪表板', icon: 'dashboard' }
},
{
path: 'goods',
name: 'Goods',
component: () => import('@/views/goods/index.vue'),
meta: { title: '商品管理', icon: 'shop' }
},
// ... 更多路由
]
}
];
权限路由
// 动态路由加载
const asyncRoutes = [
{
path: '/user-manage',
meta: { roles: ['admin'] }, // 仅管理员可见
children: [...]
}
];
状态管理
Pinia Store 结构
store/
├── index.ts # Store 入口
└── modules/
├── user.ts # 用户状态
├── permission.ts # 权限状态
└── app.ts # 应用状态
用户状态示例
// store/modules/user.ts
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {
state: () => ({
token: '',
userInfo: null,
roles: []
}),
getters: {
isLoggedIn: (state) => !!state.token
},
actions: {
async login(credentials) {
const { token } = await loginApi(credentials);
this.token = token;
},
async getUserInfo() {
this.userInfo = await getUserInfoApi();
},
logout() {
this.token = '';
this.userInfo = null;
}
}
});
业务页面
商品管理页面
<!-- views/goods/index.vue -->
<template>
<div class="goods-container">
<!-- 搜索栏 -->
<SearchForm @search="handleSearch" />
<!-- 操作栏 -->
<div class="action-bar">
<a-button type="primary" @click="handleAdd">新增商品</a-button>
<a-button @click="handleBatchDelete">批量删除</a-button>
</div>
<!-- 数据表格 -->
<a-table
:columns="columns"
:data-source="dataSource"
:loading="loading"
:pagination="pagination"
@change="handleTableChange"
>
<template #action="{ record }">
<a-button @click="handleEdit(record)">编辑</a-button>
<a-button danger @click="handleDelete(record)">删除</a-button>
</template>
</a-table>
<!-- 编辑弹窗 -->
<EditModal ref="editModalRef" @success="refreshList" />
</div>
</template>
发布管理页面
<!-- views/publish/index.vue -->
<template>
<div class="publish-container">
<!-- 发布任务列表 -->
<TaskList :tasks="publishTasks" />
<!-- 发布配置 -->
<PublishConfig v-model:config="publishConfig" />
<!-- 操作按钮 -->
<div class="footer-actions">
<a-button @click="handleSave">保存配置</a-button>
<a-button type="primary" @click="handlePublish">开始发布</a-button>
</div>
</div>
</template>
构建配置
Vite 配置
// vite.config.mts
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': '/src',
'#': '/types'
}
},
server: {
port: 3000,
proxy: {
'/api': {
target: 'http://localhost:8000',
changeOrigin: true
}
}
},
build: {
rollupOptions: {
output: {
manualChunks: {
vue: ['vue', 'vue-router', 'pinia'],
antd: ['ant-design-vue']
}
}
}
}
});
Turbo 配置
// turbo.json
{
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
},
"dev": {
"cache": false,
"persistent": true
},
"lint": {},
"type-check": {}
}
}
开发命令
# 安装依赖
pnpm install
# 启动开发服务器
pnpm dev
# 构建生产版本
pnpm build
# 代码检查
pnpm lint
# 类型检查
pnpm type-check
样式方案
TailwindCSS
<template>
<div class="flex items-center justify-between p-4 bg-white rounded-lg shadow">
<span class="text-lg font-medium text-gray-800">标题</span>
<a-button type="primary">操作</a-button>
</div>
</template>
CSS Modules
<template>
<div :class="$style.container">
<span :class="$style.title">标题</span>
</div>
</template>
<style module>
.container {
display: flex;
padding: 16px;
}
.title {
font-size: 18px;
}
</style>
最佳实践
1. 组件设计
- 遵循单一职责原则
- 使用组合式 API (Composition API)
- 提取可复用的 composables
2. 类型安全
- 为 API 响应定义类型
- 使用泛型提高复用性
- 启用严格模式
3. 性能优化
- 路由懒加载
- 组件按需引入
- 合理使用 computed 和 watch