feat(plugin-layout): 菜单支持配置额外的匹配规则

This commit is contained in:
wanchun 2022-01-05 16:38:20 +08:00
parent ab949fb6a8
commit c998c39559
6 changed files with 62 additions and 17 deletions

View File

@ -56,21 +56,21 @@ export default {
} }
</config> </config>
``` ```
如果只是不想展示`side`,则: 如果只是不想展示`sidebar`,则:
``` ```
<config lang="json"> <config lang="json">
{ {
"layout": { "layout": {
"side": false "sidebar": false
} }
} }
</config> </config>
``` ```
`layout`的可选配置有: `layout`的可选配置有:
- **side** 左侧区域 - **sidebar** 左侧区域从v4.0.0开始,之前名称叫`side`
- **top** 头部区域 - **header** 头部区域,从v4.0.0开始,之前名称叫`top`
- **logo**logo和标题区域。 - **logo**logo和标题区域。
@ -182,6 +182,15 @@ export default {
- **name**:菜单的名称。通过匹配 `name` 和路由元信息 [meta](../../../guide/route.md#扩展路由元信息) 中的 `name`,把菜单和路由关联起来,然后使用路由元信息补充菜单配置,比如 `title`、`path` 等。 - **name**:菜单的名称。通过匹配 `name` 和路由元信息 [meta](../../../guide/route.md#扩展路由元信息) 中的 `name`,把菜单和路由关联起来,然后使用路由元信息补充菜单配置,比如 `title`、`path` 等。
- **path**:菜单的路径,可配置第三方地址。 - **path**:菜单的路径,可配置第三方地址。
- **match**:额外匹配的路径,当前路由命中匹配规则时,此菜单高亮。 (v4.0.0+
```
{
path: '/product',
match: ['/product/*', '/product/create']
}
```
- **title**:菜单的标题,如果同时使用[国际化插件](./locale.md),而且`title`的值以`$`开头,则使用`$`后面的内容去匹配语言设置。 - **title**:菜单的标题,如果同时使用[国际化插件](./locale.md),而且`title`的值以`$`开头,则使用`$`后面的内容去匹配语言设置。

View File

@ -56,21 +56,21 @@ export default {
} }
</config> </config>
``` ```
如果只是不想展示`side`,则: 如果只是不想展示`sidebar`,则:
``` ```
<config lang="json"> <config lang="json">
{ {
"layout": { "layout": {
"side": false "sidebar": false
} }
} }
</config> </config>
``` ```
`layout`的可选配置有: `layout`的可选配置有:
- **side** 左侧区域 - **sidebar** 左侧区域从v4.0.0开始,之前名称叫`side`
- **top** 头部区域 - **header** 头部区域,从v4.0.0开始,之前名称叫`top`
- **logo**logo和标题区域。 - **logo**logo和标题区域。
@ -182,6 +182,15 @@ export default {
- **name**:菜单的名称。通过匹配 `name` 和路由元信息 [meta](../../../guide/route.md#扩展路由元信息) 中的 `name`,把菜单和路由关联起来,然后使用路由元信息补充菜单配置,比如 `title`、`path` 等。 - **name**:菜单的名称。通过匹配 `name` 和路由元信息 [meta](../../../guide/route.md#扩展路由元信息) 中的 `name`,把菜单和路由关联起来,然后使用路由元信息补充菜单配置,比如 `title`、`path` 等。
- **path**:菜单的路径,可配置第三方地址。 - **path**:菜单的路径,可配置第三方地址。
- **match**:额外匹配的路径,当前路由命中匹配规则时,此菜单高亮。 (v4.0.0+
```
{
path: '/product',
match: ['/product/*', '/product/create']
}
```
- **title**:菜单的标题,如果同时使用[国际化插件](./locale.md),而且`title`的值以`$`开头,则使用`$`后面的内容去匹配语言设置。 - **title**:菜单的标题,如果同时使用[国际化插件](./locale.md),而且`title`的值以`$`开头,则使用`$`后面的内容去匹配语言设置。

View File

@ -0,0 +1,9 @@
export const flatNodes = (nodes = []) => nodes.reduce((res, node) => {
res.push(node);
if (node.children) {
res = res.concat(
flatNodes(node.children)
);
}
return res;
}, []);

View File

@ -2,7 +2,7 @@
<f-layout v-if="routeLayout" class="main-layout"> <f-layout v-if="routeLayout" class="main-layout">
<template v-if="navigation === 'side'"> <template v-if="navigation === 'side'">
<f-aside <f-aside
v-if="routeLayout.side" v-if="routeLayout.sidebar"
v-model:collapsed="collapsed" v-model:collapsed="collapsed"
:fixed="fixedSideBar" :fixed="fixedSideBar"
class="layout-aside" class="layout-aside"
@ -32,7 +32,7 @@
}" }"
> >
<f-header <f-header
v-if="routeLayout.top" v-if="routeLayout.header"
class="layout-header" class="layout-header"
:fixed="currentFixedHeader" :fixed="currentFixedHeader"
> >
@ -59,7 +59,7 @@
</template> </template>
<template v-if="navigation === 'top'"> <template v-if="navigation === 'top'">
<f-header <f-header
v-if="routeLayout.top" v-if="routeLayout.header"
class="layout-header" class="layout-header"
:inverted="theme === 'dark'" :inverted="theme === 'dark'"
:fixed="currentFixedHeader" :fixed="currentFixedHeader"
@ -96,7 +96,7 @@
</template> </template>
<template v-if="navigation === 'mixin'"> <template v-if="navigation === 'mixin'">
<f-header <f-header
v-if="routeLayout.top" v-if="routeLayout.header"
class="layout-header" class="layout-header"
:fixed="currentFixedHeader" :fixed="currentFixedHeader"
:inverted="theme === 'dark'" :inverted="theme === 'dark'"
@ -117,7 +117,7 @@
:style="{ top: currentFixedHeader ? '54px' : 'auto' }" :style="{ top: currentFixedHeader ? '54px' : 'auto' }"
> >
<f-aside <f-aside
v-if="routeLayout.side" v-if="routeLayout.sidebar"
v-model:collapsed="collapsed" v-model:collapsed="collapsed"
:fixed="fixedSideBar" :fixed="fixedSideBar"
collapsible collapsible
@ -226,8 +226,8 @@ export default {
key: 'layout', key: 'layout',
type: ApplyPluginsType.modify, type: ApplyPluginsType.modify,
initialValue: { initialValue: {
side: true, sidebar: true,
top: true, header: true,
logo: true logo: true
} }
}); });

View File

@ -1,6 +1,6 @@
<template> <template>
<f-menu <f-menu
:modelValue="route.path" :modelValue="activePath"
:inverted="inverted" :inverted="inverted"
:mode="mode" :mode="mode"
:options="fixedMenus" :options="fixedMenus"
@ -15,6 +15,7 @@ import { useRoute, useRouter } from '@@/core/coreExports';
import MenuIcon from './MenuIcon'; import MenuIcon from './MenuIcon';
import { transform as transformByAccess } from '../helpers/pluginAccess'; import { transform as transformByAccess } from '../helpers/pluginAccess';
import { transform as transformByLocale } from '../helpers/pluginLocale'; import { transform as transformByLocale } from '../helpers/pluginLocale';
import { flatNodes } from '../helpers/utils';
export default { export default {
components: { components: {
@ -56,6 +57,23 @@ export default {
return copy; return copy;
}); });
const fixedMenus = computed(() => transformByLocale(transformByAccess(transform(props.menus)))); const fixedMenus = computed(() => transformByLocale(transformByAccess(transform(props.menus))));
const menus = computed(() => flatNodes(fixedMenus.value));
const activePath = computed(() => {
const matchMenus = menus.value.filter((menu) => {
const match = menu.match;
if (!match || !Array.isArray(match)) {
return false;
}
return match.some((str) => {
const reg = new RegExp(str);
return reg.test(route.path);
});
});
if (matchMenus.length === 0) {
return route.path;
}
return matchMenus[0].path;
});
const onMenuClick = (e) => { const onMenuClick = (e) => {
const path = e.value; const path = e.value;
if (/^https?:\/\//.test(path)) { if (/^https?:\/\//.test(path)) {
@ -69,7 +87,7 @@ export default {
} }
}; };
return { return {
route, activePath,
fixedMenus, fixedMenus,
onMenuClick onMenuClick
}; };

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 50 KiB