Skip to content
This repository has been archived by the owner on Aug 28, 2024. It is now read-only.

Commit

Permalink
feat: 左侧混合菜单模式 (#34)
Browse files Browse the repository at this point in the history
* perf: Header样式调整

* feat: 新增IconWrapper,El组件

* perf: LayoutHeader,LayoutSider样式调整,适配dark模式

* perf: 固定头部

* wip: 项目配置

* fix: 修复menuSetting属性设置错误

* wip: 项目配置组件

* feat: 项目配置组件,配置主题,界面布局属性

* feat: 增加拷贝,重置,清空缓存方法

* fix: 项目配置项错误问题

* fix: useMenuSearch报错

* perf: 登录表单适配Dark模式

* wip: 锁屏

* wip: 自动锁屏

* fix: 修复 run dev 报错

* feat: 锁屏

* perf: 顶部菜单混合模式logo样式

* wip: 左侧混合菜单模式

* wip: 左侧混合菜单

* feat: 左侧混合菜单模式

* fix: 优化交互体验
  • Loading branch information
hormers authored Dec 27, 2022
1 parent 207f80e commit 461fc48
Show file tree
Hide file tree
Showing 15 changed files with 2,121 additions and 3,759 deletions.
11 changes: 10 additions & 1 deletion apps/admin/src/init-application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ import { localeList } from '@vben/locale/src/config'
import { useRootSetting } from '@/hooks/setting/useRootSetting'
import { useTransitionSetting } from '@/hooks/setting/useTransitionSetting'
import { useHeaderSetting } from '@/hooks/setting/useHeaderSetting'
import { getAllParentPath, getMenus } from '@/router'
import {
getAllParentPath,
getChildrenMenus,
getCurrentParentPath,
getMenus,
getShallowMenus
} from '@/router'
import { useDesign } from '@/hooks/web/useDesign'
import { useAppInject } from '@/hooks/web/use-app-inject'
import { useTabs } from '@/hooks/useTabs'
Expand Down Expand Up @@ -81,6 +87,9 @@ async function initPackages() {
return {
useRootSetting,
getMenus,
getCurrentParentPath,
getShallowMenus,
getChildrenMenus,
getAllParentPath,
useHeaderSetting,
useDesign,
Expand Down
1 change: 1 addition & 0 deletions apps/admin/src/layout/components/logo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ function goHome() {
transition: all 0.2s ease;
height: 48px;
background: transparent;
box-sizing: border-box;
&__title {
font-size: 16px;
Expand Down
6 changes: 6 additions & 0 deletions packages/layouts/bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ export interface ContextOptions {
usePromise: (fn: Function, config?: unknown) => unknown
useDesign: (scope: string) => unknown
getMenus: () => Promise<any>
getCurrentParentPath: (currentPath: string) => Promise<any>
getShallowMenus: () => Promise<any>
getChildrenMenus: (parentPath: string) => Promise<any>
getAllParentPath: (menu, path) => string[]
Logo: VNode | null
}
Expand All @@ -43,6 +46,9 @@ export let context: ContextOptions = {
useTabs: () => undefined,
useDesign: (scope: string) => undefined,
getMenus: async () => ({}),
getCurrentParentPath: async (currentPath: string) => ({}),
getShallowMenus: async () => ({}),
getChildrenMenus: async (parentPath: string) => ({}),
getAllParentPath: (menu, path) => [],
Logo: null,
}
Expand Down
3 changes: 2 additions & 1 deletion packages/layouts/src/components/header.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const {
getShowNotice,
} = useHeaderSetting()
const { getSettingButtonPosition, getShowSettingButton } = useRootSetting()
const { getMenuType } = useMenuSetting()
const { getMenuType, getMenuWidth } = useMenuSetting()
const shadowColor = computed(() =>
isDark.value ? 'rgb(255, 255, 255, 0.09)' : 'rgb(239, 239, 245)',
)
Expand Down Expand Up @@ -64,6 +64,7 @@ const getShowSetting = computed(() => {
getMenuType === MenuTypeEnum.TOP_MENU ||
getMenuType === MenuTypeEnum.MIX
"
:style="{width: getMenuWidth + 'px', maxWidth: getMenuWidth + 'px'}"
/>
<slot name="breadcrumb">
<LayoutBreadcrumb
Expand Down
111 changes: 111 additions & 0 deletions packages/layouts/src/components/menu/mix-menu.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<script lang="ts" setup>
import {ref, h, unref, nextTick, computed} from 'vue'
import { createNamespace, mapTree } from '@vben/utils'
import { VbenIconify } from '@vben/vbencomponents'
import { context } from '../../../bridge'
const { listenerRouteChange } = context
import {
RouteLocationNormalizedLoaded,
RouterLink,
useRouter,
} from 'vue-router'
import { useI18n } from '@vben/locale'
import { REDIRECT_NAME } from '@vben/constants'
const props = defineProps({
list: {
type: Array,
default: ()=>[],
},
})
const { bem } = createNamespace('layout-menu')
// const collapsed = ref(false)
const { t } = useI18n()
const { currentRoute } = useRouter()
const menuRef = ref(null)
const activeKey = ref()
// 定位菜单选择 与 当前路由匹配
const showOption = () => {
nextTick(() => {
if (!menuRef.value) return
menuRef.value.Ref.showOption()
})
}
const menuList = computed(()=>{
return mapTree(props.list, { conversion: (menu) => routerToMenu(menu) })
})
listenerRouteChange((route) => {
if (route.name === REDIRECT_NAME) return
const currentActiveMenu = route.meta?.currentActiveMenu as string
handleMenuChange(route)
if (currentActiveMenu) {
activeKey.value = currentActiveMenu
}
showOption()
})
async function handleMenuChange(route?: RouteLocationNormalizedLoaded) {
const menu = route || unref(currentRoute)
activeKey.value = menu.name
}
// 路由格式化
const routerToMenu = (item: RouteRecordItem) => {
const { name, children, meta, icon } = item
const title = t(meta.title as string)
return {
label: () => {
if (children) {
return title
}
return h(
RouterLink,
{
to: {
name,
},
},
{ default: () => title },
)
},
key: name,
icon: renderIcon(icon),
}
}
function renderIcon(icon: string) {
return () => h(VbenIconify, { icon })
}
</script>

<template>
<div :class="bem()">
<VbenScrollbar :class="bem('scrollbar')">
<VbenMenu
v-model:value="activeKey"
:options="menuList"
:collapsed-width="48"
:collapsed="false"
:collapsed-icon-size="22"
:indent="18"
:root-indent="18"
ref="menuRef"
/>
</VbenScrollbar>
</div>
</template>

<style lang="less" scoped>
.layout-menu {
display: flex;
flex-direction: column;
height: 100%;
&__scrollbar {
flex: 1;
flex-basis: auto;
}
}
</style>
Loading

0 comments on commit 461fc48

Please sign in to comment.