我将从多个层面详细说明前端架构设计的关键要素:
- 项目基础架构
├── public/ # 静态资源
├── src/
│ ├── api/ # API 接口管理
│ ├── assets/ # 项目资源文件
│ ├── components/ # 公共组件
│ ├── composables/ # 组合式函数
│ ├── config/ # 配置文件
│ ├── directives/ # 自定义指令
│ ├── hooks/ # 自定义钩子
│ ├── layouts/ # 布局组件
│ ├── router/ # 路由配置
│ ├── store/ # 状态管理
│ ├── styles/ # 全局样式
│ ├── utils/ # 工具函数
│ ├── views/ # 页面组件
│ ├── App.vue # 根组件
│ └── main.js # 入口文件
├── tests/ # 测试文件
├── .env # 环境变量
└── package.json
- 核心技术栈选型
// package.json
{
"dependencies": {
"vue": "^3.3.0",
"vue-router": "^4.0.0",
"pinia": "^2.0.0", // 状态管理
"axios": "^1.0.0", // HTTP 请求
"element-plus": "^2.0.0", // UI组件库
"vite": "^4.0.0", // 构建工具
"typescript": "^5.0.0", // TypeScript
"sass": "^1.0.0", // CSS预处理器
"jest": "^29.0.0" // 单元测试
}
}
- API封装示例
// src/api/request.ts
import axios from 'axios'
const request = axios.create({
baseURL: process.env.VUE_APP_API_BASE_URL,
timeout: 5000
})
// 请求拦截器
request.interceptors.request.use(
config => {
const token = localStorage.getItem('token')
if (token) {
config.headers['Authorization'] = `Bearer ${token}`
}
return config
},
error => Promise.reject(error)
)
// 响应拦截器
request.interceptors.response.use(
response => response.data,
error => {
if (error.response.status === 401) {
// 处理未授权
router.push('/login')
}
return Promise.reject(error)
}
)
export default request
- 状态管理设计
// src/store/modules/user.ts
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
state: () => ({
userInfo: null,
token: localStorage.getItem('token') || ''
}),
actions: {
async login(credentials) {
try {
const data = await loginApi(credentials)
this.setUserInfo(data.user)
this.setToken(data.token)
} catch (error) {
throw error
}
},
setUserInfo(user) {
this.userInfo = user
},
setToken(token) {
this.token = token
localStorage.setItem('token', token)
}
}
})
- 路由配置与权限控制
// src/router/index.ts
import { createRouter, createWebHistory } from 'vue-router'
import { useUserStore } from '@/store/modules/user'
const routes = [
{
path: '/login',
component: () => import('@/views/Login.vue'),
meta: { requiresAuth: false }
},
{
path: '/',
component: () => import('@/layouts/Default.vue'),
children: [
{
path: 'dashboard',
component: () => import('@/views/Dashboard.vue'),
meta: {
requiresAuth: true,
roles: ['admin', 'user']
}
}
]
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
router.beforeEach((to, from, next) => {
const userStore = useUserStore()
if (to.meta.requiresAuth && !userStore.token) {
next('/login')
} else {
next()
}
})
export default router
- 自定义Hook示例
// src/hooks/useRequest.ts
import { ref } from 'vue'
export function useRequest(requestFn) {
const data = ref(null)
const loading = ref(false)
const error = ref(null)
async function execute(...args) {
loading.value = true
error.value = null
try {
const result = await requestFn(...args)
data.value = result
} catch (e) {
error.value = e
} finally {
loading.value = false
}
}
return {
data,
loading,
error,
execute
}
}
- 性能优化策略
// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import compression from 'vite-plugin-compression'
export default defineConfig({
plugins: [
vue(),
compression() // Gzip压缩
],
build: {
rollupOptions: {
output: {
manualChunks: {
'vendor': ['vue', 'vue-router', 'pinia'],
'ui': ['element-plus']
}
}
},
chunkSizeWarningLimit: 1000
}
})
- 工具函数示例
// src/utils/index.ts
export const debounce = (fn: Function, delay: number) => {
let timer: NodeJS.Timeout | null = null
return function (...args: any[]) {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(this, args)
}, delay)
}
}
export const formatDate = (date: Date, format = 'YYYY-MM-DD'): string => {
// 日期格式化实现
}
export const storage = {
set(key: string, value: any) {
localStorage.setItem(key, JSON.stringify(value))
},
get(key: string) {
const value = localStorage.getItem(key)
return value ? JSON.parse(value) : null
}
}
- 错误处理与监控
// src/utils/errorHandler.ts
import * as Sentry from '@sentry/vue'
export function setupErrorHandling(app) {
if (process.env.NODE_ENV === 'production') {
Sentry.init({
app,
dsn: 'YOUR_SENTRY_DSN',
integrations: [
new Sentry.BrowserTracing()
]
})
}
app.config.errorHandler = (error, instance, info) => {
// 错误上报
Sentry.captureException(error)
console.error('Global Error:', error)
}
}
- 组件通信示例
// src/composables/useEventBus.ts
import mitt from 'mitt'
const emitter = mitt()
export function useEventBus() {
function emit(event: string, data?: any) {
emitter.emit(event, data)
}
function on(event: string, callback: Function) {
emitter.on(event, callback)
}
function off(event: string, callback: Function) {
emitter.off(event, callback)
}
return {
emit,
on,
off
}
}
这个架构设计考虑了以下几个关键点:
- 可维护性:清晰的目录结构和模块化设计
- 可扩展性:便于添加新功能和模块
- 性能优化:代码分割、懒加载等策略
- 安全性:API请求封装、权限控制
- 开发效率:组件复用、工具函数等
- 代码质量:TypeScript支持、错误处理
评论区