mirror of
https://gitee.com/WeBank/fes.js.git
synced 2024-12-02 19:58:18 +08:00
feat(plugin-layout): 菜单支持配置额外的匹配规则
This commit is contained in:
parent
ab949fb6a8
commit
c998c39559
@ -56,21 +56,21 @@ export default {
|
||||
}
|
||||
</config>
|
||||
```
|
||||
如果只是不想展示`side`,则:
|
||||
如果只是不想展示`sidebar`,则:
|
||||
```
|
||||
<config lang="json">
|
||||
{
|
||||
"layout": {
|
||||
"side": false
|
||||
"sidebar": false
|
||||
}
|
||||
}
|
||||
</config>
|
||||
```
|
||||
`layout`的可选配置有:
|
||||
|
||||
- **side**: 左侧区域
|
||||
- **sidebar**: 左侧区域,从v4.0.0开始,之前名称叫`side`
|
||||
|
||||
- **top**: 头部区域
|
||||
- **header**: 头部区域,,从v4.0.0开始,之前名称叫`top`
|
||||
|
||||
- **logo**:logo和标题区域。
|
||||
|
||||
@ -182,6 +182,15 @@ export default {
|
||||
- **name**:菜单的名称。通过匹配 `name` 和路由元信息 [meta](../../../guide/route.md#扩展路由元信息) 中的 `name`,把菜单和路由关联起来,然后使用路由元信息补充菜单配置,比如 `title`、`path` 等。
|
||||
|
||||
- **path**:菜单的路径,可配置第三方地址。
|
||||
|
||||
- **match**:额外匹配的路径,当前路由命中匹配规则时,此菜单高亮。 (v4.0.0+)
|
||||
|
||||
```
|
||||
{
|
||||
path: '/product',
|
||||
match: ['/product/*', '/product/create']
|
||||
}
|
||||
```
|
||||
|
||||
- **title**:菜单的标题,如果同时使用[国际化插件](./locale.md),而且`title`的值以`$`开头,则使用`$`后面的内容去匹配语言设置。
|
||||
|
||||
|
@ -56,21 +56,21 @@ export default {
|
||||
}
|
||||
</config>
|
||||
```
|
||||
如果只是不想展示`side`,则:
|
||||
如果只是不想展示`sidebar`,则:
|
||||
```
|
||||
<config lang="json">
|
||||
{
|
||||
"layout": {
|
||||
"side": false
|
||||
"sidebar": false
|
||||
}
|
||||
}
|
||||
</config>
|
||||
```
|
||||
`layout`的可选配置有:
|
||||
|
||||
- **side**: 左侧区域
|
||||
- **sidebar**: 左侧区域,从v4.0.0开始,之前名称叫`side`
|
||||
|
||||
- **top**: 头部区域
|
||||
- **header**: 头部区域,,从v4.0.0开始,之前名称叫`top`
|
||||
|
||||
- **logo**:logo和标题区域。
|
||||
|
||||
@ -182,6 +182,15 @@ export default {
|
||||
- **name**:菜单的名称。通过匹配 `name` 和路由元信息 [meta](../../../guide/route.md#扩展路由元信息) 中的 `name`,把菜单和路由关联起来,然后使用路由元信息补充菜单配置,比如 `title`、`path` 等。
|
||||
|
||||
- **path**:菜单的路径,可配置第三方地址。
|
||||
|
||||
- **match**:额外匹配的路径,当前路由命中匹配规则时,此菜单高亮。 (v4.0.0+)
|
||||
|
||||
```
|
||||
{
|
||||
path: '/product',
|
||||
match: ['/product/*', '/product/create']
|
||||
}
|
||||
```
|
||||
|
||||
- **title**:菜单的标题,如果同时使用[国际化插件](./locale.md),而且`title`的值以`$`开头,则使用`$`后面的内容去匹配语言设置。
|
||||
|
||||
|
9
packages/fes-plugin-layout/src/runtime/helpers/utils.js
Normal file
9
packages/fes-plugin-layout/src/runtime/helpers/utils.js
Normal 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;
|
||||
}, []);
|
@ -2,7 +2,7 @@
|
||||
<f-layout v-if="routeLayout" class="main-layout">
|
||||
<template v-if="navigation === 'side'">
|
||||
<f-aside
|
||||
v-if="routeLayout.side"
|
||||
v-if="routeLayout.sidebar"
|
||||
v-model:collapsed="collapsed"
|
||||
:fixed="fixedSideBar"
|
||||
class="layout-aside"
|
||||
@ -32,7 +32,7 @@
|
||||
}"
|
||||
>
|
||||
<f-header
|
||||
v-if="routeLayout.top"
|
||||
v-if="routeLayout.header"
|
||||
class="layout-header"
|
||||
:fixed="currentFixedHeader"
|
||||
>
|
||||
@ -59,7 +59,7 @@
|
||||
</template>
|
||||
<template v-if="navigation === 'top'">
|
||||
<f-header
|
||||
v-if="routeLayout.top"
|
||||
v-if="routeLayout.header"
|
||||
class="layout-header"
|
||||
:inverted="theme === 'dark'"
|
||||
:fixed="currentFixedHeader"
|
||||
@ -96,7 +96,7 @@
|
||||
</template>
|
||||
<template v-if="navigation === 'mixin'">
|
||||
<f-header
|
||||
v-if="routeLayout.top"
|
||||
v-if="routeLayout.header"
|
||||
class="layout-header"
|
||||
:fixed="currentFixedHeader"
|
||||
:inverted="theme === 'dark'"
|
||||
@ -117,7 +117,7 @@
|
||||
:style="{ top: currentFixedHeader ? '54px' : 'auto' }"
|
||||
>
|
||||
<f-aside
|
||||
v-if="routeLayout.side"
|
||||
v-if="routeLayout.sidebar"
|
||||
v-model:collapsed="collapsed"
|
||||
:fixed="fixedSideBar"
|
||||
collapsible
|
||||
@ -226,8 +226,8 @@ export default {
|
||||
key: 'layout',
|
||||
type: ApplyPluginsType.modify,
|
||||
initialValue: {
|
||||
side: true,
|
||||
top: true,
|
||||
sidebar: true,
|
||||
header: true,
|
||||
logo: true
|
||||
}
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<f-menu
|
||||
:modelValue="route.path"
|
||||
:modelValue="activePath"
|
||||
:inverted="inverted"
|
||||
:mode="mode"
|
||||
:options="fixedMenus"
|
||||
@ -15,6 +15,7 @@ import { useRoute, useRouter } from '@@/core/coreExports';
|
||||
import MenuIcon from './MenuIcon';
|
||||
import { transform as transformByAccess } from '../helpers/pluginAccess';
|
||||
import { transform as transformByLocale } from '../helpers/pluginLocale';
|
||||
import { flatNodes } from '../helpers/utils';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@ -56,6 +57,23 @@ export default {
|
||||
return copy;
|
||||
});
|
||||
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 path = e.value;
|
||||
if (/^https?:\/\//.test(path)) {
|
||||
@ -69,7 +87,7 @@ export default {
|
||||
}
|
||||
};
|
||||
return {
|
||||
route,
|
||||
activePath,
|
||||
fixedMenus,
|
||||
onMenuClick
|
||||
};
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 50 KiB |
Loading…
Reference in New Issue
Block a user