mirror of
https://github.com/continew-org/continew-admin-ui.git
synced 2026-01-17 16:57:16 +08:00
chore(layout): 更新 LayoutTop 组件,优化菜单样式和交互逻辑 (同步Gi-Demo)
This commit is contained in:
@@ -1,8 +1,13 @@
|
||||
<template>
|
||||
<div class="layout-top">
|
||||
<a-row align="center" class="layout-top__header">
|
||||
<a-row align="center" class="layout-top__header" :style="getMenuStyle">
|
||||
<Logo></Logo>
|
||||
<Menu class="layout-top__menu"></Menu>
|
||||
<a-menu
|
||||
class="layout-top__menu" mode="horizontal" :theme="menuTheme" :menu-trigger-props="menuTriggerProps"
|
||||
:selected-keys="selectedKeys" @menu-item-click="handleMenuItemClick"
|
||||
>
|
||||
<MenuItem v-for="(item, index) in menuList" :key="item.path + index" :item="item" />
|
||||
</a-menu>
|
||||
<HeaderRightBar></HeaderRightBar>
|
||||
</a-row>
|
||||
<Tabs v-if="appStore.tab"></Tabs>
|
||||
@@ -14,29 +19,32 @@
|
||||
import HeaderRightBar from './components/HeaderRightBar/index.vue'
|
||||
import Logo from './components/Logo.vue'
|
||||
import Main from './components/Main.vue'
|
||||
import Menu from './components/Menu/index.vue'
|
||||
import MenuItem from './components/Menu/MenuItem.vue'
|
||||
|
||||
import Tabs from './components/Tabs/index.vue'
|
||||
import { useMenu } from './hooks/useMenus'
|
||||
import { useAppStore } from '@/stores'
|
||||
|
||||
defineOptions({ name: 'LayoutTop' })
|
||||
|
||||
const appStore = useAppStore()
|
||||
const { menuTheme, menuList, menuTriggerProps, handleMenuItemClick, selectedKeys, getMenuStyle } = useMenu()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.layout-top {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
&__header {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
background-color: var(--color-bg-1);
|
||||
width: 100%;
|
||||
padding-right: 16px;
|
||||
overflow: hidden;
|
||||
background-color: var(--color-bg-1);
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
&__menu {
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import type { CSSProperties } from 'vue'
|
||||
import type { RouteRecordRaw } from 'vue-router'
|
||||
import { computed } from 'vue'
|
||||
import { eachTree } from 'xe-utils'
|
||||
import { useRouteStore } from '@/stores'
|
||||
import { useDevice, useRouteListener } from '@/hooks'
|
||||
import { useAppStore, useRouteStore } from '@/stores'
|
||||
import { filterTree } from '@/utils'
|
||||
import { isExternal } from '@/utils/validate'
|
||||
|
||||
/**
|
||||
* 菜单管理 Hooks
|
||||
@@ -11,8 +14,30 @@ import { filterTree } from '@/utils'
|
||||
* @returns {object} 包含处理后菜单列表的响应式对象
|
||||
*/
|
||||
export function useMenu() {
|
||||
const router = useRouter()
|
||||
// 路由存储实例,用于获取原始路由配置
|
||||
const routeStore = useRouteStore()
|
||||
const appStore = useAppStore()
|
||||
const { listenerRouteChange } = useRouteListener()
|
||||
const { isDesktop } = useDevice()
|
||||
|
||||
// 是否折叠菜单
|
||||
const collapsed = computed(() =>
|
||||
!isDesktop.value ? false : appStore.menuCollapse,
|
||||
)
|
||||
|
||||
// 菜单触发器配置
|
||||
const menuTriggerProps = {
|
||||
animationName: 'slide-dynamic-origin',
|
||||
}
|
||||
|
||||
// 菜单主题
|
||||
const menuTheme = computed(() => appStore.menuDark ? 'dark' : 'light')
|
||||
|
||||
// 获取菜单样式
|
||||
const getMenuStyle = computed(() => {
|
||||
return { backgroundColor: menuTheme.value === 'dark' ? 'var(--color-menu-dark-bg)' : 'var(--color-menu-light-bg)' } as CSSProperties
|
||||
})
|
||||
|
||||
/**
|
||||
* 处理后的菜单列表
|
||||
@@ -36,7 +61,6 @@ export function useMenu() {
|
||||
if (i?.children?.length === 1 && i?.meta?.alwaysShow !== true) {
|
||||
if (i.meta) {
|
||||
i.meta.title = i.meta?.title || i.children?.[0]?.meta?.title
|
||||
i.meta.svgIcon = i.meta?.svgIcon || i.children?.[0]?.meta?.svgIcon
|
||||
i.meta.icon = i.meta?.icon || i.children?.[0]?.meta?.icon
|
||||
}
|
||||
i.path = i.children?.[0]?.path
|
||||
@@ -46,7 +70,32 @@ export function useMenu() {
|
||||
return showMenuList
|
||||
})
|
||||
|
||||
const selectedKeys = ref<string[]>([])
|
||||
|
||||
function handleMenuItemClick(key: string) {
|
||||
if (isExternal(key)) {
|
||||
window.open(key)
|
||||
return
|
||||
}
|
||||
selectedKeys.value = [key]
|
||||
router.push({ path: key })
|
||||
}
|
||||
|
||||
listenerRouteChange(({ to }) => {
|
||||
if (to?.meta?.activeMenu) {
|
||||
selectedKeys.value = [to.meta.activeMenu]
|
||||
return
|
||||
}
|
||||
selectedKeys.value = [to.path]
|
||||
})
|
||||
|
||||
return {
|
||||
menuTheme,
|
||||
getMenuStyle,
|
||||
menuList,
|
||||
menuTriggerProps,
|
||||
selectedKeys,
|
||||
collapsed,
|
||||
handleMenuItemClick,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user