十個有用的自定義Vue鉤子函數(shù)總結(jié)
Vue 是我使用的第一個 JS 框架。可以說,Vue 是我進入JavaScript世界的第一道門之一。目前,Vue 仍然是一個很棒的框架。隨著 composition API 的出現(xiàn),Vue 只會有更大的發(fā)展。在這篇文章中,我將介紹 10 個有用的自定義鉤子,讓我們的代碼更加好看。
useWindowResize
這是一個基本的鉤子,因為它被用在很多項目中.
import { ref, onMounted, onUnmounted } from 'vue'; export function useWindowResize() { const width = ref(window.innerWidth); const height = ref(window.innerHeight); const handleResize = () => { width.value = window.innerWidth; height.value = window.innerHeight; } onMounted(() => { window.addEventListener('resize', handleResize) }); onUnmounted(() => { window.removeEventListener('resize', handleResize) }) return { width, height } }
使用就更簡單了,只需要調(diào)用這個鉤子就可以獲得 window 的寬度和高度。
setup() { const { width, height } = useWindowResize(); }
useStorage
你想通過在 session storage 或 local storage 中存儲數(shù)據(jù)的值來持久化數(shù)據(jù),并將該值綁定到視圖?有了一個簡單的鉤子--useStorage,這將變得非常容易。我們只需要創(chuàng)建一個鉤子來返回從存儲空間得到的數(shù)據(jù),以及一個函數(shù)來在我們想要改變數(shù)據(jù)時將其存儲在存儲空間。下面是我的鉤子。
import { ref } from 'vue'; const getItem = (key, storage) => { let value = storage.getItem(key); if (!value) { return null; } try { return JSON.parse(value) } catch (error) { return value; } } export const useStorage = (key, type = 'session') => { let storage = null; switch (type) { case 'session': storage = sessionStorage; break; case 'local': storage = localStorage; break; default: return null; } const value = ref(getItem(key, storage)); const setItem = (storage) => { return (newValue) => { value.value = newValue; storage.setItem(key, JSON.stringify(newValue)); } } return [ value, setItem(storage) ] }
在我的代碼中,我使用 JSON.parse ** 和 JSON.stringify** 來格式化數(shù)據(jù)。如果你不想格式化它,你可以刪除它。下面是一個如何使用這個鉤子的例子。
const [token, setToken] = useStorage('token'); setToken('new token');
useNetworkStatus
這是一個有用的鉤子,支持檢查網(wǎng)絡(luò)連接的狀態(tài)。為了實現(xiàn)這個鉤子,我們需要為事件 "在線"和 "離線"添加事件監(jiān)聽器。在事件中,我們只是調(diào)用一個回調(diào)函數(shù),參數(shù)為網(wǎng)絡(luò)狀態(tài)。下面是我的代碼。
import { onMounted, onUnmounted } from 'vue'; export const useNetworkStatus = (callback = () => { }) => { const updateOnlineStatus = () => { const status = navigator.onLine ? 'online' : 'offline'; callback(status); } onMounted(() => { window.addEventListener('online', updateOnlineStatus); window.addEventListener('offline', updateOnlineStatus); }); onUnmounted(() => { window.removeEventListener('online', updateOnlineStatus); window.removeEventListener('offline', updateOnlineStatus); }) }
調(diào)用方式:
useNetworkStatus((status) => { console.log(`Your network status is ${status}`); }
useCopyToClipboard
剪切板是一個比較常見的功能,我們也可以將它封裝成 hook,代碼如下所示:
function copyToClipboard(text) { let input = document.createElement('input'); input.setAttribute('value', text); document.body.appendChild(input); input.select(); let result = document.execCommand('copy'); document.body.removeChild(input); return result; } export const useCopyToClipboard = () => { return (text) => { if (typeof text === "string" || typeof text == "number") { return copyToClipboard(text); } return false; } }
使用如下:
const copyToClipboard = useCopyToClipboard(); copyToClipboard('just copy');
useTheme
只是一個簡短的鉤子來改變網(wǎng)站的主題。它可以幫助我們輕松地切換網(wǎng)站的主題,只需用主題名稱調(diào)用這個鉤子。下面是一個我用來定義主題變量的CSS代碼例子。
html[theme="dark"] { --color: #FFF; --background: #333; } html[theme="default"], html { --color: #333; --background: #FFF; }
要改變主題,只需要做一個自定義的鉤子,它返回一個函數(shù)來通過主題名稱改變主題。代碼如下:
export const useTheme = (key = '') => { return (theme) => { document.documentElement.setAttribute(key, theme); } }
使用如下:
const changeTheme = useTheme(); changeTheme('dark');
usePageVisibility
有時,當客戶不專注于我們的網(wǎng)站時,我們需要做一些事情。要做到這一點,我們需要一些東西,讓我們知道用戶是否在關(guān)注。這是一個自定義的鉤子。我把它叫做 PageVisibility,代碼如下:
import { onMounted, onUnmounted } from 'vue'; export const usePageVisibility = (callback = () => { }) => { let hidden, visibilityChange; if (typeof document.hidden !== "undefined") { hidden = "hidden"; visibilityChange = "visibilitychange"; } else if (typeof document.msHidden !== "undefined") { hidden = "msHidden"; visibilityChange = "msvisibilitychange"; } else if (typeof document.webkitHidden !== "undefined") { hidden = "webkitHidden"; visibilityChange = "webkitvisibilitychange"; } const handleVisibilityChange = () => { callback(document[hidden]); } onMounted(() => { document.addEventListener(visibilityChange, handleVisibilityChange, false); }); onUnmounted(() => { document.removeEventListener(visibilityChange, handleVisibilityChange); }); }
用法如下:
usePageVisibility((hidden) => { console.log(`User is${hidden ? ' not' : ''} focus your site`); });
useViewport
有時我們會用寬度來檢測當前的用戶設(shè)備,這樣我們就可以根據(jù)設(shè)備來處理對應(yīng)的內(nèi)容。這種場景,我們也可以封裝成一個 hook,代碼如下:
import { ref, onMounted, onUnmounted } from 'vue'; export const MOBILE = 'MOBILE' export const TABLET = 'TABLET' export const DESKTOP = 'DESKTOP' export const useViewport = (config = {}) => { const { mobile = null, tablet = null } = config; let mobileWidth = mobile ? mobile : 768; let tabletWidth = tablet ? tablet : 922; let device = ref(getDevice(window.innerWidth)); function getDevice(width) { if (width < mobileWidth) { return MOBILE; } else if (width < tabletWidth) { return TABLET; } return DESKTOP; } const handleResize = () => { device.value = getDevice(window.innerWidth); } onMounted(() => { window.addEventListener('resize', handleResize); }); onUnmounted(() => { window.removeEventListener('resize', handleResize); }); return { device } }
使用如下:
const { device } = useViewport({ mobile: 700, table: 900 });
useOnClickOutside
當 model 框彈出時,我們希望能點擊其它區(qū)域關(guān)閉它,這個可以使用 clickOutSide,這種場景我們也可以封裝成鉤子,代碼如下:
import { onMounted, onUnmounted } from 'vue'; export const useOnClickOutside = (ref = null, callback = () => {}) => { function handleClickOutside(event) { if (ref.value && !ref.value.contains(event.target)) { callback() } } onMounted(() => { document.addEventListener('mousedown', handleClickOutside); }) onUnmounted(() => { document.removeEventListener('mousedown', handleClickOutside); }); }
用法如下:
<template> <div ref="container">View</div> </template> <script> import { ref } from 'vue'; export default { setup() { const container = ref(null); useOnClickOutside(container, () => { console.log('Clicked outside'); }) } } </script>
useScrollToBottom
除了分頁列表,加載更多(或懶惰加載)是一種友好的加載數(shù)據(jù)的方式。特別是對于移動設(shè)備,幾乎所有運行在移動設(shè)備上的應(yīng)用程序都在其用戶界面中應(yīng)用了load more。要做到這一點,我們需要檢測用戶滾動到列表底部,并為該事件觸發(fā)一個回調(diào)。
useScrollToBottom 是一個有用的鉤子,支持你這樣做。代碼如下:
import { onMounted, onUnmounted } from 'vue'; export const useScrollToBottom = (callback = () => { }) => { const handleScrolling = () => { if ((window.innerHeight + window.scrollY) >= document.body.scrollHeight) { callback(); } } onMounted(() => { window.addEventListener('scroll', handleScrolling); }); onUnmounted(() => { window.removeEventListener('scroll', handleScrolling); }); }
用法如下:
useScrollToBottom(() => { console.log('Scrolled to bottom') })
useTimer
useTimer 的代碼比其他鉤子要長一些。useTimer 支持運行一個帶有一些選項的定時器,如開始、暫停/恢復(fù)、停止。要做到這一點,我們需要使用 setInterval 方法。在這里,我們需要檢查定時器的暫停狀態(tài)。如果定時器沒有暫停,我們只需要調(diào)用一個回調(diào)函數(shù),該函數(shù)由用戶作為參數(shù)傳遞。為了支持用戶了解該定時器當前的暫停狀態(tài),除了action useTimer之外,還要給他們一個變量 isPaused,其值為該定時器的暫停狀態(tài)。代碼如下:
import { ref, onUnmounted } from 'vue'; export const useTimer = (callback = () => { }, step = 1000) => { let timerVariableId = null; let times = 0; const isPaused = ref(false); const stop = () => { if (timerVariableId) { clearInterval(timerVariableId); timerVariableId = null; resume(); } } const start = () => { stop(); if (!timerVariableId) { times = 0; timerVariableId = setInterval(() => { if (!isPaused.value) { times++; callback(times, step * times); } }, step) } } const pause = () => { isPaused.value = true; } const resume = () => { isPaused.value = false; } onUnmounted(() => { if (timerVariableId) { clearInterval(timerVariableId); } }) return { start, stop, pause, resume, isPaused } }
用法如下:
function handleTimer(round) { roundNumber.value = round; } const { start, stop, pause, resume, isPaused } = useTimer(handleTimer);
以上就是十個有用的自定義Vue鉤子函數(shù)總結(jié)的詳細內(nèi)容,更多關(guān)于Vue鉤子函數(shù)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue實現(xiàn)ajax滾動下拉加載,同時具有l(wèi)oading效果(推薦)
這篇文章主要介紹了vue實現(xiàn)ajax滾動下拉加載,同時具有l(wèi)oading效果的實現(xiàn)代碼,文章包括難點說明,介紹的非常詳細,感興趣的朋友參考下2017-01-01ant design vue嵌套表格及表格內(nèi)部編輯的用法說明
這篇文章主要介紹了ant design vue嵌套表格及表格內(nèi)部編輯的用法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10解決echarts圖表使用v-show控制圖表顯示不全的問題
這篇文章主要介紹了解決echarts圖表使用v-show控制圖表顯示不全的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07解決echarts vue數(shù)據(jù)更新,視圖不更新問題(echarts嵌在vue彈框中)
這篇文章主要介紹了解決echarts vue數(shù)據(jù)更新,視圖不更新問題(echarts嵌在vue彈框中),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07