Vue 3.0中核心的Composition API
在当今快速发展的前端生态系统中,Vue 3.0以其革命性的Composition API重新定义了组件开发的范式。作为Vue框架的一次重大进化,Composition API不仅解决了Options API在复杂组件中面临的逻辑复用和组织难题,更为开发者提供了更灵活、更强大的代码组织方式。
随着应用复杂度的不断提升,传统的Options API在处理大型组件时逐渐显现出局限性——相关逻辑被分散在不同的选项中,代码阅读和维护变得困难。Composition API应运而生,它允许开发者基于逻辑功能而非选项类型来组织代码,使得相关代码能够紧密聚合在一起,大大提升了代码的可读性和可维护性。
本文将介绍一些Vue 3.0核心的Composition API,从基础概念到高级用法,带您全面了解这一现代前端开发利器。
1. 响应式基础
1.1. ref
含义:创建一个包含单一响应式值的对象。
使用场景:用于定义单个基本类型(如字符串、数字)的响应式数据。
import { ref } from 'vue';
const count = ref(0);
function increment() {count.value++;
}
1.2. reactive
含义:创建一个深度响应的对象。
使用场景:用于定义包含多个属性的复杂数据结构。
import { reactive } from 'vue';
const state = reactive({count: 0,name: 'vue'
});
1.3. computed
含义:创建一个基于其他响应式状态的计算属性。
使用场景:当需要从其他响应式数据派生出新的值时使用。
import { ref, computed } from 'vue';
const count = ref(0);
const doubleCount = computed(() => count.value * 2);
1.4. readonly
含义:创建一个只读的响应式对象。
使用场景:保护状态数据不被外部修改。
import { reactive, readonly } from 'vue';
const state = reactive({ count: 0 });
const readonlyState = readonly(state);
1.5. watch
含义:监听一个或多个响应式数据的变化,并执行回调函数。
使用场景:需要对特定响应式数据的变化做出反应时使用。
import { ref, watch } from 'vue';
const count = ref(0);
watch(count, (newValue, oldValue) => {console.log(`Count changed from ${oldValue} to ${newValue}`);
});
1.6. watchEffect
含义:立即运行传入的副作用函数,并在其依赖的响应式状态发生变化时重新运行。
使用场景:用于自动收集依赖并重新执行副作用。
import { ref, watchEffect } from 'vue';
const count = ref(0);
watchEffect(() => {console.log(`Count is: ${count.value}`);
});
1.7. watchPostEffect
含义:与 watchEffect 类似,但在 DOM 更新后执行。
使用场景:需要在 DOM 更新后执行副作用时使用。
import { ref, watchPostEffect } from 'vue';
const count = ref(0);
watchPostEffect(() => {console.log(`DOM updated, count is: ${count.value}`);
});
1.8. watchSyncEffect
含义:与 watchEffect 类似,但在同一事件循环内同步执行。
使用场景:需要在同一事件循环内同步执行副作用时使用。
import { ref, watchSyncEffect } from 'vue';
const count = ref(0);
watchSyncEffect(() => {console.log(`Synchronous count: ${count.value}`);
});
2. 响应式工具
2.1. isRef
含义:检查一个值是否是一个 ref 对象。
使用场景:在处理混合类型数据时,确保安全地访问 ref 对象的值。
import { ref, isRef } from 'vue';
const count = ref(0);
console.log(isRef(count)); // true
2.2. unref
含义:返回 ref 对象的值,如果参数不是 ref 对象,则直接返回参数值。
使用场景:简化对 ref 对象值的访问。
import { ref, unref } from 'vue';
const count = ref(0);
console.log(unref(count)); // 0
2.3. toRef
含义:将响应式对象的某个属性转换为 ref 对象。
使用场景:在多个组件间共享响应式对象的某个属性。
import { reactive, toRef } from 'vue';
const state = reactive({ count: 0 });
const countRef = toRef(state, 'count');
2.4. toValue
含义:获取 ref 对象的值,如果参数不是 ref 对象,则直接返回参数值,类似于 unref。
使用场景:简化对 ref 对象值的访问。
import { ref, toValue } from 'vue';
const count = ref(0);
console.log(toValue(count)); // 0
2.5. toRefs
含义:将响应式对象的每个属性转换为 ref 对象。
使用场景:在多个组件间共享响应式对象的所有属性。
import { reactive, toRefs } from 'vue';const state = reactive({ count: 0, name: 'vue' });
const { count, name } = toRefs(state);
2.6. isProxy
含义:检查一个值是否是一个代理对象(由 reactive 或 readonly 创建)。
使用场景:确认一个对象是否是响应式或只读对象。
import { reactive, isProxy } from 'vue';
const state = reactive({ count: 0 });
console.log(isProxy(state)); // true
2.7. isReactive
含义:检查一个值是否是一个响应式对象。
使用场景:确认一个对象是否是响应式对象。
import { reactive, isReactive } from 'vue';
const state = reactive({ count: 0 });
console.log(isReactive(state)); // true
2.8. isReadonly
含义:检查一个值是否是一个只读对象。
使用场景:确认一个对象是否是只读对象。
import { readonly, isReadonly } from 'vue';
const state = readonly({ count: 0 });
console.log(isReadonly(state)); // true
3. 响应式进阶
3.1. shallowRef
含义:创建一个浅层响应式对象。
使用场景:当只需要浅层响应而不需要深度响应时使用。
import { shallowRef } from 'vue';
const state = shallowRef({ count: 0 });
state.value.count = 1; // 不会触发响应式
3.2. triggerRef
含义:手动触发 ref 对象的更新。
使用场景:当需要手动触发 ref 更新时间。
import { ref, triggerRef } from 'vue';
const state = ref({ count: 0 });
state.value.count = 1;
triggerRef(state); // 手动触发更新
3.3. customRef
含义:创建一个自定义的 ref,并控制其依赖追踪和通知。
使用场景:需要自定义 ref 的行为时使用。
import { customRef } from 'vue';
function useDebouncedRef(value, delay = 200) {let timeout;return customRef((track, trigger) => {return {get() {track();return value;},set(newValue) {clearTimeout(timeout);timeout = setTimeout(() => {value = newValue;trigger();}, delay);}};});
}const debounced = useDebouncedRef(0);
3.4. shallowReactive
含义:创建一个浅层响应式对象。
使用场景:当只需要浅层响应而不需要深度响应时使用。
import { shallowReactive } from 'vue';
const state = shallowReactive({ nested: { count: 0 } });
state.nested.count = 1; // 不会触发响应式
3.5. shallowReadonly
含义:创建一个浅层只读对象。
使用场景:当只需要浅层只读而不需要深度只读时使用。
import { shallowReadonly } from 'vue';
const state = shallowReadonly({ nested: { count: 0 } });
state.nested.count = 1; // 不会触发只读警告
3.6. toRaw
含义:返回代理对象的原始对象。
使用场景:需要获取响应式对象的原始非响应对象时使用。
import { reactive, toRaw } from 'vue';
const state = reactive({ count: 0 });
const rawState = toRaw(state);
3.7. markRaw
含义:标记一个对象,使其永远不会成为响应式对象。
使用场景:当不希望某个对象被 Vue 转换为响应式对象时使用。
import { markRaw } from 'vue';
const raw = markRaw({ count: 0 });
3.8. effectScope
含义:创建一个 effect 作用域,可以在这个作用域内收集和处理副作用。
使用场景:需要管理多个副作用并在适当时机停止它们时使用。
import { effectScope, ref } from 'vue';
const scope = effectScope();
scope.run(() => {const count = ref(0);watchEffect(() => {console.log(count.value);});
});
// 停止所有在这个作用域内收集的副作用
scope.stop();
3.9. getCurrentScope
含义:返回当前的 effect 作用域。
使用场景:在 effect 作用域内部获取当前作用域实例。
import { effectScope, getCurrentScope } from 'vue';
const scope = effectScope();
scope.run(() => {console.log(getCurrentScope() === scope); // true
});
3.10. onScopeDispose
含义:注册一个回调函数,当 effect 作用域被停止时调用。
使用场景:在 effect 作用域被停止时执行清理操作。
import { effectScope, onScopeDispose, ref, watchEffect } from 'vue';
const scope = effectScope();
scope.run(() => {const count = ref(0);watchEffect(() => {console.log(count.value);});onScopeDispose(() => {console.log('Scope disposed');});
});
scope.stop(); // 输出: "Scope disposed"
4. 生命周期函数
4.1. onMounted
含义:在组件挂载完成后调用。
使用场景:在组件挂载完成后执行初始化逻辑。
import { onMounted } from 'vue';
onMounted(() => {console.log('Component has been mounted');
});
4.2. onUpdated
含义:在组件更新完成后调用。
使用场景:在组件更新后执行逻辑。
import { onUpdated } from 'vue';
onUpdated(() => {console.log('Component has been updated');
});
4.3. onUnmounted
含义:在组件卸载后调用。
使用场景:在组件卸载后执行清理操作。
import { onUnmounted } from 'vue';
onUnmounted(() => {console.log('Component has been unmounted');
});
4.4. onBeforeMount
含义:在组件挂载前调用。
使用场景:在组件挂载前执行逻辑。
import { onBeforeMount } from 'vue';
onBeforeMount(() => {console.log('Component will mount soon');
});
4.5. onBeforeUpdate
含义:在组件更新前调用。
使用场景:在组件更新前执行逻辑。
import { onBeforeUpdate } from 'vue';
onBeforeUpdate(() => {console.log('Component will update soon');
});
4.6. onBeforeUnmount
含义:在组件卸载前调用。
使用场景:在组件卸载前执行清理操作。
import { onBeforeUnmount } from 'vue';
onBeforeUnmount(() => {console.log('Component will unmount soon');
});
4.7. onErrorCaptured
含义:在捕获一个来自后代组件的错误时调用。
使用场景:处理和记录错误。
import { onErrorCaptured } from 'vue';
onErrorCaptured((err, instance, info) => {console.error(err);return false;
});
4.8. onRenderTracked
含义:在组件的响应式依赖被追踪时调用。
使用场景:调试响应式依赖追踪。
import { onRenderTracked } from 'vue';
onRenderTracked((e) => {console.log('Render tracked:', e);
});
4.9. onRenderTriggered
含义:在组件的响应式依赖触发重新渲染时调用。
使用场景:调试响应式依赖触发。
import { onRenderTriggered } from 'vue';
onRenderTriggered((e) => {console.log('Render triggered:', e);
});
4.10. onActivated
含义:在 keep-alive 组件被激活时调用。
使用场景:在 keep-alive 组件激活时执行逻辑。
import { onActivated } from 'vue';
onActivated(() => {console.log('Component activated');
});
4.11. onDeactivated
含义:在 keep-alive 组件被停用时调用。
使用场景:在 keep-alive 组件停用时执行逻辑。
import { onDeactivated } from 'vue';
onDeactivated(() => {console.log('Component deactivated');
});
4.12. onServerPrefetch
含义:在组件的服务端渲染期间调用。
使用场景:在服务端渲染期间执行数据预取逻辑。
import { onServerPrefetch } from 'vue';
onServerPrefetch(() => {return fetch('/api/data').then((res) => {// 处理数据});
});