Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >10个有用的自定义钩子vue.js

10个有用的自定义钩子vue.js

作者头像
前端小智@大迁世界
发布于 2022-04-14 00:30:38
发布于 2022-04-14 00:30:38
42300
代码可运行
举报
文章被收录于专栏:终身学习者终身学习者
运行总次数:0
代码可运行

作者:Sang Nguyen 译者:前端小智 来源:medium 本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试完整考点、资料以及我的系列文章。

Vue 是我使用的第一个 JS 框架。可以说,Vue 是我进入JavaScript世界的第一道门之一。目前,Vue 仍然是一个很棒的框架。随着 composition API 的出现,Vue 只会有更大的发展。在这篇文章中,我将介绍 10 个有用的自定义钩子,让我们的代码更加好看。

useWindowResize

这是一个基本的钩子,因为它被用在很多项目中.

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 的宽度和高度。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
setup() {
    const { width, height } = useWindowResize();
}

useStorage

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 来格式化数据。如果你不想格式化它,你可以删除它。下面是一个如何使用这个钩子的例子。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const [token, setToken] = useStorage('token');
setToken('new token');

useNetworkStatus

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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);
  })
}

调用方式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
useNetworkStatus((status) => { 
    console.log(`Your network status is ${status}`);
}

useCopyToClipboard

剪切板是一个比较常见的功能,我们也可以将它封装成 hook,代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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;
  }
}

使用如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const copyToClipboard = useCopyToClipboard();
copyToClipboard('just copy');

useTheme

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
html[theme="dark"] {
   --color: #FFF;
   --background: #333;
}
html[theme="default"], html {
   --color: #333;
   --background: #FFF;
}

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export const useTheme = (key = '') => {
  return (theme) => {
    document.documentElement.setAttribute(key, theme);
  }
}

使用如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const changeTheme = useTheme();
changeTheme('dark');

usePageVisibility

有时,当客户不专注于我们的网站时,我们需要做一些事情。要做到这一点,我们需要一些东西,让我们知道用户是否在关注。这是一个自定义的钩子。我把它叫做 PageVisibility,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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);
  });
}

用法如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
usePageVisibility((hidden) => {
   console.log(`User is${hidden ? ' not' : ''} focus your site`);
});

useViewport

有时我们会用宽度来检测当前的用户设备,这样我们就可以根据设备来处理对应的内容。这种场景,我们也可以封装成一个 hook,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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
  }
}

使用如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const { device } = useViewport({ mobile: 700, table: 900 });

useOnClickOutside

当 model 框弹出时,我们希望能点击其它区域关闭它,这个可以使用 clickOutSide,这种场景我们也可以封装成钩子,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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);
  });
}

用法如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<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 是一个有用的钩子,支持你这样做。代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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);
  });
}

用法如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
useScrollToBottom(() => { console.log('Scrolled to bottom') })

useTimer

useTimer 的代码比其他钩子要长一些。 useTimer 支持运行一个带有一些选项的定时器,如开始、暂停/恢复、停止。要做到这一点,我们需要使用 setInterval 方法。在这里,我们需要检查定时器的暂停状态。如果定时器没有暂停,我们只需要调用一个回调函数,该函数由用户作为参数传递。为了支持用户了解该定时器当前的暂停状态,除了action useTimer之外,还要给他们一个变量 isPaused,其值为该定时器的暂停状态。代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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
  }
}

用法如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function handleTimer(round) {      
    roundNumber.value = round;    
}
const { 
    start,
    stop,
    pause,
    resume,
    isPaused
} = useTimer(handleTimer);

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

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

原文:https://javascript.plainengli...

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-04-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
10个有用的自定义钩子vue.js
目前,Vue 仍然是一个很不错的框架。随着 composition API 的出现,Vue 会有更大的发展空间。在这篇文章中,我将给大家介绍 10 个有用的自定义钩子,让大家的代码更加优美好看。
PHP开发工程师
2022/04/08
5000
分享 10 个有用的 Vue.js 自定义 Hook
英文 | https://javascript.plainenglish.io/10-useful-custom-hooks-with-vue-js-37f0fd42ce0d
前端达人
2023/10/09
4190
分享 10 个有用的 Vue.js 自定义 Hook
🔔叮~,你有几个系统级交互的React hooks待查收
最近摸鱼时间自己手动实现了几个系统级交互的hooks,由简单到复杂,依次分享给大家!
萌萌哒草头将军
2023/05/26
5220
🔔叮~,你有几个系统级交互的React hooks待查收
深入Vue.js与TypeScript的生命周期
Vue.js是一个渐进式JavaScript框架,用于构建用户界面。而TypeScript是一种由微软开发的开源语言,它是JavaScript的一个超集,可以编译成纯JavaScript。Vue与TypeScript的结合使得开发大型应用变得更加容易和高效。本文将详细探讨Vue.js组件中TypeScript的应用,特别是它的生命周期钩子函数,并通过丰富的示例,为你提供一个实战指南。
K8sCat
2023/11/06
3350
深入Vue.js与TypeScript的生命周期
VueJs中如何自定义hooks(组合式)函数
在Vue当中,一个非常重要的功能就是组件的复用,编写Vue组件,更多的也是在拼装组件,将页面的各个功能进行模块化
itclanCoder
2023/02/26
6870
VueJs中如何自定义hooks(组合式)函数
【前端工具类】002-监听窗口尺寸变化工具类:WindowSizeTracker
訾博ZiBo
2025/01/06
490
vue3 day4
vue3中依然可以使用v2的配置方式来定义生命周期钩子,但是有两个生命周期更改了名字
花花522
2023/03/07
2710
vue3 day4
打包 Composition API、Vue3
到目前为止 Vue 为我们提供了两种开发组件的 API 风格,选项式 API 和组合式 API。组合式 API 可以由我们导入不同的 API 函数来描述组件的逻辑,在 SFC 组件中通常还会在 script 标签显示标注setup来使用。
前端小鑫同学
2022/12/26
6020
深度解析:在vue3中使用自定义Hooks
Hooks技术最早是由React团队的Sophie Alpert和Dan Abramov在2018年提出来的。最初是为了解决React类组件中状态逻辑复用的问题提出来的。在React使用类组件时,为了复用状态逻辑,需要使用高阶组件或者Render Props等方式,这些方式会增加代码的复杂度和维护成本。而Hooks技术是使用特定函数来“钩到”React的state和生命周期等特性的技术。它可以让我们在函数组件中使用state以及其他的React特性,替代传统的类组件或高阶组件等方式。
九仞山
2023/10/14
1.5K0
美丽的公主和它的27个React 自定义 Hook
在上一篇git 原理中我们在「前置知识点」中随口提到了Hook。其中,就有我们比较熟悉的React Hook。
前端柒八九
2023/10/25
7990
美丽的公主和它的27个React 自定义 Hook
亲手打造属于你的 React Hooks
自定义 React Hook 是一个必要的工具,它可以让你为 React 应用程序添加特殊的、独特的功能。
前端修罗场
2022/07/29
10.1K0
Vue 3 生命周期完整指南
最近开源了一个 Vue 组件,还不够完善,欢迎大家来一起完善它,也希望大家能给个 star 支持一下,谢谢各位了。
前端小智@大迁世界
2021/04/01
3.1K0
Vue 3 生命周期完整指南
vue-demi
然后修改package.json,将vue 和@vue/composition-api添加到peerDependencies中
阿超
2023/08/17
3770
vue3知识点:自定义hook函数
答案:请看官方文档: https://v3.cn.vuejs.org/guide/composition-api-introduction.html
刘大猫
2024/10/31
1300
从0到1搭建一款页面自适应组件(Vue.js)
组件将根据屏幕比例及当前浏览器窗口大小,自动进行缩放处理。 建议在组件内使用百分比搭配flex进行布局,以便于在不同的分辨率下得到较为一致的展示效果。 使用前请注意将body的margin设为0,否则会引起计算误差。 fullScreenContainer.vue <template> <div id="full-screen-container" :ref="ref"> <template v-if="ready"> <slot></slot> </template>
Vam的金豆之路
2021/12/01
1.5K0
从0到1搭建一款页面自适应组件(Vue.js)
vue3页面中,同时展示和隐藏相同的组件,后展示的组件事件监听不生效?
场景:在实际开发中,遇到了这样一种场景,vue3页面,两个相同组件,在满足某条件下 v-if 展示第一个组件,满足另一个条件下, v-if 隐藏第一个组件,同时展示第二个组件,比如反馈组件,会通过 window.addEventListener 来监听自定义的反馈弹窗展示和隐藏事件。
蓓蕾心晴
2023/12/01
4370
vue3页面中,同时展示和隐藏相同的组件,后展示的组件事件监听不生效?
Vue3.0 所采用的 Composition Api 与 Vue2.x 使用的 Options Api 有什么不同?
Composition API 可以说是Vue3最大的特点,那么为什么要推出Composition Api,解决了什么问题?
@超人
2021/03/18
1K0
Vue3.0 所采用的 Composition Api 与 Vue2.x 使用的 Options Api 有什么不同?
Vue·动态可响应对象
Vue.observable(object) 让一个对象可响应。Vue 内部会用它来处理 data 函数返回的对象。返回的对象可以直接用于渲染函数和计算属性内,并且会在发生变更时触发相应的更新。也可以作为最小化的跨组件状态存储器,用于简单的场景
数媒派
2022/12/01
6260
vue3 实现 select 下拉选项
本人学生 🐶, 平时在外面没事接点小项目小赚一笔补贴生活费. 之前一直都是使用Vue2.x的版本做项目, 暑假刚刚学习了Vue3想着新项目就直接用Vue3上手. 效果展示 好了, 话不多说先给大佬们看看效果样式: 组件难点 因为下拉框可能会在某些情况下被挡住, 所以这里的下拉框被挂载到了body标签上, 并且下拉框中的选项往往是以<slot>插槽的形式编写, 这里就会困扰到很多小白, 搞不明白怎么样才能在 下拉框 与触发下拉按钮 之间关联响应式事件与数据. 组件的使用 <tk-select selec
玖柒的小窝
2021/10/22
4.9K0
vue3 实现 select 下拉选项
分享5个关于 Vue 的小知识,希望对你有所帮助(三)
大家好,上两篇文章《分享5个关于 Vue 的小知识,希望对你有所帮助(一)》和 《分享5个关于 Vue 的小知识,希望对你有所帮助(二)》,今天我们继续分享5个关于 Vue 的小知识,希望对你有所帮助。
前端达人
2023/08/31
2300
分享5个关于 Vue 的小知识,希望对你有所帮助(三)
相关推荐
10个有用的自定义钩子vue.js
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验