vue3中高阶使用与性能优化
在 Vue 3 中,setup()
是 Composition API 的核心入口,它提供了更灵活、可复用和模块化的代码组织方式。
文章目录
- 一、`setup()` 高阶使用技巧
- 1. **使用 `defineProps` 和 `defineEmits`(无需导入)**
- 2. **结合 TypeScript 类型推导**
- 3. **自定义逻辑封装为组合函数(Composable)**
- 4. **使用 `ref` 和 `reactive` 控制响应性粒度**
- 二、性能优化策略
- 1. **避免不必要的响应式数据**
- 2. **控制副作用生命周期**
- 3. **避免重复计算与渲染**
- 4. **减少模板中的复杂逻辑**
- 三、开发与维护建议
- 1. **结构清晰、职责单一**
- 2. **良好的命名规范**
- 3. **使用 `Suspense` 处理异步加载状态**
- 4. **使用 Devtools 调试**
- 四、完整示例:高性能封装组件
一、setup()
高阶使用技巧
1. 使用 defineProps
和 defineEmits
(无需导入)
Vue 3.3+ 支持自动推导 props 和 emits,无需手动引入函数。
<script setup>
const props = defineProps(['title', 'content']);
const emit = defineEmits(['update:title', 'submit']);function handleSubmit() {emit('submit', { data: props.content });
}
</script>
2. 结合 TypeScript 类型推导
提升类型安全性,支持自动补全和类型检查。
interface User {id: number;name: string;age?: number;
}const props = defineProps<{user: User;isActive: boolean;
}>();
3. 自定义逻辑封装为组合函数(Composable)
将可复用逻辑提取到独立函数中,便于跨组件复用。
// useUserValidation.ts
import { ref } from 'vue';export function useUserValidation(user) {const isValid = ref(false);function validate() {isValid.value = !!user.name && user.age > 0;}return { isValid, validate };
}
在组件中使用:
<script setup>
import { useUserValidation } from '@/composables/useUserValidation';const props = defineProps(['user']);
const { isValid, validate } = useUserValidation(props.user);
</script>
4. 使用 ref
和 reactive
控制响应性粒度
- 使用
ref
管理基础类型。 - 使用
reactive
管理对象/数组。 - 对不需要响应式的数据使用
markRaw()
或普通变量。
import { markRaw } from 'vue';const largeData = markRaw(JSON.parse(localStorage.getItem('bigData')));
二、性能优化策略
1. 避免不必要的响应式数据
- 对静态或大数据量对象使用
markRaw()
,防止 Vue 自动将其转换为响应式对象。
const config = markRaw({ theme: 'dark', version: '1.0.0' });
2. 控制副作用生命周期
- 使用
onBeforeUnmount
清理副作用(如定时器、事件监听器)。 - 使用
effectScope
管理多个响应式依赖的生命周期。
import { effectScope, onBeforeUnmount } from 'vue';const scope = effectScope();scope.run(() => {const count = ref(0);watchEffect(() => {console.log(count.value);});onBeforeUnmount(() => {scope.stop(); // 手动清理所有副作用});
});
3. 避免重复计算与渲染
- 使用
computed
缓存计算结果。 - 使用
v-once
或<keep-alive>
缓存静态内容。 - 使用
key
控制组件重新渲染时机。
<template><div :key="user.id"><!-- 当 user.id 变化时才会重新渲染 -->{{ computedName }}</div>
</template>
4. 减少模板中的复杂逻辑
- 模板中应尽量只调用简单变量或
computed
,避免直接写复杂表达式。 - 将复杂逻辑封装到
methods
或 Composable 函数中。
三、开发与维护建议
1. 结构清晰、职责单一
- 每个组件只做一件事。
- 抽离通用逻辑到
composables/
目录下。
2. 良好的命名规范
- 组合函数命名以
useXxx
开头(如useAuth
,useFetch
)。 - 文件名使用大写驼峰命名法(如
UserProfile.vue
)。
3. 使用 Suspense
处理异步加载状态
- 结合异步组件实现优雅加载体验。
<template><Suspense><AsyncComponent /><template #fallback>加载中...</template></Suspense>
</template>
4. 使用 Devtools 调试
- 利用 Vue Devtools 查看组件树、响应式依赖、性能面板等信息。
- 使用
console.warn()
或error
提醒潜在问题。
四、完整示例:高性能封装组件
<template><div class="data-table"><table><thead><tr v-for="header in headers" :key="header.key"><th>{{ header.label }}</th></tr></thead><tbody><tr v-for="row in rows" :key="row.id"><td v-for="col in headers" :key="col.key">{{ row[col.key] }}</td></tr></tbody></table></div>
</template><script setup>
import { ref, computed, onMounted } from 'vue';
import { fetchData } from '@/api/data';const props = defineProps({headers: {type: Array,required: true}
});const data = ref([]);
const loading = ref(false);async function loadData() {loading.value = true;try {const result = await fetchData();data.value = result;} finally {loading.value = false;}
}onMounted(loadData);const rows = computed(() => {return data.value.map(item => ({...item,fullName: `${item.firstName} ${item.lastName}`}));
});
</script>