
在 Vue 3 的开发实践中,掌握核心 API 能显著提升代码的可维护性和执行效率。下面结合实战场景,梳理 10 个关键技巧。
1. 响应式数据管理:ref 与 reactive
Vue 3 提供了 ref 和 reactive 两种响应式 API。ref 适合基本类型(如字符串、数字),它返回一个包含 value 属性的对象;而 reactive 则用于处理复杂对象或数组,直接返回代理对象。
import { ref, reactive } from 'vue';
// 基本类型使用 ref
const count = ref(0);
console.log(count.value); // 0
// 复杂对象使用 reactive
const state = reactive({
name: 'Vue 3',
version: '3.2.0',
});
console.log(state.name); // Vue 3
注意:访问 ref 定义的数据时必须加 .value,而 reactive 不需要。同时 reactive 不能用于基本类型。
2. 组合式 API (Composition API)
相比选项式 API,组合式 API 允许将逻辑组织成可复用的函数。通过 setup 函数,我们可以更灵活地管理组件状态,避免逻辑分散。
import { ref, computed } from 'vue';
export default {
setup() {
const count = ref(0);
const doubleCount = computed(() => count.value * 2);
function increment() {
count.value++;
}
return { count, doubleCount, increment };
},
};
这种方式让代码结构更清晰,尤其在处理复杂业务逻辑时,复用性更强。
3. 监听数据变化:watch 与 watchEffect
观察数据变动是常见需求。watch 可以精确指定监听源,支持深度监听和懒执行;watchEffect 则会自动追踪依赖,无需手动声明。
import { ref, watch, watchEffect } from 'vue';
const count = ref(0);
// 精确控制
watch(count, (newValue, oldValue) => {
console.log(`count changed from ${oldValue} to ${newValue}`);
});
// 自动追踪
watchEffect(() => {
console.log(`count is now ${count.value}`);
});
如果不确定具体依赖项,或者希望立即执行一次,watchEffect 会更顺手。
4. 跨组件通信:provide 与 inject
在深层嵌套组件中,层层传递 props 非常繁琐。provide 和 inject 解决了这个问题,特别适合全局状态(如主题、用户信息)的共享。
// 父组件
import { provide, ref } from 'vue';
export default {
setup() {
const message = ref('Hello from parent');
provide('message', message);
},
};
// 子组件
import { inject } from 'vue';
export default {
setup() {
const message = inject('message');
return { message };
},
};
这种按需注入的方式减少了组件间的耦合度。
5. 任意位置挂载:Teleport
Teleport 允许将组件内容渲染到 DOM 中的任意位置,常用于模态框、通知等需要脱离当前层级结构的场景。
<template>
<button @click="showModal = true">Open Modal</button>
<Teleport to="body">
<div v-if="showModal" class="modal">
<p>This is a modal!</p>
<button @click="showModal = false">Close</button>
</div>
</Teleport>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const showModal = ref(false);
return { showModal };
},
};
</script>
这不仅解决了样式隔离问题,也提升了用户体验。
6. 异步组件加载:Suspense
处理异步组件时,Suspense 可以在加载完成前显示占位内容,避免页面空白。
<template>
<Suspense>
<template #default>
<AsyncComponent />
</template>
<template #fallback>
<div>Loading...</div>
</template>
</Suspense>
</template>
<script>
import { defineAsyncComponent } from 'vue';
const AsyncComponent = defineAsyncComponent(() => import('./AsyncComponent.vue'));
export default {
components: { AsyncComponent },
};
</script>
这让异步加载逻辑更加简洁直观。
7. 双向绑定增强:v-model
Vue 3 改进了 v-model,支持多个绑定,并允许自定义事件名(如 modelValue 和 update:modelValue)。
<template>
<CustomInput v-model:firstName="firstName" v-model:lastName="lastName" />
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const firstName = ref('John');
const lastName = ref('Doe');
return { firstName, lastName };
},
};
</script>
自定义组件端需配合相应的 props 和 emit 实现:
<template>
<input :value="firstName" @input="$emit('update:firstName', $event.target.value)" />
<input :value="lastName" @input="$emit('update:lastName', $event.target.value)" />
</template>
<script>
export default {
props: ['firstName', 'lastName'],
};
</script>
这为表单交互提供了更大的灵活性。
8. TypeScript 支持:defineComponent
使用 defineComponent 包裹组件定义,能获得更好的类型推断和 IDE 提示,特别适合 TypeScript 项目。
import { defineComponent, ref } from 'vue';
export default defineComponent({
setup() {
const count = ref(0);
return { count };
},
});
虽然不强制使用,但在大型项目中能显著减少类型错误。
9. 多根节点:Fragment
Vue 3 原生支持 Fragment,组件模板可以有多个根节点,无需额外的 <div> 包裹,从而减少不必要的 DOM 层级。
<template>
<header>Header</header>
<main>Main Content</main>
<footer>Footer</footer>
</template>
这有助于优化渲染性能。
10. 自定义指令
Vue 3 允许开发者自定义指令来操作 DOM,例如自动聚焦或拖拽功能。
import { directive } from 'vue';
const vFocus = {
mounted(el) {
el.focus();
},
};
export default {
directives: {
focus: vFocus,
},
};
使用时直接在元素上添加 v-focus 即可,提供了灵活的底层 DOM 操作能力。
以上 10 个技巧涵盖了从响应式基础到高级特性的核心用法。在实际项目中灵活运用这些模式,能让你的 Vue 3 应用更加健壮且易于维护。


