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