Vue 3 实现监听窗口尺寸和系统亮暗色主题

1,954 阅读1分钟

简介

其实就是简单的通过 JavaScript 监听媒体查询变化,挂载到 Vue 的生命周期之中。

工程实践

上下文:

  • Vue 3 setup sugar with typescript
  • 使用 Pinia 做为状态管理, useStore() 即为读取 Pinia 状态

App.vue 文件中:

function setDeviceClass() {
  // 根据 window.innerWidth 设置 DeviceClass
  useStore().deviceClass = window.innerWidth >= 700 ? Device.desktop : Device.phone
}

function setThemeClassWithSystem() {
  // 根据 window.matchMedia 设置 setThemeClass
  useStore().systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches ? Theme.dark : Theme.light;
}

onMounted(() => {
  // 窗口宽度监听功能
  setDeviceClass();
  window.addEventListener('resize', () => {
    setDeviceClass();
  })

  // 系统主题查询
  setThemeClassWithSystem()
  // 监听系统主题是否发生变化
  window.matchMedia("(prefers-color-scheme: dark)")
    .addEventListener('change', () => {
      setThemeClassWithSystem();
    })
})

知识点备忘

  • 在 JavaScript 中实现媒体查询的 window.matchMedia(mediaQueryString) 方法,参见 🔗MDN: Window.matchMedia()
    • 在本例中,匹配方式为 window.matchMedia("(prefers-color-scheme: dark)")
    • 监听媒体查询是否变化,可对 window.matchMedia() 的返回对象添加事件监听,请参见👆🏻上述链接原文,在本例中使用 window.matchMedia(mediaQueryString).addEventListener(eventName, handlerFunction)