Vue3中Hooks函數(shù)的使用及封裝思想詳解
一. 什么是hooks函數(shù)
專業(yè)解釋:Vue 3中的Hooks函數(shù)是一種用于在組件中共享可復(fù)用邏輯的方式。
大白話:將單獨(dú)功能的js代碼抽離出來(lái), 加工成公共函數(shù),從而達(dá)到邏輯復(fù)用。
在尤大大開(kāi)發(fā)Vue3 Composition API 主要考慮了以下兩點(diǎn) :
對(duì)Vue社區(qū)調(diào)研,了解了許多使用Vue的開(kāi)發(fā)者對(duì)于更好的組件邏輯組織方式的期望。
對(duì)React Hooks和其他前端框架的解決方案進(jìn)行了學(xué)習(xí)和借鑒。
有了composition API 意味著我們就可以自定義封裝hooks,最終的目的都是進(jìn)行復(fù)用,在Vue2中復(fù)用的方式大部分都是采取的mixin,但相比hooks,hooks更清楚復(fù)用的功能來(lái)源及功能。
二、如何封裝一個(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-drag-resize 拖拽縮放插件的使用(簡(jiǎn)單示例)
本文通過(guò)代碼給大家介紹了Vue-drag-resize 拖拽縮放插件使用簡(jiǎn)單示例,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12vue項(xiàng)目的屏幕自適應(yīng)多個(gè)方案總結(jié)
最近在用VUE寫(xiě)大屏頁(yè)面,遇到屏幕自適應(yīng)問(wèn)題,下面這篇文章主要給大家介紹了關(guān)于vue項(xiàng)目的屏幕自適應(yīng)多個(gè)方案的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06vue面試??贾甤omputed是如何實(shí)現(xiàn)的
對(duì)于每天都在用的計(jì)算屬性(computed),小編猜大家肯定也想窺探其奧妙與原理對(duì)吧,所以這篇文章就來(lái)講講computed是如何實(shí)現(xiàn)的吧,感興趣的小伙伴可以學(xué)習(xí)一下2023-08-08Vue3+Canvas實(shí)現(xiàn)簡(jiǎn)易的貪吃蛇游戲
貪吃蛇作為一個(gè)經(jīng)典的小游戲,是很多人兒時(shí)的記憶,當(dāng)時(shí)的掌機(jī)、諾基亞手機(jī)里面都有它的身影。本文將用Vue3?Canvas來(lái)復(fù)刻一下這款游戲,感興趣的可以了解一下2022-07-07vue2實(shí)現(xiàn)pdf電子簽章問(wèn)題記錄
仿照e簽寶,實(shí)現(xiàn)pdf電子簽章?=>?拿到pdf鏈接,移動(dòng)章的位置,獲取章的坐標(biāo),怎么實(shí)現(xiàn)呢,下面小編給大家介紹vue2實(shí)現(xiàn)pdf電子簽章問(wèn)題記錄,感興趣的朋友一起看看吧2023-12-12某些場(chǎng)景下建議vue query代替pinia原理解析
這篇文章主要為大家介紹了某些場(chǎng)景下建議vue-query代替pinia原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02vue 開(kāi)發(fā)一個(gè)按鈕組件的示例代碼
本篇文章主要介紹了vue 開(kāi)發(fā)一個(gè)按鈕組件的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-03-03解決vue 使用axios.all()方法發(fā)起多個(gè)請(qǐng)求控制臺(tái)報(bào)錯(cuò)的問(wèn)題
這篇文章主要介紹了解決vue 使用axios.all()方法發(fā)起多個(gè)請(qǐng)求控制臺(tái)報(bào)錯(cuò)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-11-11如何在Vue中使用CleaveJS格式化你的輸入內(nèi)容
這篇文章主要介紹了如何在Vue中使用CleaveJS格式化你的輸入內(nèi)容,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-12-12