什么 Hooks?請(qǐng)叫我 Composables !
Hello,大家好,我是 Sunday。
昨天跟一位同學(xué)聊天,說(shuō)到:“在 Vue 中 hooks 是否可以使用 Vue 的生命周期?”
我一下就沒(méi)反應(yīng)過(guò)來(lái) “Vue 中有 hooks 了嗎?”。后來(lái)才明白,人家那叫 Composables(組合式函數(shù))
1. 什么是 hooks?
hook 翻譯過(guò)來(lái)是鉤子的意思。hooks 作為復(fù)數(shù),直譯就是 多個(gè)鉤子,在開發(fā)領(lǐng)域中特指 鉤子函數(shù)。
在開發(fā)領(lǐng)域,最初的 hook 是和回調(diào)鉤子綁定的。比如我們常說(shuō)的 git hooks 指的就是在 git 提交的時(shí)候所產(chǎn)生的多個(gè)回調(diào)鉤子函數(shù)。
圖片
不過(guò),在 React 16.8 的版本之后,React 文檔中提到了 React Hooks 的概念。
圖片
React Hooks 與傳統(tǒng) hook 的概念不太相同,他表示的是:以 use 開頭的自定義函數(shù)
在 React 中,所有內(nèi)置的 Hooks 和社區(qū)約定的自定義 Hooks 函數(shù)都遵循以 use 開頭的命名規(guī)則
自此,hooks 的概念才進(jìn)入到大部分開發(fā)者的視野中。
2. Vue 中的 “hooks”
Vue 中嚴(yán)格來(lái)說(shuō) 不存在 hooks 的概念。但是,卻有非常類似(也有人說(shuō)是抄襲)的概念,這就是 Composables(組合式函數(shù))
“組合式函數(shù)”(Composables) 是一個(gè)利用 Vue 的組合式 API 來(lái)封裝和復(fù)用有狀態(tài)邏輯的函數(shù)。
與 React 相同,它(Composables)的命名也要求 以 use 開頭的駝峰標(biāo)識(shí),而返回值則盡量返回 以 ref 包裹的響應(yīng)式數(shù)據(jù)
在 Vue 的官方文檔中,描述了 Composables 與 React Hooks 的關(guān)系:
圖片
3. Composables 示例
接下來(lái),我們就通過(guò)一個(gè) 鼠標(biāo)跟蹤器示例,來(lái)更加清楚的了解下 Composables 的應(yīng)用場(chǎng)景。
3.1 監(jiān)聽鼠標(biāo)位置的直接寫法
如果我們要直接在組件中使用組合式 API 實(shí)現(xiàn)鼠標(biāo)跟蹤功能,它的代碼會(huì)是這樣:
<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
const x = ref(0)
const y = ref(0)
function update(event) {
x.value = event.pageX
y.value = event.pageY
}
onMounted(() => window.addEventListener('mousemove', update))
onUnmounted(() => window.removeEventListener('mousemove', update))
</script>
<template>Mouse position is at: {{ x }}, {{ y }}</template>這個(gè)代碼邏輯并不復(fù)雜:
- 首先我們使用 ref 定義了兩個(gè)響應(yīng)式數(shù)據(jù) x、y
- 然后在 onMounted 和 onUnmounted 生命周期中,完成事件的掛載和銷毀
- 通過(guò) update 方法,修改響應(yīng)式數(shù)據(jù)的值,并展示在頁(yè)面中
這樣的代碼作用在單獨(dú)的組件里,如果想要 復(fù)用 就比較麻煩了。因此,就可以使用 Composables
3.2 使用 Composables
基于 Composables 封裝該邏輯:
// mouse.js
import { ref, onMounted, onUnmounted } from 'vue'
// 按照慣例,組合式函數(shù)名以“use”開頭
export function useMouse() {
// 被組合式函數(shù)封裝和管理的狀態(tài)
const x = ref(0)
const y = ref(0)
// 組合式函數(shù)可以隨時(shí)更改其狀態(tài)。
function update(event) {
x.value = event.pageX
y.value = event.pageY
}
// 一個(gè)組合式函數(shù)也可以掛靠在所屬組件的生命周期上
// 來(lái)啟動(dòng)和卸載副作用
onMounted(() => window.addEventListener('mousemove', update))
onUnmounted(() => window.removeEventListener('mousemove', update))
// 通過(guò)返回值暴露所管理的狀態(tài)
return { x, y }
}根據(jù)以上代碼所以,我們可知:
- Composables 中,應(yīng) 盡量使用 ref
- Composables 中,生命周期可正常調(diào)用,就像我們寫普通的 js 一樣
下面是它在組件中使用的方式:
<script setup>
import { useMouse } from './mouse.js'
const { x, y } = useMouse()
</script>
<template>Mouse position is at: {{ x }}, {{ y }}</template>



























