跳到主要内容Vue 3 最佳实践总结与开发技巧 | 极客日志JavaScriptNuct大前端
Vue 3 最佳实践总结与开发技巧
Vue 3 最佳实践涵盖项目结构配置、Composition API 逻辑复用、响应式系统优化、组件设计与缓存、性能监控与懒加载、国际化、路由管理、状态管理(Pinia)、单元测试、构建部署、安全实践、可访问性、PWA 开发及 SSR/SSG 方案。文章提供 TypeScript 集成、第三方库(Axios/VueUse)使用、动画过渡、动态组件及插件开发指南,并包含电商与资讯网站性能优化案例及迁移策略,旨在提升应用性能、可维护性与用户体验。
念念不忘29 浏览 Vue 3 最佳实践总结与开发技巧
在 Vue 3 的开发旅程中,掌握一系列最佳实践和技巧至关重要。这些实践和技巧不仅能提升开发效率,还能确保应用的性能、可维护性和用户体验达到最佳状态。本文将深入探讨 Vue 3 开发中的关键实践和技巧,帮助开发者在项目中充分发挥 Vue 3 的优势。
一、项目结构与配置
(一)项目结构
一个清晰的项目结构是成功开发的基础。推荐采用以下结构:
src/
├── assets/
├── components/
├── composables/
├── hooks/
├── layouts/
├── router/
├── stores/
├── utils/
├── views/
├── App.vue
├── main.js
├── env.d.ts
├── vite.config.ts
├── tsconfig.json
├── package.json
└── .eslintrc.js
(二)构建配置
使用 Vite 进行构建配置,确保开发和生产环境的高效性。
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import path from 'path';
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
},
},
server: {
: ,
: ,
},
: {
: ,
: ,
: {
: {
: ,
},
},
},
});
port
3000
open
true
build
target
'es2020'
minify
'terser'
terserOptions
compress
drop_console
true
二、Composition API 的使用
(一)逻辑复用
通过 composables 文件夹组织可复用逻辑。
import { ref, computed } from 'vue';
export function useCounter() {
const count = ref(0);
const doubleCount = computed(() => count.value * 2);
function increment() {
count.value++;
}
return { count, doubleCount, increment };
}
<!-- 在组件中使用 -->
<script setup>
import { useCounter } from '@/composables/useCounter';
const { count, doubleCount, increment } = useCounter();
</script>
<template>
<div>
<h1>{{ count }}</h1>
<p>{{ doubleCount }}</p>
<button @click="increment">Increment</button>
</div>
</template>
(二)类型安全
使用 TypeScript 为 Composition API 提供类型支持。
import { ref, computed } from 'vue';
export interface CounterState {
count: number;
doubleCount: number;
}
export function useCounter(): CounterState {
const count = ref(0);
const doubleCount = computed(() => count.value * 2);
function increment() {
count.value++;
}
return { count, doubleCount: doubleCount.value, increment };
}
三、响应式系统优化
(一)使用 shallowReactive 和 shallowRef
当不需要深层响应式处理时,使用 shallowReactive 和 shallowRef 以减少 Proxy 的嵌套代理。
import { shallowReactive } from 'vue';
const state = shallowReactive({
data: {
name: 'Vue 3',
description: 'A progressive JavaScript framework',
},
});
(二)避免不必要的响应式操作
仅对需要响应式的数据使用 ref 和 reactive。
import { ref } from 'vue';
const name = ref('Vue 3');
const description = 'A progressive JavaScript framework';
四、组件设计与开发
(一)组件拆分
将复杂组件拆分为多个小组件,提高可维护性和复用性。
<!-- ParentComponent.vue -->
<template>
<div>
<ChildComponent />
</div>
</template>
<script setup>
import ChildComponent from './ChildComponent.vue';
</script>
<!-- ChildComponent.vue -->
<template>
<div>
<h1>{{ title }}</h1>
<p>{{ content }}</p>
</div>
</template>
<script setup>
defineProps({
title: {
type: String,
required: true,
},
content: {
type: String,
required: true,
},
});
</script>
(二)组件缓存
使用 keep-alive 缓存不活动的组件实例。
<template>
<keep-alive include="TabComponent">
<component :is="currentComponent"></component>
</keep-alive>
</template>
<script setup>
import { ref } from 'vue';
import TabComponent from './TabComponent.vue';
const currentComponent = ref('TabComponent');
</script>
五、性能优化与监控
(一)懒加载
使用 defineAsyncComponent 实现组件的懒加载。
import { defineAsyncComponent } from 'vue';
const AsyncComponent = defineAsyncComponent(() => import('./AsyncComponent.vue'));
(二)性能监控
使用 Vue Devtools 和 Lighthouse 进行性能监控。
- 在开发过程中使用 Vue Devtools 监控性能。
- 在构建过程中使用 Lighthouse 进行自动化性能测试。
六、国际化与本地化
(一)使用 Vue I18n
import { createI18n } from 'vue-i18n';
const i18n = createI18n({
legacy: false,
locale: 'en',
messages: {
en: {
greeting: 'Hello, Vue 3!',
},
zh: {
greeting: '你好,Vue 3!',
},
},
});
export default i18n;
import { createApp } from 'vue';
import App from './App.vue';
import i18n from './i18n';
const app = createApp(App);
app.use(i18n);
app.mount('#app');
(二)动态切换语言
<template>
<div>
<button @click="changeLanguage('en')">English</button>
<button @click="changeLanguage('zh')">中文</button>
<h1>{{ $t('greeting') }}</h1>
</div>
</template>
<script setup>
import { useI18n } from 'vue-i18n';
const { t, locale } = useI18n();
function changeLanguage(lang) {
locale.value = lang;
}
</script>
七、路由管理
(一)路由懒加载
import { createRouter, createWebHistory } from 'vue-router';
const routes = [
{
path: '/',
component: () => import('./views/HomeView.vue'),
},
{
path: '/about',
component: () => import('./views/AboutView.vue'),
},
];
const router = createRouter({
history: createWebHistory(),
routes,
});
export default router;
(二)路由守卫
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth && !isAuthenticated) {
next('/login');
} else {
next();
}
});
八、状态管理
(一)使用 Pinia
import { defineStore } from 'pinia';
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0,
}),
actions: {
increment() {
this.count++;
},
},
});
<!-- 在组件中使用 -->
<script setup>
import { useCounterStore } from '@/stores/counter';
const counterStore = useCounterStore();
</script>
<template>
<div>
<h1>{{ counterStore.count }}</h1>
<button @click="counterStore.increment">Increment</button>
</div>
</template>
(二)模块化状态管理
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {
state: () => ({
user: null,
}),
actions: {
setUser(user) {
this.user = user;
},
},
});
import { useUserStore } from './modules/user';
export { useUserStore };
九、单元测试与集成测试
(一)使用 Vitest
import { describe, it, expect } from 'vitest';
import { useCounter } from '@/composables/useCounter';
describe('useCounter', () => {
it('increments count', () => {
const { count, increment } = useCounter();
increment();
expect(count.value).toBe(1);
});
});
(二)使用 Cypress
describe('Homepage', () => {
it('displays greeting', () => {
cy.visit('/');
cy.contains('Hello, Vue 3!').should('be.visible');
});
});
十、构建与部署
(一)使用 Vite 构建
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [vue()],
build: {
target: 'es2020',
minify: 'terser',
terserOptions: {
compress: {
drop_console: true,
},
},
},
});
(二)部署到生产环境
十一、开发工具与插件
(一)Vue Devtools
Vue Devtools 是 Vue 官方提供的浏览器扩展,用于调试 Vue 应用。
(二)ESLint 和 Prettier
使用 ESLint 和 Prettier 确保代码风格一致。
module.exports = {
extends: ['plugin:vue/vue3-recommended', 'prettier'],
rules: {
'vue/multi-word-component-names': 'off',
},
};
十二、团队协作与代码规范
(一)代码审查
(二)Git 工作流
git checkout -b feature/new-component
git add .
git commit -m 'Add new component'
git checkout develop
git merge feature/new-component
git branch -d feature/new-component
十三、持续集成与持续部署
(一)GitHub Actions
配置 GitHub Actions 实现自动化构建和部署。
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Install dependencies
run: npm install
- name: Build
run: npm run build
- name: Deploy
run: npm run deploy
(二)Netlify
npm install -g netlify-cli
netlify login
netlify deploy --prod
十四、安全性最佳实践
(一)输入验证
function validateInput(input) {
const regex = /^[a-zA-Z0-9\s]+$/;
return regex.test(input);
}
(二)内容安全策略
在 vite.config.ts 中配置 CSP。
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [vue()],
server: {
middlewareMode: true,
},
build: {
target: 'es2020',
minify: 'terser',
terserOptions: {
compress: {
drop_console: true,
},
},
},
});
十五、错误处理与日志记录
(一)全局错误处理
import { createApp } from 'vue';
import App from './App.vue';
import { createLogger } from './logger';
const app = createApp(App);
app.config.errorHandler = (err, vm, info) => {
createLogger().error(`Error in ${info}: ${err.message}`);
};
app.mount('#app');
(二)日志记录
import winston from 'winston';
const logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json()
),
transports: [
new winston.transports.File({ filename: 'error.log', level: 'error' }),
new winston.transports.File({ filename: 'combined.log' }),
],
});
if (process.env.NODE_ENV !== 'production') {
logger.add(new winston.transports.Console());
}
export function createLogger() {
return logger;
}
十六、可访问性(Accessibility)开发
(一)ARIA 属性
<template>
<button :aria-label="buttonLabel" @click="handleClick">
{{ buttonText }}
</button>
</template>
<script setup>
import { ref } from 'vue';
const buttonText = ref('Click me');
const buttonLabel = ref('Primary action button');
</script>
(二)键盘导航
<template>
<div role="tablist">
<div
v-for="(tab, index) in tabs"
:key="index"
role="tab"
:aria-selected="activeTab === index"
@click="activeTab = index"
@keydown.enter.space="activeTab = index"
tabindex="0"
>
{{ tab }}
</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
const tabs = ['Home', 'About', 'Contact'];
const activeTab = ref(0);
</script>
十七、渐进式 Web 应用(PWA)开发
(一)使用 Vite PWA 插件
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { VitePWA } from 'vite-plugin-pwa';
export default defineConfig({
plugins: [
vue(),
VitePWA({
registerType: 'autoUpdate',
includeAssets: ['favicon.ico', 'apple-touch-icon.png'],
manifest: {
name: 'My Vue 3 PWA',
short_name: 'My PWA',
description: 'A progressive web app built with Vue 3',
theme_color: '#ffffff',
icons: [
{
src: 'pwa-192x192.png',
sizes: '192x192',
type: 'image/png',
},
{
src: 'pwa-512x512.png',
sizes: '512x512',
type: 'image/png',
},
],
},
}),
],
});
(二)离线支持
import { precacheAndRoute } from 'workbox-precaching';
import { registerRoute } from 'workbox-routing';
import { CacheFirst } from 'workbox-strategies';
precacheAndRoute(self.__WB_MANIFEST);
registerRoute(
({ request }) => request.mode === 'navigate',
new CacheFirst({
cacheName: 'pages-cache',
plugins: [
new CacheableResponsePlugin({ statuses: [200] }),
],
})
);
十八、服务端渲染(SSR)与静态生成(SSG)
(一)使用 Nuxt 3
Nuxt 3 是 Vue 3 的官方框架,支持 SSR 和 SSG。
npm create nuxt-app@latest
(二)配置 Nuxt 3 项目
export default {
ssr: true,
target: 'static',
nitro: {
preset: 'vercel',
},
};
十九、第三方库集成
(一)使用 Axios
import axios from 'axios';
const api = axios.create({
baseURL: 'https://api.example.com',
});
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.provide('axios', api);
});
(二)使用 Vue Use
Vue Use 提供了许多实用的 Composition API。
import { ref } from 'vue';
import { useMouse } from '@vueuse/core';
export function useMouse() {
const { x, y } = useMouse();
return { x, y };
}
<!-- 在组件中使用 -->
<script setup>
import { useMouse } from '@/composables/useMouse';
const { x, y } = useMouse();
</script>
<template>
<div>Mouse position: {{ x }},{{ y }}</div>
</template>
二十、动画与过渡效果
(一)使用 Vue 过渡
使用 Vue 的 <transition> 组件实现动画效果。
<template>
<div>
<button @click="show = !show">Toggle</button>
<transition name="fade">
<div v-if="show">Hello, Vue 3!</div>
</transition>
</div>
</template>
<script setup>
import { ref } from 'vue';
const show = ref(true);
</script>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter-from, .fade-leave-to {
opacity: 0;
}
</style>
(二)使用 CSS 动画库
使用 CSS 动画库(如 Animate.css)增强动画效果。
<template>
<div>
<button @click="show = !show">Toggle</button>
<transition name="bounce">
<div v-if="show">Hello, Vue 3!</div>
</transition>
</div>
</template>
<script setup>
import { ref } from 'vue';
const show = ref(true);
</script>
<style>
@import 'animate.css';
.bounce-enter-active {
animation: bounceIn 0.5s;
}
.bounce-leave-active {
animation: bounceOut 0.5s;
}
</style>
二十一、动态组件与插件开发
(一)动态组件
使用 Vue 的 <component> 标签实现动态组件。
<template>
<div>
<button @click="currentComponent = 'Home'">Home</button>
<button @click="currentComponent = 'About'">About</button>
<button @click="currentComponent = 'Contact'">Contact</button>
<component :is="currentComponent"></component>
</div>
</template>
<script setup>
import Home from './components/Home.vue';
import About from './components/About.vue';
import Contact from './components/Contact.vue';
const currentComponent = ref('Home');
</script>
(二)开发插件
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.config.globalProperties.$myMethod = function () {
console.log('My plugin method');
};
});
<!-- 在组件中使用 -->
<script setup>
import { onMounted } from 'vue';
onMounted(() => {
console.log(this.$myMethod());
});
</script>
二十二、TypeScript 集成
(一)配置 TypeScript
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"strict": true,
"jsx": "preserve",
"moduleResolution": "node",
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"types": ["vite/client"]
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"exclude": ["node_modules"]
}
(二)使用 TypeScript
<script lang="ts" setup>
import { ref } from 'vue';
const count = ref(0);
const message = ref('Hello, Vue 3!');
const increment = () => {
count.value++;
};
</script>
<template>
<div>
<h1>{{ count }}</h1>
<p>{{ message }}</p>
<button @click="increment">Increment</button>
</div>
</template>
二十三、项目文档编写
(一)使用 VitePress
VitePress 是 Vue 团队提供的文档站点工具。
npm create vitepress@latest
(二)编写文档
# 项目文档
## 介绍
本项目是一个基于 Vue 3 的 Web 应用。
## 安装
```bash
npm install
开发
构建
#
#
参与 Vue.js 社区,获取支持和分享经验。
#
利用 Vue.js 官方文档和资源进行学习。
```bash
# 访问 Vue.js 官方文档
https://vuejs.org/
二十五、性能优化案例分析
(一)案例一:某电商网站的性能优化
该电商网站因商品数据庞大且页面交互复杂,首屏加载耗时过长。通过升级至 Vue 3 并利用其新特性进行优化后,性能显著提升。
- 优化措施:
- 采用 Composition API 重构组件,合理拆分与复用逻辑,减少不必要的状态更新与渲染。
- 利用
Suspense 组件异步加载商品列表与详情,搭配骨架屏提升用户体验。
- 开启
keep-alive 缓存商品分类与筛选组件,避免重复渲染。
- 使用
v-memo 指令缓存结果,减少重新渲染。
- 优化事件监听,采用事件委托和节流函数控制事件触发频率。
- 使用 Web Worker 将复杂计算(如数据排序、过滤)移到后台线程,减轻主线程负担。
- 采用路由懒加载、代码分割、保持组件精简策略,利用 Vue Router 的懒加载功能将路由组件按需加载,结合 Webpack 的代码分割将应用拆分为多个代码块,避免在单个组件中集成过多功能。
- 对 Vue、Element Plus 等静态资源通过 CDN 加载,减少本地打包体积。
- 使用 Nuxt 3 进行 SSR 渲染和静态站点生成,提升首屏加载速度并减少服务器负载。
- 使用 Vue Devtools、Lighthouse 和 Chrome Performance 等工具验证优化效果。
- 优化效果:
- 首屏加载时间缩短近 60%。
- 滚动流畅度提升,转化率增长。
(二)案例二:某资讯类网站的性能优化
该资讯类网站内容丰富且图片较多,移动端加载速度慢,用户流失严重。
- 优化措施:
- 采用响应式图片技术,依据设备屏幕尺寸及分辨率精准选择合适图片尺寸与格式,如移动端选用 WebP 格式缩小图片体积。
- 对 CSS 进行精简,移除未用样式,整理重复样式,减小 CSS 文件体积。
- 启用浏览器缓存机制,对图片、CSS、JavaScript 等静态资源设置长期缓存,借助缓存版本控制避免重复下载。
- 采用渐进式加载策略,先加载基础骨架屏,再逐步加载内容。
- 优化效果:
- 移动端平均加载时间从 8 秒降至 3 秒内。
- 页面切换流畅,用户留存率显著提高。
二十六、Vue 3 与 Vue 2 的迁移
(一)迁移策略
- 逐步迁移:采用 Vue 3 的兼容模式,逐步将 Vue 2 组件迁移到 Vue 3。
- 代码重构:利用 Vue 3 的新特性重构代码,提升性能和可维护性。
(二)迁移工具
- Vue 3 迁移构建工具:使用 Vue 提供的迁移构建工具,自动检测和修复 Vue 2 代码中的不兼容问题。
- Vue 3 迁移指南:参考 Vue 官方提供的迁移指南,了解详细的迁移步骤和注意事项。
npm install @vue/vue3-migration-build
二十七、未来趋势与展望
(一)Vue 3 的持续发展
(二)社区支持与生态建设
Vue 社区将持续壮大,提供更多优质的插件和工具。
(三)与新兴技术的结合
Vue 3 将与 Web Components、WebAssembly 等新兴技术结合,拓展应用场景。
二十八、总结
Vue 3 提供了多种内置优化和手动优化手段,包括响应式系统优化、编译优化、虚拟 DOM 优化、异步组件加载、代码分割、组件缓存等。通过合理利用这些策略,可以让应用性能更上一层楼,在大规模项目中提升用户体验和流畅度。希望开发者通过代码实践,深入理解这些特性的应用价值,并在项目中灵活运用。
相关免费在线工具
- Keycode 信息
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
- Escape 与 Native 编解码
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
- JavaScript / HTML 格式化
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
- JavaScript 压缩与混淆
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online