当前位置: 首页 > news >正文

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/       # 页面组件

关键注意事项

  1. Tree Shaking 优化

    // 按需引入 Element Plus
    import { ElButton, ElInput } from 'element-plus'
    app.use(ElButton).use(ElInput)
    
  2. 环境变量管理

    # .env.production
    VITE_API_URL=https://api.yourdomain.com
    VITE_USE_MOCK=false
    
  3. 错误监控集成

    // 全局错误捕获
    app.config.errorHandler = (err, vm, info) => {
      console.error('[Global Error]', err, info)
      // 上报到 Sentry
    }
    
  4. TypeScript 严格模式

    // tsconfig.json
    {
      "compilerOptions": {
        "strict": true,
        "skipLibCheck": true
      }
    }
    

通过以上深度封装,可实现:
开发效率提升:所有基础能力开箱即用
维护成本降低:模块化设计+严格类型系统
性能优化保障:智能加载策略+资源优化
安全风险控制:XSS防御+敏感操作验证
扩展能力完备:组合式函数体系支持快速功能扩展

相关文章:

  • 编译玄铁处理器RISC-V指令测试用例
  • SpringBlade 部署文档
  • 基于Python的CATIA装配体全约束自动化解决方案
  • JavaScript页面事件与滚动
  • mysql学习-事务隔离级别
  • 文件IO 2
  • 计算机科学技术研究者文献数据库推荐
  • 树莓派5 外设GPIO使能 PWM
  • DaVinci Resolve19.1下载:达芬奇调色中文版+安装步骤
  • 服务器ubuntu22.04上安装tiny-cuda-nn
  • STM32 + keil5 跑马灯
  • 深入理解 Apache Dagster:数据管道编排实战指南
  • 系统调用与中断
  • 鸿蒙学习手册(HarmonyOSNext_API16)_应用开发UI设计:Swiper
  • Swoole 的 Hyperf 框架和 Go 的 Gin 框架高并发原理以及技术实现对比分析
  • [C++面试] 智能指针面试点(重点)续4
  • 动手学深度学习:AlexNet
  • 从基础到实践(二十三):MCU选型设计指南
  • 避坑,c#开发人员学习开发app时.NET MAUI和Vue3 选择
  • 青少年编程与数学 02-013 初中数学知识点 04课题、图形与几何
  • 博柏利上财年营收下降17%,计划裁员1700人助推股价涨超18%
  • 来沪一个月几乎未花住宿钱,女子虚构卫生问题屡薅酒店羊毛被刑拘
  • 多家外资看好中国市场!野村建议“战术超配”,花旗上调恒指目标价
  • 学习教育期间违规吃喝,李献林、叶金广等人被通报
  • 巴西总统卢拉昨晚抵达北京
  • 河北邯郸一酒店婚宴发生火灾:众人惊险逃生,酒店未买保险