Vue3使用hook封装媒体查询和事件监听,使Vue的开发更加丝滑🚀🚀🚀

简介: Vue3使用hook封装媒体查询和事件监听,使Vue的开发更加丝滑🚀🚀🚀

js中媒体查询的主要方法是使用window对象下的matchMedia对象,查询语句和CSS媒体查询一样。

封装媒体查询

首先我们先看监听系统主题色的例子

  • 首先创建媒体查询对象
  • 根据查询结果设置对应的值
  • 然后建立监听事件,并且在退出时取消监听
export const useTheme = () => {
  // 首先创建媒体查询对象
  const themeMedia = matchMedia("(prefers-color-scheme: light)")
  // 根据查询结果设置对应的值
  const theme = ref(themeMedia.matches ? 'light' : 'dark')
  const onChange = (e: MediaQueryListEvent) => theme.value = e.matches ? 'light' : 'dark'
  watchEffect((onCleanup) => {
    //  然后建立监听事件
    themeMedia.addEventListener('change', onChange)
    // 并且在退出时取消监听
    onCleanup(() => themeMedia.removeEventListener('change', onChange))
  })
  return theme;
}

我们测试下

const theme = useTheme()
watchEffect(() => console.log(theme.value, 'theme'))

如果我们其他查询查询,我们需要重新设置新的值,所以,接下来我们封装一个更通用的媒体查询hook,如下,

export const useMatchMedia = (query: string) => {
  const themeMedia = matchMedia(query)
  const match = ref(themeMedia.matches)
  const onChange = (e: MediaQueryListEvent) => match.value = e.matches
  watchEffect((onCleanup) => {
    themeMedia.addEventListener('change', onChange)
    onCleanup(() => themeMedia.removeEventListener('change', onChange))
  })
  return match
}

这个例子里,我们不再对特定的媒体查询值做处理,同时,我们将查询语句作为动态变量,将结果处理交给开发者。

我们使用通用的hook重写监听系统主题色的hook,如下:

export const useTheme = () => {
  const theme = useMatchMedia("(prefers-color-scheme: light)")
  const theme = ref(themeMedia.matches ? 'light' : 'dark')
  return theme  ? 'light' : 'dark'
}

是不是这样更简洁了。

封装事件监听

接下来,我们再看第二个简单的例子,监听网络状态。

监听网络状态,主要通过监听navigator.onLine的变化,值的变化可以通过addEventListener方法,

有了封装媒体查询的例子,我们首先会想到封装事件监听的值的变化可以通过addEventListener方法,成为一个通用的钩子函数。如下:

export const useEventListener = <K extends keyof WindowEventMap>(
  target: K,
  listener: (ev: WindowEventMap[K]) => any
) => {
  watchEffect((onCleanup) => {
    addEventListener(target, listener)
    onCleanup(() => removeEventListener(target, listener))
  })
}

此时,我们就可以这样封装监听网络状态的hook了

export const useNetWork = () => {
  const isOnLine = ref(navigator.onLine)
  const setOnLine = () => isOnLine.value = true
  const setOffLine = () => isOnLine.value = false
  useEventListener('online', setOnLine)
  useEventListener('offline', setOffLine)
  return isOnLine
}

我们测试下

const isOnLine = useNetWork()
watchEffect(() => console.log(isOnLine.value, 'isOnLine'))
<h1 v-if="isOnLine">onLine</h1>
<h1 v-else>offLine</h1>

接下来我们测试下其他的监听事件,比如监听scroll事件。

useEventListener('scroll', () => console.log('scroll'))

功能是正常的,但是顺理成章,我们还需要写一个防抖函数

export const debounce = (
  fn: (...args: any[]) => void,
  delay: number
) => {
  let timer: NodeJS.Timeout
  return  (...args: any[]) => {
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      fn.apply(this, args)
    }, delay)
  }
}
useEventListener('scroll', debounce(() => console.log('scroll'), 200))


好了今天的分享到这了,如果文章中有纰漏的地方欢迎指正,我及时修改,感谢你的阅读

觉得文章还不错点个赞再走吧,十分感谢

相关文章
|
4天前
|
JavaScript
理解 Vue 的 setup 应用程序钩子
【10月更文挑战第3天】`setup` 函数是 Vue 3 中的新组件选项,在组件创建前调用,作为初始化逻辑的入口。它接收 `props` 和 `context` 两个参数,内部定义的变量和函数需通过 `return` 暴露给模板。`props` 包含父组件传入的属性,`context` 包含组件上下文信息。`setup` 可替代 `beforeCreate` 和 `created` 钩子,并提供类似 `data`、`computed` 和 `methods` 的功能,支持逻辑复用和 TypeScript 类型定义。
20 11
|
6天前
|
JavaScript
vue尚品汇商城项目-day07【vue插件-50.(了解)表单校验插件】
vue尚品汇商城项目-day07【vue插件-50.(了解)表单校验插件】
16 4
|
6天前
|
JavaScript
vue尚品汇商城项目-day07【51.路由懒加载】
vue尚品汇商城项目-day07【51.路由懒加载】
17 4
|
6天前
|
JavaScript
vue尚品汇商城项目-day07【vue插件-54.(了解)生成二维码插件】
vue尚品汇商城项目-day07【vue插件-54.(了解)生成二维码插件】
16 2
|
9天前
|
JavaScript
vue组件中的插槽
本文介绍了Vue中组件的插槽使用,包括单个插槽和多个具名插槽的定义及在父组件中的使用方法,展示了如何通过插槽将父组件的内容插入到子组件的指定位置。
|
7天前
|
JavaScript
vue消息订阅与发布
vue消息订阅与发布
|
7天前
|
JavaScript 前端开发 IDE
Vue学习笔记5:用Vue的事件监听 实现数据更新的实时视图显示
Vue学习笔记5:用Vue的事件监听 实现数据更新的实时视图显示
|
7天前
|
JavaScript 前端开发 API
Vue学习笔记4:用reactive() 实现数据更新的实时视图显示
Vue学习笔记4:用reactive() 实现数据更新的实时视图显示
|
7天前
|
JavaScript 前端开发
Vue学习笔记8:解决Vue学习笔记7中用v-for指令渲染列表遇到两个问题
Vue学习笔记8:解决Vue学习笔记7中用v-for指令渲染列表遇到两个问题
|
7天前
|
JavaScript 前端开发 API
Vue学习笔记7:使用v-for指令渲染列表
Vue学习笔记7:使用v-for指令渲染列表
下一篇
无影云桌面