《从零构建企业级 Node.js + TypeScript 项目骨架:工程化最佳实践全解析》
收到你的反馈,我们来写一篇真正具备深度、结构清晰、代码严谨、适合 CSDN 发布并吸引收藏点赞的高质量技术文章。这篇文章我们选择一个非常实用且受关注度高的方向:
Vue3 + Vite 企业级项目架构设计详解(组件封装、状态管理、权限控制实战)
一、前言
Vue3 发布以来,配合 Vite 构建的开发体验已经彻底改变了前端工程模式。尤其在中大型企业项目中,如何构建一个可维护、可扩展、高性能的前端架构,成了前端开发工程化的关键挑战。
本文将基于实际企业项目经验,从以下几个核心方面讲解一套完整的 Vue3 项目架构设计:
- 项目结构分层与模块化策略
- 全局状态管理(Pinia)设计模式
- 通用组件的抽象与封装
- 权限控制逻辑的统一实现
- 环境变量与多环境构建管理
- 项目自动化配置优化(alias、自动引入等)
文章不仅有代码,还有思想和规范设计逻辑,适合希望构建企业级 Vue3 项目的开发者参考实践。
二、项目结构设计
目录结构
src/
├── api/ # 所有 API 请求封装
├── assets/ # 静态资源
├── components/ # 通用组件
├── directives/ # 自定义指令
├── hooks/ # 通用逻辑 Hooks
├── layouts/ # 页面布局
├── pages/ # 路由页面
├── router/ # 路由配置
├── store/ # 状态管理
├── utils/ # 工具函数
├── views/ # 页面视图
├── permission.ts # 权限控制
├── main.ts # 入口文件
└── App.vue
这种分层结构保证了项目逻辑清晰,易于维护。
三、状态管理:模块化 + 持久化(Pinia)
安装:
npm install pinia
初始化:
// main.ts
import { createPinia } from 'pinia';
const app = createApp(App);
app.use(createPinia());
示例模块:用户模块(store/modules/user.ts)
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {
state: () => ({
token: '',
userInfo: null,
}),
actions: {
setToken(token: string) {
this.token = token;
localStorage.setItem('token', token);
},
async fetchUserInfo() {
const res = await getUserInfo();
this.userInfo = res.data;
},
},
});
支持持久化,可以用插件如 pinia-plugin-persistedstate
自动持久化。
四、权限控制设计
我们采用路由守卫 + 权限白名单控制 + 动态路由注册的组合方式。
// permission.ts
import router from './router';
import { useUserStore } from '@/store/modules/user';
const whiteList = ['/login'];
router.beforeEach(async (to, from, next) => {
const userStore = useUserStore();
if (userStore.token) {
if (to.path === '/login') next('/');
else {
if (!userStore.userInfo) {
await userStore.fetchUserInfo();
// 动态添加权限路由
}
next();
}
} else {
whiteList.includes(to.path) ? next() : next('/login');
}
});
五、通用组件封装:表格 + 弹窗 + 分页器
表格组件(components/BaseTable.vue)
<template>
<el-table :data="data" v-bind="$attrs">
<slot />
</el-table>
</template>
<script setup lang="ts">
defineProps<{ data: any[] }>();
</script>
优势:
- 支持 v-bind 所有 table 属性
- 支持插槽扩展自定义列
封装这些基础组件可以大大减少冗余代码,提升开发效率。
六、统一 API 管理:Axios 封装
// api/http.ts
import axios from 'axios';
const service = axios.create({
baseURL: import.meta.env.VITE_API_URL,
timeout: 10000,
});
service.interceptors.request.use(config => {
const token = localStorage.getItem('token');
if (token) config.headers.Authorization = `Bearer ${token}`;
return config;
});
export default service;
接口模块封装:
// api/user.ts
import request from './http';
export function getUserInfo() {
return request.get('/user/info');
}
七、自动引入优化(unplugin-auto-import)
安装:
npm install unplugin-auto-import -D
在 vite.config.ts
配置:
import AutoImport from 'unplugin-auto-import/vite';
AutoImport({
imports: ['vue', 'vue-router', 'pinia'],
dts: 'src/auto-imports.d.ts',
}),
可实现自动引入 ref
、computed
等,无需重复 import。
八、环境变量与多环境配置
使用 .env
文件:
.env.development
.env.production
.env.staging
示例:
VITE_API_URL=https://dev.api.com
在代码中读取:
console.log(import.meta.env.VITE_API_URL);
九、动态菜单渲染与权限菜单生成
企业项目中,菜单往往来自服务端,需结合权限动态渲染。
1. 接口响应结构示例
[
{
"name": "Dashboard",
"path": "/dashboard",
"component": "Layout",
"children": [
{
"name": "Overview",
"path": "overview",
"component": "dashboard/Overview",
"meta": { "title": "概览", "icon": "Home", "roles": ["admin", "user"] }
}
]
}
]
2. 后端菜单转路由方法
// utils/permission.ts
export function transformMenuToRoute(menuList) {
return menuList.map(item => {
const route = {
path: item.path,
name: item.name,
component: () => import(`@/views/${item.component}.vue`),
meta: item.meta || {},
children: item.children ? transformMenuToRoute(item.children) : []
};
return route;
});
}
3. 路由动态添加
// permission.ts
const dynamicRoutes = transformMenuToRoute(serverMenuList);
dynamicRoutes.forEach(route => router.addRoute(route));
十、前端权限控制:按钮级别权限处理
针对按钮/模块的权限可以通过自定义指令控制显示:
// directives/permission.ts
import { useUserStore } from '@/store/modules/user';
export default {
mounted(el, binding) {
const { userInfo } = useUserStore();
const hasPermission = userInfo?.permissions.includes(binding.value);
if (!hasPermission) el.parentNode?.removeChild(el);
}
};
使用:
<el-button v-permission="'user:add'">新增用户</el-button>
十一、Element Plus 主题定制与暗黑模式
企业 UI 通常要求品牌色、夜间模式支持。
1. 安装插件
npm install element-plus --save
在 vite.config.ts
中配置按需引入:
import AutoImport from 'unplugin-auto-import/vite';
import Components from 'unplugin-vue-components/vite';
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
2. 暗黑模式配置
/* main.css */
html.dark {
--el-color-primary: #409eff;
background-color: #1f1f1f;
}
通过切换类名 html.dark
可启用暗黑风:
document.documentElement.classList.add('dark');
十二、项目部署优化建议
- 使用 Vite 的
base
配置支持部署路径:// vite.config.ts base: '/admin/',
- 利用 Nginx 实现前端静态资源缓存与 gzip 压缩
- 打包分析工具:
npm run build --report
- 使用
vite-plugin-compression
实现打包压缩 - 接入 Sentry、阿里云前端监控 SDK 进行上线监控