useResize.ts 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. import { onBeforeMount, onMounted, onBeforeUnmount } from "vue"
  2. import { useAppStore } from "@/store/modules/app"
  3. import { useRouteListener } from "@/hooks/useRouteListener"
  4. import { DeviceEnum } from "@/constants/app-key"
  5. /** 参考 Bootstrap 的响应式设计将最大移动端宽度设置为 992 */
  6. const MAX_MOBILE_WIDTH = 992
  7. /** 根据浏览器宽度变化,变换 Layout 布局 */
  8. export default () => {
  9. const appStore = useAppStore()
  10. const { listenerRouteChange } = useRouteListener()
  11. /** 用于判断当前设备是否为移动端 */
  12. const _isMobile = () => {
  13. const rect = document.body.getBoundingClientRect()
  14. return rect.width - 1 < MAX_MOBILE_WIDTH
  15. }
  16. /** 用于处理窗口大小变化事件 */
  17. const _resizeHandler = () => {
  18. if (!document.hidden) {
  19. const isMobile = _isMobile()
  20. appStore.toggleDevice(isMobile ? DeviceEnum.Mobile : DeviceEnum.Desktop)
  21. isMobile && appStore.closeSidebar(true)
  22. }
  23. }
  24. /** 监听路由变化,根据设备类型调整布局 */
  25. listenerRouteChange(() => {
  26. if (appStore.device === DeviceEnum.Mobile && appStore.sidebar.opened) {
  27. appStore.closeSidebar(false)
  28. }
  29. })
  30. /** 在组件挂载前添加窗口大小变化事件监听器 */
  31. onBeforeMount(() => {
  32. window.addEventListener("resize", _resizeHandler)
  33. })
  34. /** 在组件挂载后根据窗口大小判断设备类型并调整布局 */
  35. onMounted(() => {
  36. if (_isMobile()) {
  37. appStore.toggleDevice(DeviceEnum.Mobile)
  38. appStore.closeSidebar(true)
  39. }
  40. })
  41. /** 在组件卸载前移除窗口大小变化事件监听器 */
  42. onBeforeUnmount(() => {
  43. window.removeEventListener("resize", _resizeHandler)
  44. })
  45. }