vue3项目技术点总结,vue难点 (适合0-1开发小伙伴)
Vue3 后台项目深度封装总结(结构化版)
一、核心工具封装
1. 增强型 Storage 封装
// utils/storage.js
import { ref, watchEffect } from 'vue' // 增加响应式支持
const storage = {
// 基础方法
set(key, val) {
localStorage.setItem(key, JSON.stringify(val))
},
get(key) {
return JSON.parse(localStorage.getItem(key))
},
remove(key) {
localStorage.removeItem(key)
},
// 响应式存储(Vue3 特色)
reactive(key, defaultValue) {
const val = ref(this.get(key) || defaultValue)
watchEffect(() => {
this.set(key, val.value)
})
return val
}
}
export default storage
使用场景:
// 在 setup 中使用响应式存储
const userToken = storage.reactive('token', 'default_token')
userToken.value = 'new_token' // 自动同步到 localStorage
二、Axios 深度封装
1. 智能请求层
// utils/request.js
import axios from 'axios'
import { ElMessage } from 'element-plus'
const service = axios.create({
baseURL: import.meta.env.VITE_API_URL, // 使用环境变量
timeout: 15000,
headers: { 'X-Custom-Header': 'vue3-admin' }
})
// 智能重试机制
const MAX_RETRY = 2
service.interceptors.response.use(null, async (error) => {
const { config, response } = error
if (!config || !response) return Promise.reject(error)
config.retryCount = config.retryCount || 0
if (config.retryCount < MAX_RETRY && response.status >= 500) {
config.retryCount++
await new Promise(resolve => setTimeout(resolve, 1000))
return service(config)
}
return Promise.reject(error)
})
// 增强型响应处理
service.interceptors.response.use(response => {
const { code, message } = response.data
if (code !== 200) {
ElMessage.error(message || '业务逻辑错误')
return Promise.reject(response.data)
}
return response.data
})
2. API 模块化 + TypeScript 支持
// api/user.ts
import service from '@/utils/request'
interface LoginParams {
username: string
password: string
}
interface UserInfo {
id: number
name: string
roles: string[]
}
export const login = (data: LoginParams) =>
service.post<{ token: string }>('/login', data)
export const getUserInfo = () =>
service.get<UserInfo>('/user/info')
三、状态管理最佳实践
1. Pinia 模块化封装
// stores/user.ts
import { defineStore } from 'pinia'
import { ref } from 'vue'
import { getUserInfo } from '@/api/user'
export const useUserStore = defineStore('user', () => {
const userInfo = ref<Nullable<UserInfo>>(null)
const loading = ref(false)
const fetchUserInfo = async () => {
loading.value = true
try {
userInfo.value = await getUserInfo()
} finally {
loading.value = false
}
}
return { userInfo, loading, fetchUserInfo }
})
2. 自动持久化插件
// plugins/persist.js
export const piniaPersist = (key) => ({
afterHydrate: (ctx) => {
const data = localStorage.getItem(key)
if (data) ctx.store.$patch(JSON.parse(data))
},
beforeUnmount: (ctx) => {
localStorage.setItem(key, JSON.stringify(ctx.store.$state))
}
})
// 使用
defineStore('user', () => {...}, {
plugins: [piniaPersist('user-store')]
})
四、高效工具函数设计
1. 组合式过滤器
// composables/useFilters.js
import { computed } from 'vue'
export const useFilters = () => {
const dateFormat = (timestamp, format = 'YYYY-MM-DD') => {
// 实现日期格式化逻辑
return computedDate
}
const currency = (value, symbol = '¥') => {
return `${symbol}${value.toFixed(2)}`
}
return { dateFormat, currency }
}
2. 防抖/节流指令
// directives/index.js
import { throttle, debounce } from 'lodash-es'
export const vThrottle = {
mounted(el, binding) {
const [fn, time = 300] = binding.value
el.addEventListener('click', throttle(fn, time))
}
}
export const vDebounce = {
mounted(el, binding) {
const [fn, time = 300] = binding.value
el.addEventListener('input', debounce(fn, time))
}
}
五、性能优化策略
1. 路由懒加载 + 分包策略
// router.js
const routes = [
{
path: '/dashboard',
component: () => import(/* webpackChunkName: "dashboard" */ '@/views/Dashboard.vue')
}
]
2. 智能组件加载
<!-- AsyncComponentWrapper.vue -->
<script setup>
import { defineAsyncComponent, shallowRef, onMounted } from 'vue'
const props = defineProps({
name: String
})
const component = shallowRef(null)
onMounted(async () => {
component.value = defineAsyncComponent(() =>
import(`@/components/${props.name}.vue`)
)
})
</script>
<template>
<component :is="component" v-if="component" />
</template>
六、安全增强措施
1. XSS 防御处理
// utils/xss.js
import xss from 'xss'
const xssOptions = {
whiteList: {
a: ['href', 'title'],
img: ['src']
}
}
export const sanitize = (html) => xss(html, xssOptions)
2. 敏感操作二次验证
// composables/useSecurity.js
import { ElMessageBox } from 'element-plus'
export const useConfirm = (message = '确认执行此操作?') => {
return new Promise((resolve) => {
ElMessageBox.confirm(message, '安全提醒', {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning'
}).then(resolve).catch(() => {})
})
}
// 使用
const handleDelete = async () => {
await useConfirm('确认删除该数据?')
// 执行删除操作
}
项目结构规范
src/
├─ api/ # 接口模块
├─ assets/ # 静态资源
├─ components/ # 全局组件
├─ composables/ # 组合式函数
│ ├─ useFilters.js
│ └─ useSecurity.js
├─ directives/ # 自定义指令
├─ layouts/ # 布局组件
├─ router/ # 路由配置
├─ stores/ # Pinia 状态管理
├─ styles/ # 全局样式
├─ types/ # TS 类型定义
├─ utils/ # 工具库
│ ├─ request.js
│ └─ storage.js
└─ views/ # 页面组件
关键注意事项
-
Tree Shaking 优化
// 按需引入 Element Plus import { ElButton, ElInput } from 'element-plus' app.use(ElButton).use(ElInput)
-
环境变量管理
# .env.production VITE_API_URL=https://api.yourdomain.com VITE_USE_MOCK=false
-
错误监控集成
// 全局错误捕获 app.config.errorHandler = (err, vm, info) => { console.error('[Global Error]', err, info) // 上报到 Sentry }
-
TypeScript 严格模式
// tsconfig.json { "compilerOptions": { "strict": true, "skipLibCheck": true } }
通过以上深度封装,可实现:
✅ 开发效率提升:所有基础能力开箱即用
✅ 维护成本降低:模块化设计+严格类型系统
✅ 性能优化保障:智能加载策略+资源优化
✅ 安全风险控制:XSS防御+敏感操作验证
✅ 扩展能力完备:组合式函数体系支持快速功能扩展