

Vue3 性能优化技巧总结
用shallowReactive替代reactive,性能瞬间起飞
Vue3 的reactive默认是深度响应式,大型数据结构稍有变动就触发整个组件重渲染,性能堪忧。
解决方案:使用shallowReactive,只追踪第一层属性的变化,就像开启了“响应式节能模式”。
1import { shallowReactive } from 'vue'; 2constuserInfo = shallowReactive({ 3 name:'前端码畜', 4 address: {city:'',street:''}, 5 hobbies: ['写代码','写Bug'] 6}); 7userInfo.name ='Vue 高手'; // ✅ 会触发更新 userInfo.address.city ='北京'; // ❌ 不会触发更新!
为什么推荐?
对于如表格数据、API 响应等大数据对象,
shallowReactive用toRefs解构响应式对象,清爽优雅
每次都手动state.xxx获取属性太繁琐?
解决方案: 使用toRefs一键将响应式对象转为独立的ref。
1import{ reactive, toRefs }from'vue'; 2constuser = reactive({ name:'张三',age:25 }); 3const{ name, age } = toRefs(user); 4name.value ='李四';// ✅ 自动响应更新
为什么推荐? 减少冗余逻辑,让模板更简洁,开发更流畅。
用watchEffect自动追踪依赖,响应式更聪明
普通watch用法太啰嗦,还得手动指定依赖源?
解决方案: watchEffect`自动感知依赖,数据变了就触发。
1import { ref, watchEffect } from 'vue'; 2constcount = ref(0); 3constdouble = ref(0); 4watchEffect(()=>{ 5 double.value = count.value * 2; 6});
为什么推荐?
适用于表单联动、缓存数据、动态依赖场景,响应式编程首选。
使用Suspense异步组件加载更丝滑
问题:异步组件加载时页面一片空白,用户体验不佳?
解决方案:用Suspense包裹异步组件,优雅展示 loading 状态。
1<template> 2 <Suspense> 3 <template #default> 4 <AsyncComponent /> 5 </template> 6 <template #fallback> 7 <div>组件加载中…</div> 8 </template> 9 </Suspense> 10</template> 11<script setup> 12import { defineAsyncComponent } from 'vue'; 13const AsyncComponent = defineAsyncComponent(() => import('./AsyncComponent.vue')); 14</script>
为什么推荐?提升异步组件加载体验,优化首屏性能。
用Teleport让弹窗随心所欲渲染到任何位置
问题:模态框、菜单层级混乱、z-index 失控?
解决方案:使用Teleport将内容直接传送到body或其他 DOM 节点。
1<template> 2 <button @click="show = true">打开弹窗</button> 3 <Teleport to="body"> 4 <div v-if="show" class="modal"> 5 <button @click="show = false">关闭</button> 6 </div> 7 </Teleport> 8</template>
为什么推荐?彻底解决样式冲突和 DOM 结构限制,是构建组件库的必杀技。
v-copy,实现一键复制
问题:每次复制内容都要手动写execCommand很麻烦?
解决方案:封装成一个可复用的自定义指令:
1app.directive('copy', { 2 mounted(el, binding) { 3 el.addEventListener('click', () => { 4 consttextarea =document.createElement('textarea'); 5 textarea.value = binding.value; 6 document.body.appendChild(textarea); 7 textarea.select(); 8 document.execCommand('copy'); 9 document.body.removeChild(textarea); 10 }); 11 } 12});
使用方式:
<button v-copy="'复制这段话'">点我复制</button>
为什么推荐?逻辑集中、组件更简洁、交互更友好。
使用 Pinia 插件,扩展状态管理功能
问题:Pinia 状态管理逻辑越来越庞杂,难以复用?
解决方案:自定义插件统一扩展所有 store 的功能:
1// 插件:添加 $reset 方法 2constresetPlugin =({ store }) =>{ 3 store.$reset =()=>store.$patch(store.$initialState); 4}; 5constpinia = createPinia(); 6pinia.use(resetPlugin);
使用示例:
1constuserStore = useUserStore(); 2userStore.$reset();// 快速重置状态
为什么推荐?共享逻辑,结构清晰,是中大型项目中不可或缺的利器。
使用v-memo缓存列表项渲染
问题:大列表频繁重绘,性能直线下滑?
解决方案:用v-memo指令缓存渲染结果,只有依赖项变化才更新。
1<li v-for="item in items" :key="item.id" v-memo="[item.id, item.status]"> 2 {{ item.name }} - {{ item.status }} 3</li>
为什么推荐?显著减少无效更新,优化表格、虚拟滚动等性能瓶颈。
用useIntersectionObserver实现智能懒加载
问题:页面加载慢,大量图片资源拖垮性能?
解决方案:借助 VueUse 的useIntersectionObserver轻松实现图片懒加载。
1<script setup> 2 import { useIntersectionObserver } from '@vueuse/core'; 3 const target = ref(null); 4 const isVisible = ref(false); 5 useIntersectionObserver(target, ([entry]) => { 6 isVisible.value = entry.isIntersecting; 7 }); 8</script> 9<template> 10 <img ref="target" :src="isVisible ? 'img.jpg' : ''" alt="懒加载图"> 11</template>
为什么推荐?加快首屏加载速度,有利于 SEO 与移动端体验。
封装自定义 Hook(Composable),逻辑复用更高效
问题:表单校验、请求逻辑不断复制粘贴? 解决方案:封装为可复用的 Composable 函数。
1// useFormValidation.js 2export default function(){ 3 constemail = ref(''); 4 consterrors = ref({}); 5 constvalidate =()=>{ 6 errors.value = {}; 7 if(!email.value) errors.value.email ='邮箱不能为空'; 8 returnObject.keys(errors.value).length ===0; 9 }; 10 return{ 11 email, errors, validate }; 12}
在组件中使用:
1<script setup> 2 import useFormValidation from './useFormValidation'; 3 const { email, errors, validate } = useFormValidation(); 4</script>
为什么推荐?高度模块化、便于测试,复用率极高,是 Vue3 最值得投入的模式之一。
| 技巧 编号 | 技巧名称 | 应用价值 |
|---|---|---|
| #1 | shallowReactive | 减少不必要的响应式更新 |
| #2 | toRefs | 更优雅地解构响应式对象 |
| #3 | watchEffect | 自动依赖追踪 |
| #4 | Suspense | 提升异步组件体验 |
| #5 | Teleport | 解决组件渲染位置问题 |
| #6 | v-copy指令 | 实现一键复制 |
| #7 | Pinia 插件 | 优化状态管理逻辑 |
| #8 | v-memo | 缓存列表渲染 |
| #9 | useIntersectionObserver | 智能懒加载 |
| #10 | 自定义 Hook(Composable) | 逻辑封装与复用 |