refactor: useResize hook
This commit is contained in:
parent
4583495aa3
commit
07158c8db4
51
src/layout/hooks/useResize.ts
Normal file
51
src/layout/hooks/useResize.ts
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import { watch, onBeforeMount, onMounted, onBeforeUnmount } from "vue"
|
||||||
|
import { useRoute } from "vue-router"
|
||||||
|
import { useAppStore, DeviceType } from "@/store/modules/app"
|
||||||
|
|
||||||
|
/** 参考 Bootstrap 的响应式设计 WIDTH = 992 */
|
||||||
|
const WIDTH = 992
|
||||||
|
|
||||||
|
/** 根据大小变化重新布局 */
|
||||||
|
export default () => {
|
||||||
|
const route = useRoute()
|
||||||
|
const appStore = useAppStore()
|
||||||
|
|
||||||
|
const _isMobile = () => {
|
||||||
|
const rect = document.body.getBoundingClientRect()
|
||||||
|
return rect.width - 1 < WIDTH
|
||||||
|
}
|
||||||
|
|
||||||
|
const _resizeHandler = () => {
|
||||||
|
if (!document.hidden) {
|
||||||
|
const isMobile = _isMobile()
|
||||||
|
appStore.toggleDevice(isMobile ? DeviceType.Mobile : DeviceType.Desktop)
|
||||||
|
if (isMobile) {
|
||||||
|
appStore.closeSidebar(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => route.name,
|
||||||
|
() => {
|
||||||
|
if (appStore.device === DeviceType.Mobile && appStore.sidebar.opened) {
|
||||||
|
appStore.closeSidebar(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
onBeforeMount(() => {
|
||||||
|
window.addEventListener("resize", _resizeHandler)
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (_isMobile()) {
|
||||||
|
appStore.toggleDevice(DeviceType.Mobile)
|
||||||
|
appStore.closeSidebar(true)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
window.removeEventListener("resize", _resizeHandler)
|
||||||
|
})
|
||||||
|
}
|
@ -1,25 +1,22 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, onBeforeMount, onBeforeUnmount, onMounted, reactive } from "vue"
|
import { computed } from "vue"
|
||||||
import { useAppStore, DeviceType } from "@/store/modules/app"
|
import { useAppStore, DeviceType } from "@/store/modules/app"
|
||||||
import { useSettingsStore } from "@/store/modules/settings"
|
import { useSettingsStore } from "@/store/modules/settings"
|
||||||
import { AppMain, NavigationBar, Settings, Sidebar, TagsView, RightPanel } from "./components"
|
import { AppMain, NavigationBar, Settings, Sidebar, TagsView, RightPanel } from "./components"
|
||||||
import useResize from "./useResize"
|
import useResize from "./hooks/useResize"
|
||||||
|
|
||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
const settingsStore = useSettingsStore()
|
const settingsStore = useSettingsStore()
|
||||||
const { sidebar, device, addEventListenerOnResize, resizeMounted, removeEventListenerResize, watchRouter } = useResize()
|
|
||||||
|
|
||||||
const state = reactive({
|
/** Layout 布局响应式 */
|
||||||
handleClickOutside: () => {
|
useResize()
|
||||||
appStore.closeSidebar(false)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
const classObj = computed(() => {
|
const classObj = computed(() => {
|
||||||
return {
|
return {
|
||||||
hideSidebar: !sidebar.value.opened,
|
hideSidebar: !appStore.sidebar.opened,
|
||||||
openSidebar: sidebar.value.opened,
|
openSidebar: appStore.sidebar.opened,
|
||||||
withoutAnimation: sidebar.value.withoutAnimation,
|
withoutAnimation: appStore.sidebar.withoutAnimation,
|
||||||
mobile: device.value === DeviceType.Mobile
|
mobile: appStore.device === DeviceType.Mobile
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const showSettings = computed(() => {
|
const showSettings = computed(() => {
|
||||||
@ -31,22 +28,14 @@ const showTagsView = computed(() => {
|
|||||||
const fixedHeader = computed(() => {
|
const fixedHeader = computed(() => {
|
||||||
return settingsStore.fixedHeader
|
return settingsStore.fixedHeader
|
||||||
})
|
})
|
||||||
|
const handleClickOutside = () => {
|
||||||
watchRouter()
|
appStore.closeSidebar(false)
|
||||||
onBeforeMount(() => {
|
}
|
||||||
addEventListenerOnResize()
|
|
||||||
})
|
|
||||||
onMounted(() => {
|
|
||||||
resizeMounted()
|
|
||||||
})
|
|
||||||
onBeforeUnmount(() => {
|
|
||||||
removeEventListenerResize()
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div :class="classObj" class="app-wrapper">
|
<div :class="classObj" class="app-wrapper">
|
||||||
<div v-if="classObj.mobile && sidebar.opened" class="drawer-bg" @click="state.handleClickOutside" />
|
<div v-if="classObj.mobile && classObj.openSidebar" class="drawer-bg" @click="handleClickOutside" />
|
||||||
<Sidebar class="sidebar-container" />
|
<Sidebar class="sidebar-container" />
|
||||||
<div :class="{ hasTagsView: showTagsView }" class="main-container">
|
<div :class="{ hasTagsView: showTagsView }" class="main-container">
|
||||||
<div :class="{ 'fixed-header': fixedHeader }">
|
<div :class="{ 'fixed-header': fixedHeader }">
|
||||||
|
@ -1,67 +0,0 @@
|
|||||||
import { computed, watch } from "vue"
|
|
||||||
import { useRoute } from "vue-router"
|
|
||||||
import { useAppStore, DeviceType } from "@/store/modules/app"
|
|
||||||
|
|
||||||
/** 参考 Bootstrap 的响应式设计 WIDTH = 992 */
|
|
||||||
const WIDTH = 992
|
|
||||||
|
|
||||||
/** 根据大小变化重新布局 */
|
|
||||||
export default () => {
|
|
||||||
const route = useRoute()
|
|
||||||
const appStore = useAppStore()
|
|
||||||
|
|
||||||
const device = computed(() => {
|
|
||||||
return appStore.device
|
|
||||||
})
|
|
||||||
|
|
||||||
const sidebar = computed(() => {
|
|
||||||
return appStore.sidebar
|
|
||||||
})
|
|
||||||
|
|
||||||
const watchRouter = watch(
|
|
||||||
() => route.name,
|
|
||||||
() => {
|
|
||||||
if (appStore.device === DeviceType.Mobile && appStore.sidebar.opened) {
|
|
||||||
appStore.closeSidebar(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const isMobile = () => {
|
|
||||||
const rect = document.body.getBoundingClientRect()
|
|
||||||
return rect.width - 1 < WIDTH
|
|
||||||
}
|
|
||||||
|
|
||||||
const resizeMounted = () => {
|
|
||||||
if (isMobile()) {
|
|
||||||
appStore.toggleDevice(DeviceType.Mobile)
|
|
||||||
appStore.closeSidebar(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const resizeHandler = () => {
|
|
||||||
if (!document.hidden) {
|
|
||||||
appStore.toggleDevice(isMobile() ? DeviceType.Mobile : DeviceType.Desktop)
|
|
||||||
if (isMobile()) {
|
|
||||||
appStore.closeSidebar(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const addEventListenerOnResize = () => {
|
|
||||||
window.addEventListener("resize", resizeHandler)
|
|
||||||
}
|
|
||||||
|
|
||||||
const removeEventListenerResize = () => {
|
|
||||||
window.removeEventListener("resize", resizeHandler)
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
device,
|
|
||||||
sidebar,
|
|
||||||
resizeMounted,
|
|
||||||
addEventListenerOnResize,
|
|
||||||
removeEventListenerResize,
|
|
||||||
watchRouter
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user