Vue 3 配合 TypeScript 是现代前端开发的主流组合。作为冉冉博客的前端教程系列,今天分享一个企业级项目的完整架构设计。
一、项目结构设计
清晰的项目结构是大型项目的基础:
src/
├── assets/ # 静态资源
├── components/ # 公共组件
│ ├── base/ # 基础组件 (Button, Input...)
│ ├── business/ # 业务组件
│ └── layout/ # 布局组件
├── composables/ # 组合式函数
│ ├── useAuth.ts
│ ├── useFetch.ts
│ └── usePagination.ts
├── directives/ # 自定义指令
├── hooks/ # 生命周期钩子
├── plugins/ # 插件配置
├── router/ # 路由配置
├── services/ # API 服务层
├── stores/ # 状态管理 (Pinia)
├── types/ # TypeScript 类型定义
├── utils/ # 工具函数
├── views/ # 页面组件
└── App.vue
二、TypeScript 类型定义
完善的类型定义是代码质量的保障:
// types/api.ts
interface ApiResponse {
code: number;
data: T;
message: string;
}
interface PageParams {
page: number;
pageSize: number;
}
interface PageResult {
list: T[];
total: number;
page: number;
pageSize: number;
}
// types/user.ts
interface User {
id: number;
username: string;
email: string;
avatar?: string;
roles: string[];
createdAt: string;
}
type UserStatus = 'active' | 'inactive' | 'banned';
三、Pinia 状态管理
// stores/user.ts
import { defineStore } from 'pinia';
import { ref, computed } from 'vue';
import type { User } from '@/types';
export const useUserStore = defineStore('user', () => {
const userInfo = ref(null);
const token = ref('');
const isLoggedIn = computed(() => !!token.value);
const isAdmin = computed(() => userInfo.value?.roles.includes('admin'));
async function login(username: string, password: string) {
const res = await api.login({ username, password });
token.value = res.data.token;
userInfo.value = res.data.user;
}
function logout() {
token.value = '';
userInfo.value = null;
}
return { userInfo, token, isLoggedIn, isAdmin, login, logout };
});
四、组合式函数封装
提取复用逻辑,提高代码质量:
// composables/usePagination.ts
import { ref, computed } from 'vue';
import type { PageParams, PageResult } from '@/types';
export function usePagination(
fetchFn: (params: PageParams) => Promise>
) {
const list = ref([]);
const loading = ref(false);
const total = ref(0);
const page = ref(1);
const pageSize = ref(20);
const totalPages = computed(() => Math.ceil(total.value / pageSize.value));
async function loadData() {
loading.value = true;
try {
const res = await fetchFn({ page: page.value, pageSize: pageSize.value });
list.value = res.data.list;
total.value = res.data.total;
} finally {
loading.value = false;
}
}
function setPage(newPage: number) {
page.value = newPage;
loadData();
}
return { list, loading, total, page, pageSize, totalPages, loadData, setPage };
}
五、API 服务层设计
// services/user.ts
import type { User, ApiResponse } from '@/types';
export const userService = {
getList(params: { page: number; pageSize: number }) {
return http.get>('/users', { params });
},
getById(id: number) {
return http.get>(`/users/${id}`);
},
create(data: Partial) {
return http.post>('/users', data);
},
update(id: number, data: Partial) {
return http.put>(`/users/${id}`, data);
},
delete(id: number) {
return http.delete>(`/users/${id}`);
},
};
六、路由权限控制
// router/guard.ts
import type { Router } from 'vue-router';
import { useUserStore } from '@/stores/user';
export function setupRouterGuard(router: Router) {
router.beforeEach(async (to, from, next) => {
const userStore = useUserStore();
const requiresAuth = to.meta.requiresAuth;
const requiredRoles = to.meta.roles as string[] | undefined;
if (requiresAuth && !userStore.isLoggedIn) {
next('/login');
return;
}
if (requiredRoles && !userStore.hasRole(requiredRoles)) {
next('/403');
return;
}
next();
});
}
七、性能优化技巧
- 路由懒加载:按模块拆分,配合预加载策略
- 组件懒加载:大组件使用 defineAsyncComponent
- 图片优化:WebP 格式、懒加载、CDN
- Tree Shaking:按需引入,清理无用代码
- 虚拟列表:大数据列表使用虚拟滚动
- 缓存策略:HTTP 缓存、Vue 缓存
Vue 3 + TypeScript 是现代前端开发的黄金组合。掌握这些架构设计和最佳实践,能让你在企业级项目中游刃有余。更多前端干货,欢迎持续关注冉冉博客。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END















暂无评论内容