Vue3核心語法進階(Hook)

Vue3 自定義 Hook:讓你的代碼像樂高一樣“可復用”!

大家好,我是你們的前端小伙伴!上一篇我們聊了 Vue3 的生命周期,今天咱們繼續深入 Vue3 的核心利器——自定義 Hook(Custom Hook)

如果你已經用過 refreactivewatchonMounted 這些 Composition API,那你已經“會用工具了”。而今天我們要學的,是如何把一堆工具打包成一個“超級工具包”,哪里需要就往哪里一放,功能立馬就有了!

這個“超級工具包”,就是 自定義 Hook


什么是自定義 Hook?

想象一下,你在寫一個電商網站,有 5 個頁面都需要“獲取用戶信息 + 檢查登錄狀態 + 顯示用戶頭像”。

如果你在每個頁面都重復寫一遍:

const userInfo = ref(null)
const isLoggedIn = ref(false)onMounted(async () => {const data = await fetch('/api/user')userInfo.value = dataisLoggedIn.value = data ? true : false
})watch(userInfo, (newVal) => {if (newVal) console.log('用戶已登錄')
})

那……恭喜你,代碼已經“復制粘貼”了 5 遍!如果哪天接口變了,你得改 5 個地方,想想都頭大。

自定義 Hook 就是:把這段“通用邏輯”抽出來,變成一個函數,誰需要誰調用!


自定義 Hook 的本質

它就是一個以 use 開頭的普通函數,比如 useUseruseCartuseLocalStorage

它內部可以使用任何 Composition API(refwatchonMounted 等),然后把需要暴露的數據和方法 return 出去。


動手寫一個:useUser()?用戶信息 Hook

我們來寫一個真正可用的自定義 Hook!

// composables/useUser.js
import { ref, onMounted, watch } from 'vue'export function useUser() {const userInfo = ref(null)const isLoggedIn = ref(false)const loading = ref(true)// 模擬請求用戶數據const fetchUser = async () => {loading.value = truetry {const res = await fetch('/api/user')const data = await res.json()userInfo.value = dataisLoggedIn.value = !!data} catch (err) {console.error('獲取用戶失敗', err)} finally {loading.value = false}}// 組件掛載時自動獲取用戶onMounted(() => {fetchUser()})// 監聽用戶信息變化watch(userInfo, (newVal) => {if (newVal) {console.log(`歡迎回來,${newVal.name}!`)}})// 把你需要的東西 return 出去return {userInfo,isLoggedIn,loading,fetchUser // 也可以手動刷新}
}

文件名建議:composables/useXxx.js,這是 Vue 社區的約定。


在組件中使用它

現在,任何組件只要想用“用戶邏輯”,一句話搞定:

<!-- UserProfile.vue -->
<script setup>
import { useUser } from '@/composables/useUser'// 一行代碼,搞定用戶邏輯!
const { userInfo, isLoggedIn, loading, fetchUser } = useUser()
</script><template><div v-if="loading">加載中...</div><div v-else-if="isLoggedIn"><h2>歡迎,{{ userInfo.name }}!</h2><button @click="fetchUser">刷新</button></div><div v-else>請先登錄</div>
</template>

看到了嗎?組件代碼變得極其干凈,邏輯都被“封裝”到 useUser 里了。


自定義 Hook 的核心優勢

優勢說明
邏輯復用一套登錄邏輯,10 個頁面都能用
解耦清晰組件只管“視圖”,Hook 管“邏輯”
易于測試直接測試?useUser?函數,不用渲染組件
類型友好TypeScript 能自動推導返回值類型

高級用法:支持參數和返回函數

自定義 Hook 不只是“固定邏輯”,它也可以很靈活!

示例:useLocalStorage?—— 讓數據自動存到本地

// composables/useLocalStorage.js
import { ref, watch } from 'vue'export function useLocalStorage(key, initialValue) {// 從 localStorage 讀取,或用默認值const data = ref(JSON.parse(localStorage.getItem(key)) || initialValue)// 數據變化時,自動存到 localStoragewatch(data, (newVal) => {localStorage.setItem(key, JSON.stringify(newVal))}, { deep: true }) // deep: true 支持對象/數組return data
}

使用它:

// 計數器,刷新頁面也不會丟!
const count = useLocalStorage('count', 0)// 用戶設置
const settings = useLocalStorage('userSettings', { theme: 'dark' })

看,一個 Hook,支持任意 key 和默認值,真正做到了“通用”


常見誤區 & 注意事項

誤區 1:在普通函數里用?ref?就是 Hook?

No!只有在 setup<script setup> 中調用的函數,才能使用 Composition API。你的 useXxx 函數必須在組件上下文中調用。

誤區 2:Hook 可以 return 模板?

不能!Hook 只負責邏輯和數據,模板還是得在組件里寫。

最佳實踐:命名規范

  • 一定要以?use?開頭,比如?useMouseuseScrolluseFetch
  • 返回值盡量結構清晰,方便解構使用
  • 復雜邏輯可以拆分成多個小 Hook

實戰案例:useMouse?—— 跟蹤鼠標位置

// composables/useMouse.js
import { ref, onMounted, onUnmounted } from 'vue'export function useMouse() {const x = ref(0)const y = ref(0)const update = (e) => {x.value = e.clientXy.value = e.clientY}onMounted(() => {window.addEventListener('mousemove', update)})onUnmounted(() => {window.removeEventListener('mousemove', update)})return { x, y }
}

使用:

<script setup>
import { useMouse } from '@/composables/useMouse'
const { x, y } = useMouse()
</script><template><div>鼠標位置:{{ x }}, {{ y }}</div>
</template>

瞬間,你的組件就有了“追蹤鼠標”的超能力!


為什么叫“Hook”?

“Hook” 的意思是“鉤子”,它就像是把一段邏輯“鉤”進組件的生命周期中。

比如 onMounted 就是一個“鉤子”,告訴 Vue:“等組件掛載后,執行我這個函數”。

而自定義 Hook,就是把多個鉤子和邏輯打包,變成一個可復用的“增強包”。


總結:自定義 Hook 的靈魂

關鍵點說明
目的邏輯復用,避免重復代碼
形式useXxx()?函數,返回響應式數據和方法
能力可接收參數、可組合多個 API、可嵌套使用
好處代碼更清晰、維護更容易、團隊協作更高效

最后一句話

組件負責“長什么樣”,Hook 負責“怎么動”。

把通用邏輯封裝成 Hook,你的代碼就會像樂高積木一樣,拼裝自由,復用無憂

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/91947.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/91947.shtml
英文地址,請注明出處:http://en.pswp.cn/web/91947.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

工控領域協議之Modbus

Modbus 是一種通信協議&#xff0c;用于工業自動化領域中的設備之間的通信。它是一種串行通信協議&#xff0c;廣泛應用于連接不同設備、傳感器和執行器的工業控制系統。 Modbus 在工業控制系統、自動化設備、能源管理系統等領域得到廣泛應用。 Modbus 協議的基本特點&#xff…

大件垃圾識別 mAP↑28%:陌訊多模態融合算法實戰解析

一、行業痛點&#xff1a;大件垃圾識別的現實困境在城市環衛智能化轉型過程中&#xff0c;大件垃圾&#xff08;如廢舊家具、電器等&#xff09;的自動化識別與分揀成為關鍵環節。據住建部《城市環境衛生發展報告》顯示&#xff0c;傳統人工分揀模式下大件垃圾識別準確率不足 6…

vk框架或者普通函數封裝的一些函數可以拿取使用【會持續更新】

1.身份證校驗【通用】/*** function isIDCard* description 判斷是否為有效的身份證號碼。* param {string} idCard - 待驗證的身份證號碼。* returns {boolean} 返回驗證結果。*/ pubFun.isIDCard function (idCard) {// 身份證號碼為15位或者18位&#xff0c;15位時全為數字…

如何給Word和WPS文檔添加密碼或取消密碼

要保護Word和WPS文檔&#xff0c;可以為它們加密&#xff0c;加密有兩類&#xff1a;打開密碼和修改密碼。密碼設置有兩個入口&#xff0c;一個是在另存為&#xff0c;一個是在文件菜單。Word和WPS文字的路徑略有不同&#xff0c;微軟Office和WPS的其他套件也是如此操作。一、W…

uni-app項目gitignore文件示例

uni-app 忽略以下文件和目錄 DS_Store 忽略 UniApp 編譯生成的小程序相關目錄 unpackage/ uni_modules/ 忽略編輯器自動生成的文件 idea/ vscode/ 忽略日志文件 logs/ 忽略臨時文件 temp/ 忽略構建工具自動生成的文件 build/ 忽略 npm 安裝的包文件 package-lock.json yarn.loc…

LeetCode 135:分糖果

LeetCode 135&#xff1a;分糖果問題本質與核心挑戰 給定孩子的評分數組&#xff0c;需滿足 “每個孩子至少1顆糖果&#xff0c;相鄰評分高的孩子糖果更多”&#xff0c;求最少糖果總數。核心挑戰&#xff1a; 相鄰約束是雙向的&#xff08;左→右和右→左都需滿足&#xff09;…

【QT】安裝與配置

個人主頁&#xff1a;Guiat 歸屬專欄&#xff1a;QT 文章目錄1. QT簡介與準備工作1.1 什么是QT1.2 QT的版本選擇1.3 系統要求檢查2. QT安裝方式詳解2.1 官方在線安裝器2.2 離線安裝包2.3 包管理器安裝3. Windows平臺安裝配置3.1 Windows安裝步驟3.2 環境變量配置3.3 Visual Stu…

Java從入門到精通 - 算法、正則、異常

算法、正則、異常 此筆記參考黑馬教程&#xff0c;僅學習使用&#xff0c;如有侵權&#xff0c;聯系必刪 文章目錄算法、正則、異常1. 常見算法1.1 簡單認識算法1.1.1 什么是算法&#xff1f;1.1.2 為什么要學習算法&#xff1f;1.2 排序算法1.2.1 冒泡排序1.2.1.1 實現冒泡排…

題單【排序】

P1271 【深基9.例1】選舉學生會 P1271 【深基9.例1】選舉學生會 - 洛谷 【方法一】快速排序 使用sort()&#xff0c;注意數組的范圍&#xff01;&#xff01;&#xff01; #include<bits/stdc.h> using namespace std;int a[2000000],n,m;int main() {cin>>n>&g…

【機器學習】(算法優化二)提升算法之:AdaBoost與隨機梯度

文章目錄一、 AdaBoost&#xff1a;自適應提升算法1、AdaBoost數學原理詳解1.1、 目標函數1.2、 樣本權重更新的邏輯1.3、 模型權重計算的含義1.4、 AdaBoost的核心思想2、為什么AdaBoost如此有效&#xff1f;二、 隨機梯度提升算法&#xff1a;梯度優化下更精細的優化1、隨機梯…

力扣 hot100 Day65

75. 顏色分類 給定一個包含紅色、白色和藍色、共 n 個元素的數組 nums &#xff0c;原地 對它們進行排序&#xff0c;使得相同顏色的元素相鄰&#xff0c;并按照紅色、白色、藍色順序排列。 我們使用整數 0、 1 和 2 分別表示紅色、白色和藍色。 必須在不使用庫內置的 sort 函…

12.Linux 磁盤管理

Linux : 磁盤管理 一、磁盤設備命名規則磁盤類型設備命名模式示例特點SATA/SCSI/SAS/dev/sdXsda&#xff08;第一塊硬盤&#xff09; sda1&#xff08;第一塊硬盤第一分區&#xff09;機械硬盤/通用接口NVMe/dev/nvmeXnYpZnvme0n1&#xff08;第一通道第一塊盤&#xff09; …

《Linux服務與安全管理》| DHCP服務器安裝和配置

《Linux服務與安全管理》| DHCP服務器安裝和配置 目錄 《Linux服務與安全管理》| DHCP服務器安裝和配置 一、點擊“編輯虛擬機設置”&#xff0c;配置三臺虛擬機為“僅主機”模式。 二、server01開機&#xff0c;root用戶登錄&#xff0c;輸入nmtui&#xff0c;進入圖形界面…

賽博威攜手Dify,助力AI在企業的場景化落地

人工智能正以前所未有的速度重塑商業世界。我們經歷了從理論探索到大語言模型&#xff08;LLM&#xff09;的爆發式增長&#xff0c;如今&#xff0c;一個以“AI Agent&#xff08;智能體&#xff09;”為核心的新階段已然來臨。AI Agent代表了人工智能應用的未來形態。它不再被…

嵌入式硬件中三極管推挽電路控制與實現

我們昨天講到了這個電路。 如果 A 電是 PWM 波,那么請問 B 點是不是 PWM 波呢?那么,當 PWM 為高時, B 點的電流是從哪里流過來的?

數據結構——查找(三、樹形查找)

一、二叉排序樹&#xff08;BST&#xff09;1、二叉排序樹的定義構造一棵二叉排序樹的目的并不是排序&#xff0c;而是提高查找、插入和刪除關鍵字的速度二叉排序樹&#xff08;也稱二叉搜索樹&#xff09;或者是一顆空樹&#xff0c;或者是具有以下性質的二叉樹1、若左子樹非空…

八股——Kafka相關

文章目錄1、 消息隊列的作用什么&#xff1f;思&#xff1a;消息隊列是什么?消息隊列的定義消息隊列的工作原理消息隊列的作用消息隊列的常見類型消息隊列的簡單例子2、Kafka 集群的架構是什么樣子的&#xff1f;3、Kafka 消費者組和生產者組是什么&#xff1f;定義與核心作用…

墨者學院SQL手工注入漏洞測試(MySQL數據庫)題目,純手工注入教程

打開練習手工注入的靶場,發現此時為一個登錄頁面,我們先試著登錄看看注入點在不在登錄頁面 使用用戶:or 1=1# 密碼:admin123;嘗試登錄,發現顯示錯誤后直接彈回原頁面,無sql報錯相關語句,這里不存在sql注入點 一:判斷注入點以及猜測是否有注入 此時點擊這里的動態頁面…

[硬件電路-140]:模擬電路 - 信號處理電路 - 鎖定放大器概述、工作原理、常見芯片、管腳定義

一、鎖定放大器概述鎖定放大器&#xff08;Lock-in Amplifier&#xff09;是一種基于相干檢測技術的高靈敏度測量儀器&#xff0c;通過將待測信號與參考信號進行同步處理&#xff0c;從強噪聲中提取微弱信號并精確測量其振幅與相位。其核心優勢包括&#xff1a;信噪比提升&…

下載 | Windows Server 2025官方原版ISO映像!(7月更新、標準版、數據中心版、26100.4652)

? 資源A066_Windows_Server_2025系統映像&#x1f536; Windows Server 2025官方原版ISO映像&#xff0c;7月更新版已放出。提供來自微軟官方每月更新的ISO原版映像&#xff0c;內部包含了標準版和數據中心版&#xff0c;可選擇無GUI界面版或桌面體驗版&#xff0c;滿足不同部…