作者:Sang Nguyen
译者:前端小智
来源:medium

有梦想,有干货,微信搜索 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。

本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试完整考点、资料以及我的系列文章。

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

用法如下:

<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

除了分页列表,加载更多(或懒惰加载)是一种友好的加载数据的方式。特别是对于移动设备,几乎所有运行在移动设备上的应用程序都在其用户界面中应用了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. 是一个很棒的框架,希望你能用它来构建更多很棒的东西。


代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。

原文:https://javascript.plainenglish.io/10-useful-custom-hook-with-vue-js-37f0fd42ce0d

交流

有梦想,有干货,微信搜索 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。

本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试完整考点、资料以及我的系列文章。

10个有用的自定义钩子vue.js相关推荐

  1. Flask Vue.js全栈开发

    Flask Vue.js全栈开发的 最新完整代码 及使用方式 本系列的最新代码及使用方式将持续更新到: http://www.madmalls.com/blog/post/latest-code/ 1 ...

  2. (私人收藏)Vue.js手册及教程

    (私人收藏)Vue.js手册及教程 https://pan.baidu.com/s/1XG1XdbbdBQm7cyhQKUIrRQ 5lrt Vue.js手册及教程Vue.js 教程Vue.js 安装 ...

  3. Vue.js 系列教程 3:Vue-cli,生命周期钩子

    原文:intro-to-vue-3-vue-cli-lifecycle-hooks 译者:nzbin 这是 JavaScript 框架 Vue.js 五篇教程的第三部分.在这一部分,我们将学习 Vue ...

  4. js 返回上一页面_构建大型 Vue.js 项目的10条建议

    下面是我在开发大型 Vue 项目时的最佳实践.这些技巧将帮助你开发更高效.更易于维护和共享的代码. 今年做自由职业的时候,我有机会开发了一些大型 Vue 应用程序.我所说的这些项目,Vuex stor ...

  5. vue.js 四(指令和自定义指令)

    官方的指令说明已经很简单了,这里再写一遍,也是自己加深一下印象 v-text 就是写入单纯的文本,可以忽略这个指令直接双花括号代替 <span v-text="msg"> ...

  6. Vue.js 学习笔记 十一 自定义指令

    之前看到过v-bind,v-on等指令,Vue还可以自定义指<div id="divApp"        <div v-focus></div> & ...

  7. Vue.js 学习笔记 十 自定义按键事件

    <div id="divApp"><!--任何键盘动作都会触发--><input type="text" v-on:keyup=& ...

  8. Vue.js中的自定义指令directives

    除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令.自定义指令,需要声明钩子函数.注册自定义指令也分为注册全局自定义指令和注册局部自定义指令.两者用法相同, ...

  9. 10.Vue.js前端框架:过渡

    1.过渡的作用 Vue.js 内置了一套过渡系统,该系统是 Vue.js 为 DOM 动画效果提供的一个特性.在插入.更新或者移除 DOM 时可以触发 CSS 过渡和动画,从而产生过渡效果. 2.单元 ...

  10. 10个技巧!实现Vue.js极致性能优化(建议收藏)

    导语 | Vue是一套用于构建用户界面的渐进式的JavaScript框架.它具有体积小,更高的运行效率,双向数据绑定,生态丰富.学习成本低等优点,所以Vue也被广泛用在移动端跨平台框架上.接下来,我将 ...

最新文章

  1. 用于初始化Xilinx 存储 IP核的COE文件格式
  2. java arraylist 实现原理_Java进阶--深入理解ArrayList实现原理
  3. python在哪里写程序和运行-Python程序的编写和运行方式有两种()
  4. USACO Training Section 1.2 双重回文数 Dual Palindrom
  5. js中select下拉框重置_如何利用CSS3制作炫酷的下拉框
  6. 原创 | 万万没想到,JVM内存结构的面试题可以问的这么难?
  7. linux -- 三剑客 |grep - sed -awk
  8. EasyRecovery的工具栏介绍
  9. 数组、集合、链表实现学生成绩管理系统
  10. sublime php测试,sublime phpcs代码检查配置
  11. dota2 自定义官方服务器,起源2引擎DOTA2重生设置 自定义房间创建
  12. 如何成功对接APP项目资源
  13. springBoot-Quartz 定时任务
  14. layer的move要怎么用
  15. vijos 1443 月亮之眼
  16. html lang=zh-cn解决Mac版Firefox中文字体显示问题
  17. 2021全球程序员收入报告出炉
  18. MATLAB 设置纵轴显示范围、科学记数法
  19. 罗旭对话王海滨:制造业正在向数字化要效益
  20. 第一周-3.2道路升级

热门文章

  1. matlab中仿真图中有格子,关于matlab做图的一些东西(—)
  2. W02:小组策划(森林冰火人)
  3. 数组(arr)的常用方法
  4. Coremail带你一图读懂政务云建设-国产化-信心之选
  5. [NLP] LLM---<训练中文LLama2(四)方式一>对LLama2进行SFT微调
  6. CSS——CSS复合选择器(重中之重 ☆)
  7. RabbitMQ 3.5.1的安装(centos7.x安装rabbitmq 3.5.1,RPM包安装方式)
  8. Python分析51job岗位、多元回归建模预测薪资
  9. uniapp上传图片、视频
  10. 内卷的千亿“客户S化“市场,谁能开辟新天地?