Vue3中Hooks函數(shù)的使用及封裝思想詳解
一. 什么是hooks函數(shù)
專業(yè)解釋:Vue 3中的Hooks函數(shù)是一種用于在組件中共享可復(fù)用邏輯的方式。
大白話:將單獨(dú)功能的js代碼抽離出來, 加工成公共函數(shù),從而達(dá)到邏輯復(fù)用。
在尤大大開發(fā)Vue3 Composition API 主要考慮了以下兩點(diǎn) :
對(duì)Vue社區(qū)調(diào)研,了解了許多使用Vue的開發(fā)者對(duì)于更好的組件邏輯組織方式的期望。
對(duì)React Hooks和其他前端框架的解決方案進(jìn)行了學(xué)習(xí)和借鑒。
有了composition API 意味著我們就可以自定義封裝hooks,最終的目的都是進(jìn)行復(fù)用,在Vue2中復(fù)用的方式大部分都是采取的mixin,但相比hooks,hooks更清楚復(fù)用的功能來源及功能。
二、如何封裝一個(gè)hooks函數(shù)
例如實(shí)現(xiàn)一個(gè)點(diǎn)擊按鈕獲取body的寬度和高度
<script setup lang="ts">
import { reactive } from "vue";
const data = reactive({
width: 0,
height:0
})
const getViewportSize = () => {
data.width = document.body.clientWidth;
data.height = document.body.clientHeight;
}
</script>
<template>
<button @click="getViewportSize" > 獲取窗口大小 </button>
<div>
<div>寬度 : {{data.width}}</div>
<div>寬度 : {{data.height}}</div>
</div>
</template>抽離邏輯,封裝成hooks函數(shù)
hooks封裝規(guī)范:
1. 新建hooks文件;
2. 函數(shù)名前綴加上use;
3. 合理利用Vue提供的響應(yīng)式函數(shù)及生命周期;
4. 暴露出 變量 和 方法 提供外部需要時(shí)使用;
src/hooks/index.js
import { reactive } from "vue";
export function useVwSize() {
const data = reactive({
width: 0,
height:0
})
const getViewportSize = () => {
data.width = document.body.clientWidth;
data.height = document.body.clientHeight;
}
return {
data,getViewportSize
}
}index.vue 使用hooks
<script setup lang="ts">
import { useVwSize } from "@/hooks";
const { data, getViewportSize } = useVwSize();
</script>
<template>
<button @click="getViewportSize">獲取窗口大小</button>
<div>
<div>寬度 : {{ data.width }}</div>
<div>寬度 : {{ data.height }}</div>
</div>
</template>三、Hooks 常用 Demo
(1)驗(yàn)證碼倒計(jì)時(shí)
/**
* 倒計(jì)時(shí)
* @param {Number} second 倒計(jì)時(shí)秒數(shù)
* @return {Number} count 倒計(jì)時(shí)秒數(shù)
* @return {Function} countDown 倒計(jì)時(shí)函數(shù)
* @example
* const { count, countDown } = useCountDown()
* countDown(60)
* <div>{{ count }}</div>
*/
export function useCountDown() {
const count = ref(0);
const timer = ref(null);
const countDown = (second, ck) => {
if (count.value === 0 && timer.value === null) {
ck();
count.value = second;
timer.value = setInterval(() => {
count.value--;
if (count.value === 0) clearInterval(timer.value);
}, 1000);
}
};
onBeforeMount(() => {
timer.value && clearInterval(timer.value);
});
return {
count,
countDown,
};
}<script setup lang="ts">
import {useCountDown} from "@/hooks";
// 倒計(jì)時(shí)
const { count, countDown } = useCountDown();
const sendCode = () => {
console.log("發(fā)送驗(yàn)證碼");
};
</script>
<button :disabled="count!=0" @click="countDown(5,sendCode)">倒計(jì)時(shí) {{ count || '' }} </button>(2)防抖
/**
* @params {Function} fn 需要防抖的函數(shù) delay 防抖時(shí)間
* @returns {Function} debounce 防抖函數(shù)
* @example
* const { debounce } = useDebounce()
* const fn = () => { console.log('防抖') }
* const debounceFn = debounce(fn, 1000)
* debounceFn()
*
*/
export function useDebounce() {
const debounce = (fn, delay) => {
let timer = null;
return function () {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, arguments);
}, delay);
};
};
return { debounce };
}<script setup lang="ts">
import { useDebounce } from "@/hooks";
// 防抖
const { debounce } = useDebounce()
const fn = () => {
console.log('點(diǎn)擊了哈');
}
const debounceClick = debounce(fn,1000)
<button @click="debounceClick">防抖點(diǎn)擊</button>
</script>(3)節(jié)流
/**
* @params {Function} fn 需要節(jié)流的函數(shù) delay 節(jié)流時(shí)間
* @returns {Function} throttle 節(jié)流函數(shù)
* @example
* const { throttle } = useThrottle()
* const fn = () => { console.log('節(jié)流') }
* const throttleFn = throttle(fn, 1000)
* throttleFn()
*
*
* */
export function useThrottle() {
const throttle = (fn, delay) => {
let timer = null;
return function () {
if (!timer) {
timer = setTimeout(() => {
fn.apply(this, arguments);
timer = null;
}, delay);
}
};
};
return { throttle };
}<script setup lang="ts">
import { useThrottle} from "@/hooks";
const fn = () => {
console.log('點(diǎn)擊了哈');
}
const { throttle } = useThrottle()
const throttleClick = throttle(fn,1000)
</script>
<button @click="throttleClick">節(jié)流點(diǎn)擊</button>以上就是Vue3中Hooks函數(shù)的使用及封裝思想詳解的詳細(xì)內(nèi)容,更多關(guān)于Vue3 Hooks的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Vue.js使用this.$confirm換行顯示提示信息實(shí)例
在編寫Web應(yīng)用時(shí),實(shí)現(xiàn)多行文本顯示通常需要用到HTML標(biāo)簽或JavaScript特定函數(shù),本文介紹了如何使用JavaScript的$createElement函數(shù)來創(chuàng)建多行文本顯示,$createElement可以創(chuàng)建任何HTML標(biāo)簽,使得在JavaScript中控制HTML輸出更加靈活,通過簡單的代碼示例2024-10-10
vue代理如何配置重寫方法(pathRewrite與rewrite)
這篇文章主要介紹了vue代理如何配置重寫方法(pathRewrite與rewrite),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03
解決vue net :ERR_CONNECTION_REFUSED報(bào)錯(cuò)問題
這篇文章主要介紹了解決vue net :ERR_CONNECTION_REFUSED報(bào)錯(cuò)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-08-08
Vue中引入echarts的步驟及折線圖、柱狀圖常見配置項(xiàng)
這篇文章主要介紹了Vue中引入echarts的步驟及折線圖、柱狀圖常見配置項(xiàng),需要的朋友可以參考下2023-11-11
Vue3實(shí)現(xiàn)滾動(dòng)條自動(dòng)滾動(dòng)到底部
在Vue中,通過ref和watch結(jié)合nextTick實(shí)現(xiàn)滾動(dòng)區(qū)域自動(dòng)滾動(dòng)到底部,并添加返回頂部按鈕,適用于動(dòng)態(tài)內(nèi)容場景,供開發(fā)者參考2025-08-08
vue el-table設(shè)置selection選中狀態(tài)實(shí)現(xiàn)方式
在Vue使用Element UI的el-table組件時(shí),toggleRowSelection方法用于切換行的選中狀態(tài),關(guān)鍵代碼通常涉及調(diào)用該方法并傳入行數(shù)據(jù)和選中狀態(tài)(true或false),以實(shí)現(xiàn)行的選中或取消選中2025-12-12

