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