简介
其实就是简单的通过 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)
- 在本例中,匹配方式为