当前位置:首页 > 系统运维

十个有用的自定义钩子Vue.js

Vue 是用的义钩我使用的第一个 JS 框架。可以说,自定Vue 是用的义钩我进入JavaScript世界的第一道门之一。目前,自定Vue 仍然是用的义钩一个很棒的框架。随着 composition API 的自定出现,Vue 只会有更大的用的义钩发展。在这篇文章中,自定我将介绍 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

}

}

使用就更简单了,只需要调用这个钩子就可以获得 window 的用的义钩宽度和高度。

setup() {

const { width,自定 height } = useWindowResize();

}useStorage

你想通过在 session storage 或 local storage 中存储数据的服务器托管值来持久化数据,并将该值绑定到视图?用的义钩有了一个简单的钩子--useStorage,这将变得非常容易。我们只需要创建一个钩子来返回从存储空间得到的数据,以及一个函数来在我们想要改变数据时将其存储在存储空间。下面是我的钩子。

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** 来格式化数据。如果你不想格式化它,你可以删除它。下面是一个如何使用这个钩子的例子。

const [token, setToken] = useStorage(token);

setToken(new token);

useNetworkStatus

这是一个有用的钩子,支持检查网络连接的状态。为了实现这个钩子,我们需要为事件 "在线"和 "离线"添加事件监听器。在事件中,我们只是调用一个回调函数,参数为网络状态。下面是我的代码。香港云服务器

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);

})

}

调用方式:

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

只是一个简短的钩子来改变网站的主题。它可以帮助我们轻松地切换网站的主题,只需用主题名称调用这个钩子。下面是一个我用来定义主题变量的CSS代码例子。

html[theme="dark"] {

--color: #FFF;

--background: #333;

}

html[theme="default"], html {

--color: #333;

--background: #FFF;

}

要改变主题,只需要做一个自定义的钩子,它返回一个函数来通过主题名称改变主题。代码如下:

export const useTheme = (key = ) => {

return (theme) => {

document.documentElement.setAttribute(key, theme);

}

}

使用如下:

const changeTheme = useTheme();

changeTheme(dark);

usePageVisibility

有时,当客户不专注于我们的网站时,我们需要做一些事情。要做到这一点,我们需要一些东西,让我们知道用户是否在关注。这是一个自定义的钩子。我把它叫做 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

有时我们会用宽度来检测当前的用户设备,这样我们就可以根据设备来处理对应的源码库内容。这种场景,我们也可以封装成一个 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 框弹出时,我们希望能点击其它区域关闭它,这个可以使用 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);

});

}

用法如下:

View

import { ref } from vue;

export default {

setup() {

const container = ref(null);

useOnClickOutside(container, () => {

console.log(Clicked outside);

})

}

}

useScrollToBottom

除了分页列表,加载更多(或懒惰加载)是一种友好的加载数据的方式。特别是对于移动设备,几乎所有运行在移动设备上的应用程序都在其用户界面中应用了load more。要做到这一点,我们需要检测用户滚动到列表底部,并为该事件触发一个回调。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 支持运行一个带有一些选项的定时器,如开始、暂停/恢复、停止。要做到这一点,我们需要使用 setInterval 方法。在这里,我们需要检查定时器的暂停状态。如果定时器没有暂停,我们只需要调用一个回调函数,该函数由用户作为参数传递。为了支持用户了解该定时器当前的暂停状态,除了action useTimer之外,还要给他们一个变量 isPaused,其值为该定时器的暂停状态。代码如下:

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);

本文分享了10个有用的Vue自定义钩子。希望它们对你有帮助。Vue. 是一个很棒的框架,希望你能用它来构建更多很棒的东西。

作者:Sang Nguyen 译者:前端小智 来源:medium 原文:https://javascript.plainenglish.io/10-useful-custom-hook-with-vue-js-37f0fd42ce0d。

分享到:

滇ICP备2023006006号-16