在Vue3发布后,Composition API作为一个重要的特性,彻底改变了我们组织Vue组件代码的方式。其中,自定义Hooks的概念源自React,但Vue3对其进行了重新设计和优化,使其更加符合Vue的开发理念。本文将深入探讨Vue3中的自定义Hooks,帮助你掌握这个强大的代码复用工具。
Hooks是一种特殊的函数,它可以让你在函数组件中使用状态和其他Vue特性。Vue3中的Hooks通常具有以下特征:
// Vue2 Mixin方式
const mouseMixin = {
data() {
return {
x: 0,
y: 0
}
},
mounted() {
window.addEventListener('mousemove', this.update)
},
methods: {
update(e) {
this.x = e.pageX
this.y = e.pageY
}
},
destroyed() {
window.removeEventListener('mousemove', this.update)
}
}
// Vue3 Hooks方式
function useMousePosition() {
const x = ref(0)
const y = ref(0)
const update = (e) => {
x.value = e.pageX
y.value = e.pageY
}
onMounted(() => {
window.addEventListener('mousemove', update)
})
onUnmounted(() => {
window.removeEventListener('mousemove', update)
})
return {
x, y }
}
Vue3的响应式系统是Hooks实现的基础,主要包括:
// 1. ref:适用于基础类型
const count = ref(0)
// 2. reactive:适用于对象类型
const state = reactive({
count: 0,
message: 'Hello'
})
// 3. computed:计算属性
const doubleCount = computed(() => count.value * 2)
// 4. watch:侦听器
watch(count, (newValue, oldValue) => {
console.log(`count changed from ${
oldValue} to ${
newValue}`)
})
Hooks可以使用所有的生命周期钩子:
function useLifecycleLogger() {
onBeforeMount(() => {
console.log('组件即将挂载')
})
onMounted(() => {
console.log('组件已挂载')
})
onBeforeUpdate(() => {
console.log('组件即将更新')
})
onUpdated(() => {
console.log('组件已更新')
})
onBeforeUnmount(() => {
console.log('组件即将卸载')
})
onUnmounted(() => {
console.log('组件已卸载')
})
}
Hooks可以与provide/inject配合使用:
// 在父组件中
function useThemeProvider() {
const theme = ref('light')
provide('theme', theme)
const toggleTheme = () => {
theme.value = theme.value === 'light' ? 'dark' : 'light'
}
return {
theme,
toggleTheme
}
}
// 在子组件中
function useTheme() {
const theme = inject('theme')
if (!theme) {
throw new