feat: add useLayoutMode
This commit is contained in:
parent
0a4d896965
commit
02dca40083
@ -1,11 +1,12 @@
|
||||
import { getConfigLayout } from "@/utils/cache/local-storage"
|
||||
import { LayoutModeEnum } from "@/constants/app-key"
|
||||
|
||||
/** 项目配置类型 */
|
||||
export interface LayoutSettings {
|
||||
/** 是否显示 Settings Panel */
|
||||
showSettings: boolean
|
||||
/** 布局模式 */
|
||||
layoutMode: "left" | "top" | "left-top"
|
||||
layoutMode: LayoutModeEnum
|
||||
/** 是否显示标签栏 */
|
||||
showTagsView: boolean
|
||||
/** 是否显示 Logo */
|
||||
@ -34,7 +35,7 @@ export interface LayoutSettings {
|
||||
|
||||
/** 默认配置 */
|
||||
const defaultSettings: LayoutSettings = {
|
||||
layoutMode: "left",
|
||||
layoutMode: LayoutModeEnum.Left,
|
||||
showSettings: true,
|
||||
showTagsView: true,
|
||||
fixedHeader: true,
|
||||
|
@ -4,6 +4,13 @@ export enum DeviceEnum {
|
||||
Desktop
|
||||
}
|
||||
|
||||
/** 布局模式 */
|
||||
export enum LayoutModeEnum {
|
||||
Left = "left",
|
||||
Top = "top",
|
||||
LeftTop = "left-top"
|
||||
}
|
||||
|
||||
/** 侧边栏打开状态常量 */
|
||||
export const SIDEBAR_OPENED = "opened"
|
||||
/** 侧边栏关闭状态常量 */
|
||||
|
16
src/hooks/useLayoutMode.ts
Normal file
16
src/hooks/useLayoutMode.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { computed } from "vue"
|
||||
import { useSettingsStore } from "@/store/modules/settings"
|
||||
import { LayoutModeEnum } from "@/constants/app-key"
|
||||
|
||||
const settingsStore = useSettingsStore()
|
||||
const isLeft = computed(() => settingsStore.layoutMode === LayoutModeEnum.Left)
|
||||
const isTop = computed(() => settingsStore.layoutMode === LayoutModeEnum.Top)
|
||||
const isLeftTop = computed(() => settingsStore.layoutMode === LayoutModeEnum.LeftTop)
|
||||
|
||||
const setLayoutMode = (mode: LayoutModeEnum) => {
|
||||
settingsStore.layoutMode = mode
|
||||
}
|
||||
|
||||
export function useLayoutMode() {
|
||||
return { isLeft, isTop, isLeftTop, setLayoutMode }
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
<script lang="ts" setup>
|
||||
import { storeToRefs } from "pinia"
|
||||
import { useSettingsStore } from "@/store/modules/settings"
|
||||
import { useLayoutMode } from "@/hooks/useLayoutMode"
|
||||
import logo from "@/assets/layouts/logo.png?url"
|
||||
import logoText1 from "@/assets/layouts/logo-text-1.png?url"
|
||||
import logoText2 from "@/assets/layouts/logo-text-2.png?url"
|
||||
@ -13,18 +12,17 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
collapse: true
|
||||
})
|
||||
|
||||
const settingsStore = useSettingsStore()
|
||||
const { layoutMode } = storeToRefs(settingsStore)
|
||||
const { isLeft, isTop } = useLayoutMode()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="layout-logo-container" :class="{ collapse: props.collapse, 'layout-mode-top': layoutMode === 'top' }">
|
||||
<div class="layout-logo-container" :class="{ collapse: props.collapse, 'layout-mode-top': isTop }">
|
||||
<transition name="layout-logo-fade">
|
||||
<router-link v-if="props.collapse" key="collapse" to="/">
|
||||
<img :src="logo" class="layout-logo" />
|
||||
</router-link>
|
||||
<router-link v-else key="expand" to="/">
|
||||
<img :src="layoutMode !== 'left' ? logoText2 : logoText1" class="layout-logo-text" />
|
||||
<img :src="!isLeft ? logoText2 : logoText1" class="layout-logo-text" />
|
||||
</router-link>
|
||||
</transition>
|
||||
</div>
|
||||
|
@ -1,5 +1,4 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from "vue"
|
||||
import { useRouter } from "vue-router"
|
||||
import { storeToRefs } from "pinia"
|
||||
import { useAppStore } from "@/store/modules/app"
|
||||
@ -14,15 +13,15 @@ import ThemeSwitch from "@/components/ThemeSwitch/index.vue"
|
||||
import Screenfull from "@/components/Screenfull/index.vue"
|
||||
import SearchMenu from "@/components/SearchMenu/index.vue"
|
||||
import { useDevice } from "@/hooks/useDevice"
|
||||
import { useLayoutMode } from "@/hooks/useLayoutMode"
|
||||
|
||||
const { isMobile } = useDevice()
|
||||
const { isTop } = useLayoutMode()
|
||||
const router = useRouter()
|
||||
const appStore = useAppStore()
|
||||
const userStore = useUserStore()
|
||||
const settingsStore = useSettingsStore()
|
||||
const { layoutMode, showNotify, showThemeSwitch, showScreenfull, showSearchMenu } = storeToRefs(settingsStore)
|
||||
|
||||
const isTop = computed(() => layoutMode.value === "top")
|
||||
const { showNotify, showThemeSwitch, showScreenfull, showSearchMenu } = storeToRefs(settingsStore)
|
||||
|
||||
/** 切换侧边栏 */
|
||||
const toggleSidebar = () => {
|
||||
|
@ -1,20 +1,14 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from "vue"
|
||||
import { storeToRefs } from "pinia"
|
||||
import { useSettingsStore } from "@/store/modules/settings"
|
||||
import { useLayoutMode } from "@/hooks/useLayoutMode"
|
||||
import { LayoutModeEnum } from "@/constants/app-key"
|
||||
|
||||
const settingsStore = useSettingsStore()
|
||||
const { layoutMode } = storeToRefs(settingsStore)
|
||||
|
||||
const isLeft = computed(() => layoutMode.value === "left")
|
||||
const isTop = computed(() => layoutMode.value === "top")
|
||||
const isLeftTop = computed(() => layoutMode.value === "left-top")
|
||||
const { isLeft, isTop, isLeftTop, setLayoutMode } = useLayoutMode()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="select-layout-mode">
|
||||
<el-tooltip content="左侧模式">
|
||||
<el-container class="layout-mode left" :class="{ active: isLeft }" @click="layoutMode = 'left'">
|
||||
<el-container class="layout-mode left" :class="{ active: isLeft }" @click="setLayoutMode(LayoutModeEnum.Left)">
|
||||
<el-aside />
|
||||
<el-container>
|
||||
<el-header />
|
||||
@ -23,13 +17,17 @@ const isLeftTop = computed(() => layoutMode.value === "left-top")
|
||||
</el-container>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="顶部模式">
|
||||
<el-container class="layout-mode top" :class="{ active: isTop }" @click="layoutMode = 'top'">
|
||||
<el-container class="layout-mode top" :class="{ active: isTop }" @click="setLayoutMode(LayoutModeEnum.Top)">
|
||||
<el-header />
|
||||
<el-main />
|
||||
</el-container>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="混合模式">
|
||||
<el-container class="layout-mode left-top" :class="{ active: isLeftTop }" @click="layoutMode = 'left-top'">
|
||||
<el-container
|
||||
class="layout-mode left-top"
|
||||
:class="{ active: isLeftTop }"
|
||||
@click="setLayoutMode(LayoutModeEnum.LeftTop)"
|
||||
>
|
||||
<el-header />
|
||||
<el-container>
|
||||
<el-aside />
|
||||
|
@ -2,15 +2,16 @@
|
||||
import { watchEffect } from "vue"
|
||||
import { storeToRefs } from "pinia"
|
||||
import { useSettingsStore } from "@/store/modules/settings"
|
||||
import { useLayoutMode } from "@/hooks/useLayoutMode"
|
||||
import { resetConfigLayout } from "@/utils"
|
||||
import SelectLayoutMode from "./SelectLayoutMode.vue"
|
||||
import { Refresh } from "@element-plus/icons-vue"
|
||||
|
||||
const { isLeft } = useLayoutMode()
|
||||
const settingsStore = useSettingsStore()
|
||||
|
||||
/** 使用 storeToRefs 将提取的属性保持其响应性 */
|
||||
const {
|
||||
layoutMode,
|
||||
showTagsView,
|
||||
showLogo,
|
||||
fixedHeader,
|
||||
@ -43,7 +44,7 @@ const switchSettings = {
|
||||
|
||||
/** 非左侧模式时,Header 都是 fixed 布局 */
|
||||
watchEffect(() => {
|
||||
layoutMode.value !== "left" && (fixedHeader.value = true)
|
||||
isLeft.value && (fixedHeader.value = true)
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -55,7 +56,7 @@ watchEffect(() => {
|
||||
<h4>功能配置</h4>
|
||||
<div class="setting-item" v-for="(settingValue, settingName, index) in switchSettings" :key="index">
|
||||
<span class="setting-name">{{ settingName }}</span>
|
||||
<el-switch v-model="settingValue.value" :disabled="layoutMode !== 'left' && settingName === '固定 Header'" />
|
||||
<el-switch v-model="settingValue.value" :disabled="!isLeft && settingName === '固定 Header'" />
|
||||
</div>
|
||||
<el-button type="danger" :icon="Refresh" @click="resetConfigLayout">重 置</el-button>
|
||||
</div>
|
||||
|
@ -1,13 +1,13 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from "vue"
|
||||
import { useRoute } from "vue-router"
|
||||
import { storeToRefs } from "pinia"
|
||||
import { useAppStore } from "@/store/modules/app"
|
||||
import { usePermissionStore } from "@/store/modules/permission"
|
||||
import { useSettingsStore } from "@/store/modules/settings"
|
||||
import SidebarItem from "./SidebarItem.vue"
|
||||
import Logo from "../Logo/index.vue"
|
||||
import { useDevice } from "@/hooks/useDevice"
|
||||
import { useLayoutMode } from "@/hooks/useLayoutMode"
|
||||
import { getCssVariableValue } from "@/utils"
|
||||
|
||||
const v3SidebarMenuBgColor = getCssVariableValue("--v3-sidebar-menu-bg-color")
|
||||
@ -15,11 +15,11 @@ const v3SidebarMenuTextColor = getCssVariableValue("--v3-sidebar-menu-text-color
|
||||
const v3SidebarMenuActiveTextColor = getCssVariableValue("--v3-sidebar-menu-active-text-color")
|
||||
|
||||
const { isMobile } = useDevice()
|
||||
const { isLeft, isTop } = useLayoutMode()
|
||||
const route = useRoute()
|
||||
const appStore = useAppStore()
|
||||
const permissionStore = usePermissionStore()
|
||||
const settingsStore = useSettingsStore()
|
||||
const { layoutMode, showLogo } = storeToRefs(settingsStore)
|
||||
|
||||
const activeMenu = computed(() => {
|
||||
const {
|
||||
@ -30,24 +30,22 @@ const activeMenu = computed(() => {
|
||||
})
|
||||
const noHiddenRoutes = computed(() => permissionStore.routes.filter((item) => !item.meta?.hidden))
|
||||
const isCollapse = computed(() => !appStore.sidebar.opened)
|
||||
const isLeft = computed(() => layoutMode.value === "left")
|
||||
const isTop = computed(() => layoutMode.value === "top")
|
||||
const isLogo = computed(() => isLeft.value && showLogo.value)
|
||||
const isLogo = computed(() => isLeft.value && settingsStore.showLogo)
|
||||
const backgroundColor = computed(() => (isLeft.value ? v3SidebarMenuBgColor : undefined))
|
||||
const textColor = computed(() => (isLeft.value ? v3SidebarMenuTextColor : undefined))
|
||||
const activeTextColor = computed(() => (isLeft.value ? v3SidebarMenuActiveTextColor : undefined))
|
||||
const sidebarMenuItemHeight = computed(() => {
|
||||
return layoutMode.value !== "top" ? "var(--v3-sidebar-menu-item-height)" : "var(--v3-navigationbar-height)"
|
||||
return !isTop.value ? "var(--v3-sidebar-menu-item-height)" : "var(--v3-navigationbar-height)"
|
||||
})
|
||||
const sidebarMenuHoverBgColor = computed(() => {
|
||||
return layoutMode.value !== "top" ? "var(--v3-sidebar-menu-hover-bg-color)" : "transparent"
|
||||
return !isTop.value ? "var(--v3-sidebar-menu-hover-bg-color)" : "transparent"
|
||||
})
|
||||
const tipLineWidth = computed(() => {
|
||||
return layoutMode.value !== "top" ? "2px" : "0px"
|
||||
return !isTop.value ? "2px" : "0px"
|
||||
})
|
||||
// 当为顶部模式时隐藏垂直滚动条
|
||||
const hiddenScrollbarVerticalBar = computed(() => {
|
||||
return layoutMode.value === "top" ? "none" : "block"
|
||||
return isTop.value ? "none" : "block"
|
||||
})
|
||||
</script>
|
||||
|
||||
|
@ -5,6 +5,7 @@ import { useSettingsStore } from "@/store/modules/settings"
|
||||
import useResize from "./hooks/useResize"
|
||||
import { useWatermark } from "@/hooks/useWatermark"
|
||||
import { useDevice } from "@/hooks/useDevice"
|
||||
import { useLayoutMode } from "@/hooks/useLayoutMode"
|
||||
import LeftMode from "./LeftMode.vue"
|
||||
import TopMode from "./TopMode.vue"
|
||||
import LeftTopMode from "./LeftTopMode.vue"
|
||||
@ -16,9 +17,9 @@ useResize()
|
||||
|
||||
const { setWatermark, clearWatermark } = useWatermark()
|
||||
const { isMobile } = useDevice()
|
||||
const { isLeft, isTop, isLeftTop } = useLayoutMode()
|
||||
const settingsStore = useSettingsStore()
|
||||
const { showSettings, layoutMode, showTagsView, showWatermark, showGreyMode, showColorWeakness } =
|
||||
storeToRefs(settingsStore)
|
||||
const { showSettings, showTagsView, showWatermark, showGreyMode, showColorWeakness } = storeToRefs(settingsStore)
|
||||
|
||||
const classes = computed(() => {
|
||||
return {
|
||||
@ -46,11 +47,11 @@ watchEffect(() => {
|
||||
<template>
|
||||
<div :class="classes">
|
||||
<!-- 左侧模式 -->
|
||||
<LeftMode v-if="layoutMode === 'left' || isMobile" />
|
||||
<LeftMode v-if="isLeft || isMobile" />
|
||||
<!-- 顶部模式 -->
|
||||
<TopMode v-else-if="layoutMode === 'top'" />
|
||||
<TopMode v-else-if="isTop" />
|
||||
<!-- 混合模式 -->
|
||||
<LeftTopMode v-else-if="layoutMode === 'left-top'" />
|
||||
<LeftTopMode v-else-if="isLeftTop" />
|
||||
<!-- 右侧设置面板 -->
|
||||
<RightPanel v-if="showSettings">
|
||||
<Settings />
|
||||
|
Loading…
x
Reference in New Issue
Block a user