diff --git a/CHANGELOG.zh_CN.md b/CHANGELOG.zh_CN.md index 3c581a2..605d637 100644 --- a/CHANGELOG.zh_CN.md +++ b/CHANGELOG.zh_CN.md @@ -15,6 +15,7 @@ - 修复 form 表单初始化值为 0 问题 - 修复表格换行问题 - 修复菜单外链不跳转 +- 修复菜单顶部显示问题 ## 2.0.0-rc.17 (2020-01-18) diff --git a/build/config/lessModifyVars.ts b/build/config/lessModifyVars.ts index f2ebcf2..716b930 100644 --- a/build/config/lessModifyVars.ts +++ b/build/config/lessModifyVars.ts @@ -1,7 +1,8 @@ /** * less global variable */ -const primaryColor = '#018ffb'; +const primaryColor = '#0084f4'; +// const primaryColor = '#018ffb'; // const primaryColor = '#0065cc'; //{ const modifyVars = { diff --git a/package.json b/package.json index 1805297..2ee04d8 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "@typescript-eslint/eslint-plugin": "^4.14.0", "@typescript-eslint/parser": "^4.14.0", "@vitejs/plugin-legacy": "^1.2.1", - "@vitejs/plugin-vue": "^1.1.2", + "@vitejs/plugin-vue": "1.1.0", "@vitejs/plugin-vue-jsx": "^1.0.2", "@vue/compiler-sfc": "^3.0.5", "@vuedx/typecheck": "^0.6.0", diff --git a/src/components/Menu/src/BasicMenu.vue b/src/components/Menu/src/BasicMenu.vue index 2def934..0d42922 100644 --- a/src/components/Menu/src/BasicMenu.vue +++ b/src/components/Menu/src/BasicMenu.vue @@ -13,13 +13,7 @@ v-bind="getInlineCollapseOptions" > <template v-for="item in items" :key="item.path"> - <BasicSubMenuItem - :item="item" - :theme="theme" - :level="1" - :showTitle="showTitle" - :isHorizontal="isHorizontal" - /> + <BasicSubMenuItem :item="item" :theme="theme" :isHorizontal="isHorizontal" /> </template> </Menu> </template> @@ -46,6 +40,7 @@ // import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; import { listenerLastChangeTab } from '/@/logics/mitt/tabChange'; + import { getAllParentPath } from '/@/router/helper/menuHelper'; export default defineComponent({ name: 'BasicMenu', @@ -96,16 +91,12 @@ prefixCls, `justify-${align}`, { - [`${prefixCls}--hide-title`]: !unref(showTitle), - [`${prefixCls}--collapsed-show-title`]: props.collapsedShowTitle, [`${prefixCls}__second`]: !props.isHorizontal && unref(getSplit), [`${prefixCls}__sidebar-hor`]: unref(getIsTopMenu), }, ]; }); - const showTitle = computed(() => props.collapsedShowTitle && unref(getCollapsed)); - const getInlineCollapseOptions = computed(() => { const isInline = props.mode === MenuModeEnum.INLINE; @@ -135,7 +126,7 @@ } ); - async function handleMenuClick({ key, keyPath }: { key: string; keyPath: string[] }) { + async function handleMenuClick({ key }: { key: string; keyPath: string[] }) { const { beforeClickFn } = props; if (beforeClickFn && isFunction(beforeClickFn)) { const flag = await beforeClickFn(key); @@ -144,7 +135,9 @@ emit('menuClick', key); isClickGo.value = true; - menuState.openKeys = keyPath; + // const parentPath = await getCurrentParentPath(key); + + // menuState.openKeys = [parentPath]; menuState.selectedKeys = [key]; } @@ -160,7 +153,8 @@ const parentPath = await getCurrentParentPath(path); menuState.selectedKeys = [parentPath]; } else { - menuState.selectedKeys = [path]; + const parentPaths = await getAllParentPath(props.items, path); + menuState.selectedKeys = parentPaths; } } @@ -172,7 +166,6 @@ getMenuClass, handleOpenChange, getOpenKeys, - showTitle, ...toRefs(menuState), }; }, diff --git a/src/components/Menu/src/components/BasicMenuItem.vue b/src/components/Menu/src/components/BasicMenuItem.vue index 005820d..45ae15c 100644 --- a/src/components/Menu/src/components/BasicMenuItem.vue +++ b/src/components/Menu/src/components/BasicMenuItem.vue @@ -1,10 +1,11 @@ <template> - <MenuItem :class="getLevelClass"> + <MenuItem> + <!-- <MenuItem :class="getLevelClass"> --> <MenuItemContent v-bind="$props" :item="item" /> </MenuItem> </template> <script lang="ts"> - import { defineComponent, computed } from 'vue'; + import { defineComponent } from 'vue'; import { Menu } from 'ant-design-vue'; import { useDesign } from '/@/hooks/web/useDesign'; import { itemProps } from '../props'; @@ -14,18 +15,19 @@ name: 'BasicMenuItem', components: { MenuItem: Menu.Item, MenuItemContent }, props: itemProps, - setup(props) { + setup() // props + { const { prefixCls } = useDesign('basic-menu-item'); - const getLevelClass = computed(() => { - const { level, theme } = props; + // const getLevelClass = computed(() => { + // const { level, theme } = props; - const levelCls = [`${prefixCls}__level${level}`, theme]; - return levelCls; - }); + // const levelCls = [`${prefixCls}__level${level}`, theme]; + // return levelCls; + // }); return { prefixCls, - getLevelClass, + // getLevelClass, }; }, }); diff --git a/src/components/Menu/src/components/BasicSubMenuItem.vue b/src/components/Menu/src/components/BasicSubMenuItem.vue index 990460e..1c4353f 100644 --- a/src/components/Menu/src/components/BasicSubMenuItem.vue +++ b/src/components/Menu/src/components/BasicSubMenuItem.vue @@ -2,17 +2,15 @@ <BasicMenuItem v-if="!menuHasChildren(item) && getShowMenu" v-bind="$props" /> <SubMenu v-if="menuHasChildren(item) && getShowMenu" - :class="[`${prefixCls}__level${level}`, theme]" + :class="[theme]" + popupClassName="app-top-menu-popup" > <template #title> <MenuItemContent v-bind="$props" :item="item" /> </template> - <!-- <template #expandIcon="{ key }"> - <ExpandIcon :key="key" /> - </template> --> <template v-for="childrenItem in item.children || []" :key="childrenItem.path"> - <BasicSubMenuItem v-bind="$props" :item="childrenItem" :level="level + 1" /> + <BasicSubMenuItem v-bind="$props" :item="childrenItem" /> </template> </SubMenu> </template> @@ -26,7 +24,6 @@ import BasicMenuItem from './BasicMenuItem.vue'; import MenuItemContent from './MenuItemContent.vue'; - // import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; export default defineComponent({ name: 'BasicSubMenuItem', isSubMenu: true, @@ -35,7 +32,6 @@ SubMenu: Menu.SubMenu, MenuItem: Menu.Item, MenuItemContent, - // ExpandIcon: createAsyncComponent(() => import('./ExpandIcon.vue')), }, props: itemProps, setup(props) { diff --git a/src/components/Menu/src/components/MenuItemContent.vue b/src/components/Menu/src/components/MenuItemContent.vue index 2701989..c3ad86a 100644 --- a/src/components/Menu/src/components/MenuItemContent.vue +++ b/src/components/Menu/src/components/MenuItemContent.vue @@ -1,10 +1,7 @@ <template> <span :class="`${prefixCls}-wrapper`"> <Icon v-if="getIcon" :icon="getIcon" :size="18" :class="`${prefixCls}-wrapper__icon`" /> - <span :class="getNameClass"> - {{ getI18nName }} - <MenuItemTag v-bind="$props" /> - </span> + {{ getI18nName }} </span> </template> <script lang="ts"> @@ -14,25 +11,21 @@ import { useI18n } from '/@/hooks/web/useI18n'; import { useDesign } from '/@/hooks/web/useDesign'; import { contentProps } from '../props'; - import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; const { t } = useI18n(); export default defineComponent({ name: 'MenuItemContent', - components: { Icon, MenuItemTag: createAsyncComponent(() => import('./MenuItemTag.vue')) }, + components: { + Icon, + }, props: contentProps, setup(props) { const { prefixCls } = useDesign('basic-menu-item-content'); const getI18nName = computed(() => t(props.item?.name)); const getIcon = computed(() => props.item?.icon); - const getNameClass = computed(() => { - const { showTitle } = props; - return { [`${prefixCls}--show-title`]: showTitle, [`${prefixCls}__name`]: !showTitle }; - }); return { prefixCls, - getNameClass, getI18nName, getIcon, }; diff --git a/src/components/Menu/src/index.less b/src/components/Menu/src/index.less index c1173a0..88c415c 100644 --- a/src/components/Menu/src/index.less +++ b/src/components/Menu/src/index.less @@ -1,129 +1,12 @@ @basic-menu-prefix-cls: ~'@{namespace}-basic-menu'; -@basic-menu-content-prefix-cls: ~'@{namespace}-basic-menu-item-content'; -@basic-menu-tag-prefix-cls: ~'@{namespace}-basic-menu-item-tag'; -.active-style() { - color: @white; - // background: @primary-color !important; - background: linear-gradient( - 118deg, - rgba(@primary-color, 0.8), - rgba(@primary-color, 1) - ) !important; -} - -.active-menu-style() { - .ant-menu-item-selected, - .ant-menu-submenu-popup.ant-menu-dark .ant-menu-item-selected { - .active-style(); - } +.app-top-menu-popup { + min-width: 150px; } .@{basic-menu-prefix-cls} { width: 100%; - // &__expand-icon { - // position: absolute; - // top: calc(50% - 6px); - // right: 16px; - // width: 10px; - // transform-origin: none; - // opacity: 0.45; - - // span[role='img'] { - // margin-right: 0; - // font-size: 11px; - // } - - // &--collapsed { - // opacity: 0; - // } - // } - - // collapsed show title start - .@{basic-menu-content-prefix-cls}--show-title { - max-width: unset !important; - opacity: 1 !important; - } - - &--hide-title { - &.ant-menu-inline-collapsed > .ant-menu-item, - &.ant-menu-inline-collapsed > .ant-menu-item-group > .ant-menu-item-group-list > .ant-menu-item, - &.ant-menu-inline-collapsed - > .ant-menu-item-group - > .ant-menu-item-group-list - > .ant-menu-submenu - > .ant-menu-submenu-title, - &.ant-menu-inline-collapsed .ant-menu-submenu-title { - padding-right: 16px !important; - padding-left: 16px !important; - } - } - - &--collapsed-show-title.ant-menu-inline-collapsed { - .@{basic-menu-prefix-cls}-item__level1 { - padding: 2px 0; - justify-content: center !important; - - &.ant-menu-item { - display: flex; - align-items: center; - height: 60px !important; - margin-top: 0 !important; - margin-bottom: 0 !important; - line-height: 60px !important; - - > span { - margin-top: 10px; - } - } - } - - & > li[role='menuitem']:not(.ant-menu-submenu), - & > li > .ant-menu-submenu-title { - display: flex; - margin-top: 10px; - font-size: 12px; - flex-direction: column; - align-items: center; - line-height: 24px; - } - - & > li > .ant-menu-submenu-title { - line-height: 24px; - } - .@{basic-menu-content-prefix-cls}-wrapper { - display: flex; - justify-content: center; - align-items: center; - flex-direction: column; - .@{basic-menu-content-prefix-cls}--show-title { - line-height: 30px; - } - } - } - - &.ant-menu-inline-collapsed > .ant-menu-item, - &.ant-menu-inline-collapsed > .ant-menu-item-group > .ant-menu-item-group-list > .ant-menu-item, - &.ant-menu-inline-collapsed - > .ant-menu-item-group - > .ant-menu-item-group-list - > .ant-menu-submenu - > .ant-menu-submenu-title, - &.ant-menu-inline-collapsed .ant-menu-submenu-title { - padding-right: 16px !important; - padding-left: 16px !important; - } - - .@{basic-menu-content-prefix-cls}-wrapper { - width: 100%; - margin-top: 4px; - - &__icon { - vertical-align: text-top; - } - } - .ant-menu-item { transition: unset; } @@ -179,117 +62,6 @@ } } - &.ant-menu-dark:not(.@{basic-menu-prefix-cls}__sidebar-hor):not(.@{basic-menu-prefix-cls}__second) { - // Reset menu item row height - .ant-menu-item:not(.@{basic-menu-prefix-cls}-item__level1), - .ant-menu-sub.ant-menu-inline > .ant-menu-item, - .ant-menu-sub.ant-menu-inline > .ant-menu-submenu > .ant-menu-submenu-title { - height: @app-menu-item-height; - margin: 0; - line-height: @app-menu-item-height; - } - - .ant-menu-item.@{basic-menu-prefix-cls}-item__level1 { - height: @app-menu-item-height; - line-height: @app-menu-item-height; - } - } - - // 层级样式 - &.ant-menu-dark:not(.@{basic-menu-prefix-cls}__sidebar-hor) { - overflow: hidden; - background: @sider-dark-bg-color; - .active-menu-style(); - - .ant-menu-item.ant-menu-item-selected.@{basic-menu-prefix-cls}-menu-item__level1, - .ant-menu-submenu-selected.@{basic-menu-prefix-cls}-menu-item__level1 { - color: @white; - } - - .@{basic-menu-prefix-cls}-item__level1 { - background-color: @sider-dark-bg-color; - - > .ant-menu-sub > li { - background-color: @sider-dark-lighten-1-bg-color; - } - } - - .@{basic-menu-prefix-cls}-item__level2:not(.ant-menu-item-selected), - .ant-menu-sub { - background-color: @sider-dark-lighten-1-bg-color; - } - - .@{basic-menu-prefix-cls}-item__level3:not(.ant-menu-item-selected) { - background-color: @sider-dark-lighten-2-bg-color; - - .ant-menu-item { - background-color: @sider-dark-lighten-2-bg-color; - } - } - - .ant-menu-submenu-title { - display: flex; - height: @app-menu-item-height; - // margin: 0; - align-items: center; - } - - &.ant-menu-inline-collapsed { - .ant-menu-submenu-selected, - .ant-menu-item-selected { - position: relative; - font-weight: 500; - color: @white; - background: @sider-dark-darken-bg-color !important; - - &::before { - position: absolute; - top: 0; - left: 0; - width: 3px; - height: 100%; - background: @primary-color; - content: ''; - } - } - } - } - - &.ant-menu-light:not(.@{basic-menu-prefix-cls}__sidebar-hor) { - // overflow: hidden; - border-right: none; - - .ant-menu-item.ant-menu-item-selected.@{basic-menu-prefix-cls}-menu-item__level1, - .ant-menu-submenu-selected.@{basic-menu-prefix-cls}-menu-item__level1 { - color: @primary-color; - } - } - - &.@{basic-menu-prefix-cls}__second.ant-menu-inline-collapsed:not(.@{basic-menu-prefix-cls}__sidebar-hor) { - // Reset menu item row height - .@{basic-menu-prefix-cls}-item__level1 { - display: flex; - height: @app-menu-item-height * 1.4; - padding: 6px 0 !important; - margin: 0; - font-size: 12px; - line-height: @app-menu-item-height; - align-items: center; - text-align: center; - - > div { - padding: 6px 0 !important; - font-size: 12px; - } - - .@{basic-menu-content-prefix-cls}__name { - display: inline-block; - width: 50%; - overflow: hidden; - } - } - } - .ant-menu-submenu, .ant-menu-submenu-inline { transition: unset; @@ -300,63 +72,3 @@ transition: unset; } } - -.ant-menu-dark { - &.ant-menu-submenu-popup { - > ul { - background: @sider-dark-bg-color; - } - .active-menu-style(); - } -} - -// collapsed show title end -.ant-menu-item, -.ant-menu-submenu-title { - > .@{basic-menu-content-prefix-cls}__name { - width: 100%; - - .@{basic-menu-tag-prefix-cls} { - float: right; - margin-top: @app-menu-item-height / 2; - transform: translate(0%, -50%); - } - } -} - -.@{basic-menu-tag-prefix-cls} { - position: absolute; - top: calc(50% - 8px); - right: 30px; - display: inline-block; - padding: 2px 4px; - margin-right: 4px; - font-size: 12px; - line-height: 14px; - color: #fff; - border-radius: 2px; - - &--dot { - top: calc(50% - 4px); - width: 6px; - height: 6px; - padding: 0; - border-radius: 50%; - } - - &--primary { - background: @primary-color; - } - - &--error { - background: @error-color; - } - - &--success { - background: @success-color; - } - - &--warn { - background: @warning-color; - } -} diff --git a/src/layouts/default/menu/useLayoutMenu.ts b/src/layouts/default/menu/useLayoutMenu.ts index 03615c6..2b32854 100644 --- a/src/layouts/default/menu/useLayoutMenu.ts +++ b/src/layouts/default/menu/useLayoutMenu.ts @@ -72,9 +72,6 @@ export function useSplitMenu(splitType: Ref<MenuSplitTyeEnum>) { // Handle left menu split async function handleSplitLeftMenu(parentPath: string) { - console.log('======================'); - console.log(unref(getSplitLeft)); - console.log('======================'); if (unref(getSplitLeft) || unref(getIsMobile)) return; // spilt mode left diff --git a/src/layouts/page/ParentView.vue b/src/layouts/page/ParentView.vue index b72cf2c..6d05665 100644 --- a/src/layouts/page/ParentView.vue +++ b/src/layouts/page/ParentView.vue @@ -19,9 +19,9 @@ appear > <keep-alive v-if="openCache" :include="getCaches"> - <component :is="Component" :key="route.fullPath" /> + <component :is="Component" v-bind="getKey(Component, route)" /> </keep-alive> - <component v-else :is="Component" :key="route.fullPath" /> + <component v-else :is="Component" v-bind="getKey(Component, route)" /> </transition> </template> </router-view> @@ -34,7 +34,7 @@ import { useMultipleTabSetting } from '/@/hooks/setting/useMultipleTabSetting'; import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting'; - import { useCache } from './useCache'; + import { useCache, getKey } from './useCache'; import { getTransitionName } from './transition'; export default defineComponent({ @@ -56,6 +56,7 @@ openCache, getEnableTransition, getTransitionName, + getKey, }; }, }); diff --git a/src/layouts/page/index.vue b/src/layouts/page/index.vue index 1aef527..39c1af6 100644 --- a/src/layouts/page/index.vue +++ b/src/layouts/page/index.vue @@ -27,9 +27,6 @@ </template> <script lang="ts"> - import type { FunctionalComponent } from 'vue'; - import type { RouteLocation } from 'vue-router'; - import { computed, defineComponent, unref } from 'vue'; import FrameLayout from '/@/layouts/iframe/index.vue'; @@ -37,7 +34,7 @@ import { useRootSetting } from '/@/hooks/setting/useRootSetting'; import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting'; - import { useCache } from './useCache'; + import { useCache, getKey } from './useCache'; import { useMultipleTabSetting } from '/@/hooks/setting/useMultipleTabSetting'; import { getTransitionName } from './transition'; @@ -54,10 +51,6 @@ const openCache = computed(() => unref(getOpenKeepAlive) && unref(getShowMultipleTab)); - function getKey(component: FunctionalComponent & { type: Indexable }, route: RouteLocation) { - return !!component?.type.parentView ? {} : { key: route.fullPath }; - } - return { getTransitionName, openCache, diff --git a/src/layouts/page/useCache.ts b/src/layouts/page/useCache.ts index 71aa62d..8d68ee3 100644 --- a/src/layouts/page/useCache.ts +++ b/src/layouts/page/useCache.ts @@ -1,3 +1,5 @@ +import type { FunctionalComponent } from 'vue'; +import type { RouteLocation } from 'vue-router'; import { computed, ref, unref } from 'vue'; import { useRootSetting } from '/@/hooks/setting/useRootSetting'; import { tryTsxEmit } from '/@/utils/helper/vueHelper'; @@ -6,6 +8,11 @@ import { tabStore, PAGE_LAYOUT_KEY } from '/@/store/modules/tab'; import { useRouter } from 'vue-router'; const ParentLayoutName = 'ParentLayout'; + +export function getKey(component: FunctionalComponent & { type: Indexable }, route: RouteLocation) { + return !!component?.type.parentView ? {} : { key: route.fullPath }; +} + export function useCache(isPage: boolean) { const name = ref(''); const { currentRoute } = useRouter(); diff --git a/yarn.lock b/yarn.lock index 387460b..71e33d2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1768,10 +1768,10 @@ "@vue/babel-plugin-jsx" "^1.0.1" hash-sum "^2.0.0" -"@vitejs/plugin-vue@^1.1.2": - version "1.1.2" - resolved "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-1.1.2.tgz#64d1f0e0739675f5717015ffb4d861c53af8fe60" - integrity sha512-a5ORYuPsiAO4Kb2blA/x63mDiBQBxEJkbjhVtiv5IP/I7fGfpwXPPGHx9LHD4MedpXp8icngJYMKO0hOwahtmQ== +"@vitejs/plugin-vue@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-1.1.0.tgz#8ae0b11388897b07259c9e5198c0e3fb5e4b37d9" + integrity sha512-ExlAt3nb3PB31jV9AgRZSMoGd+aQRU53fc/seghV8/l0JCzaX2mqlgpG8iytWkRxbBPgtAx4TpCPdiVKnTFT/A== "@vue/babel-helper-vue-transform-on@^1.0.2": version "1.0.2"