logoSpectreAlan's blogs
Vue3 性能优化技巧总结
标签:
Vue
js
类别:web前端
创建时间: 2024-11-05 14:35:38
字数总计: 4.92 k
建议阅读时长: 5 分钟
阅读量: 161

Vue3 性能优化技巧总结

技巧 1:shallowReactive

用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
能大幅减少不必要的重渲染。是 Vue3 项目提速的必备技巧!

技巧 2:toRefs

用toRefs解构响应式对象,清爽优雅

每次都手动state.xxx获取属性太繁琐?

解决方案: 使用toRefs一键将响应式对象转为独立的ref。

1import{ reactive, toRefs }from'vue'; 2constuser = reactive({ name:'张三',age:25 }); 3const{ name, age } = toRefs(user); 4name.value ='李四';// ✅ 自动响应更新

为什么推荐? 减少冗余逻辑,让模板更简洁,开发更流畅。

技巧 3:watchEffect

用watchEffect自动追踪依赖,响应式更聪明

普通watch用法太啰嗦,还得手动指定依赖源?

解决方案: watchEffect`自动感知依赖,数据变了就触发。

1import { ref, watchEffect } from 'vue'; 2constcount = ref(0); 3constdouble = ref(0); 4watchEffect(()=>{ 5 double.value = count.value * 2; 6});

为什么推荐?

适用于表单联动、缓存数据、动态依赖场景,响应式编程首选。

技巧 4:Suspense

使用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>

为什么推荐?提升异步组件加载体验,优化首屏性能。

技巧 5:Teleport

用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 结构限制,是构建组件库的必杀技。

技巧 6:自定义指令

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>

为什么推荐?逻辑集中、组件更简洁、交互更友好。

技巧 7:Pinia插件

使用 Pinia 插件,扩展状态管理功能

问题:Pinia 状态管理逻辑越来越庞杂,难以复用?

解决方案:自定义插件统一扩展所有 store 的功能:

1// 插件:添加 $reset 方法 2constresetPlugin =({ store }) =>{ 3 store.$reset =()=>store.$patch(store.$initialState); 4}; 5constpinia = createPinia(); 6pinia.use(resetPlugin);

使用示例:

1constuserStore = useUserStore(); 2userStore.$reset();// 快速重置状态

为什么推荐?共享逻辑,结构清晰,是中大型项目中不可或缺的利器。

技巧 8:v-memo

使用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>

为什么推荐?显著减少无效更新,优化表格、虚拟滚动等性能瓶颈。

技巧 9:useIntersectionObserver

用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 与移动端体验。

技巧 10:封装自定义 Hook

封装自定义 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 最值得投入的模式之一。

总结一下

技巧 编号技巧名称应用价值
#1shallowReactive减少不必要的响应式更新
#2toRefs更优雅地解构响应式对象
#3watchEffect自动依赖追踪
#4Suspense提升异步组件体验
#5Teleport解决组件渲染位置问题
#6v-copy指令实现一键复制
#7Pinia 插件优化状态管理逻辑
#8v-memo缓存列表渲染
#9useIntersectionObserver智能懒加载
#10自定义 Hook(Composable)逻辑封装与复用
吐槽一下
copyright