toRef 与 toRefs、shallowReactive 与 shallowRef在 Vue 3 中,生命周期的管理更加灵活,组合式 API 提供了钩子函数来替代 Vue 2 的生命周期钩子。同时,Vue 3 引入了自定义 Hook 机制,允许开发者复用组合逻辑。此外,toRef 和 toRefs 使我们能够将 reactive 对象的属性转换为 ref,而 shallowReactive 与 shallowRef 则提供了浅层的响应式处理方式。在本文中,我们将深入探讨这些 Vue 3 的新特性及其使用场景。
Vue 3 生命周期是指组件在创建、挂载、更新和销毁等过程中的一系列钩子函数。在 Vue 3 中,这些生命周期钩子已经被组合式 API 替换成了更加直观的函数形式,如 onMounted、onUpdated 等。
Vue 3 中的主要生命周期钩子包括:
onBeforeMount:组件挂载之前调用。onMounted:组件挂载之后调用。onBeforeUpdate:组件更新之前调用。onUpdated:组件更新之后调用。onBeforeUnmount:组件卸载之前调用。onUnmounted:组件卸载之后调用。这些钩子在 Vue 3 中通过组合式 API 使用,如下示例所示:
import { onMounted, onUnmounted } from 'vue';
export default {
setup() {
onMounted(() => {
console.log('Component mounted');
});
onUnmounted(() => {
console.log('Component unmounted');
});
}
};onMounted:用于在组件挂载后执行 DOM 操作或数据请求。onUpdated:适合在组件更新后对 DOM 进行调整。onUnmounted:用于清理计时器、取消订阅等操作。自定义 Hook 是 Vue 3 中的一个新特性,它允许开发者将可复用的逻辑封装在一个独立的函数中。自定义 Hook 类似于 Vue 2 中的混入,但更加灵活且不易产生命名冲突。
自定义 Hook 本质上就是一个函数,它返回我们想要复用的逻辑。可以将状态管理、业务逻辑等封装在自定义 Hook 中。
import { ref, onMounted, onUnmounted } from 'vue';
export function useMousePosition() {
const x = ref(0);
const y = ref(0);
const updateMouse = (e) => {
x.value = e.pageX;
y.value = e.pageY;
};
onMounted(() => {
window.addEventListener('mousemove', updateMouse);
});
onUnmounted(() => {
window.removeEventListener('mousemove', updateMouse);
});
return { x, y };
}在这个示例中,我们创建了一个自定义 Hook useMousePosition,它用于追踪鼠标位置。
在组件中使用自定义 Hook 十分简单,只需在 setup 中调用它:
import { useMousePosition } from './hooks/useMousePosition';
export default {
setup() {
const { x, y } = useMousePosition();
return { x, y };
}
};通过这种方式,组件可以轻松复用 useMousePosition 中的逻辑。
toRef 与 toRefstoRef 和 toRefs?toRef 和 toRefs 是 Vue 3 中引入的两个新工具,用于将 reactive 对象的某个属性或全部属性转为 ref。这在需要将响应式对象的某个属性作为 ref 使用时非常有用。
toRef:将 reactive 对象的某个属性转为 ref。toRefs:将 reactive 对象的所有属性转为 ref。toRefimport { reactive, toRef } from 'vue';
export default {
setup() {
const state = reactive({ name: 'John', age: 30 });
const nameRef = toRef(state, 'name'); // 将 name 属性转换为 ref
return { nameRef };
}
};nameRef 是一个 ref,它直接与 state.name 关联。通过修改 nameRef.value,state.name 也会随之更新。
toRefsimport { reactive, toRefs } from 'vue';
export default {
setup() {
const state = reactive({ name: 'John', age: 30 });
const { name, age } = toRefs(state); // 将所有属性转换为 ref
return { name, age };
}
};toRefs 会将 reactive 对象的所有属性转换为 ref,并保持双向绑定。
toRefs 解决了解构 reactive 对象时丢失响应式的场景。reactive 对象中的某个属性以 ref 的形式传递给子组件时,toRef 可以很方便地处理。shallowReactive 与 shallowRefshallowReactive 和 shallowRef?shallowReactive:创建一个浅层的响应式对象,只有第一层属性是响应式的,嵌套的对象不会被转为响应式。shallowRef:创建一个浅层的 ref,它只追踪对 ref 本身的修改,而不会追踪内部对象的变化。shallowReactiveimport { shallowReactive } from 'vue';
export default {
setup() {
const state = shallowReactive({
user: { name: 'John' },
age: 30
});
state.user.name = 'Doe'; // 不会触发响应式更新
state.age = 31; // 触发响应式更新
return { state };
}
};在这个例子中,age 是响应式的,而 user.name 的变化不会触发响应式更新,因为 shallowReactive 只会使第一层的属性响应式。
shallowRefimport { shallowRef } from 'vue';
export default {
setup() {
const user = shallowRef({ name: 'John' });
user.value = { name: 'Doe' }; // 这会触发响应式更新
user.value.name = 'Smith'; // 这不会触发响应式更新
return { user };
}
};在这个示例中,只有当 user.value 被重新赋值时,才会触发响应式更新,而 user.value.name 的变化不会触发更新。
shallowReactive 和 shallowRef** 用于性能优化**:在某些情况下,我们并不希望整个对象的每个属性都是响应式的,因为这可能会带来不必要的性能开销,shallow 版的响应式函数提供了一种更轻量级的选择。通过本文的学习,你应该掌握了以下关键点:
toRef 与 toRefs:掌握了将 reactive 对象的属性转换为 ref 的方法,解决了解构响应式对象丢失响应式的问题。shallowReactive 与 shallowRef:理解了浅层响应式对象的使用场景和它们在性能优化中的作用。这些新特性为 Vue 3 的开发提供了更强大的工具,使得组件逻辑复用和响应式数据的管理更加灵活和高效。在接下来的博客中,我们将继续探索 Vue 3 的更多高级特性和应用场景。如果你有任何疑问或
需要进一步讨论,欢迎在评论区留言。感谢你的阅读,期待在下一篇博客中继续与大家分享更多 Vue.js 和 Vue 3 的开发技巧与经验!