diff --git a/CHANGELOG.md b/CHANGELOG.md
index 14143107..fce9b3de 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+# [3.0.0-beta.10](https://github.com/WeBankFinTech/fes.js/compare/v3.0.0-beta.9...v3.0.0-beta.10) (2022-06-16)
+
+
+
# [3.0.0-beta.9](https://github.com/WeBankFinTech/fes.js/compare/v3.0.0-beta.8...v3.0.0-beta.9) (2022-06-16)
diff --git a/docs/.vuepress/public/left-right.png b/docs/.vuepress/public/left-right.png
new file mode 100644
index 00000000..c5c10208
Binary files /dev/null and b/docs/.vuepress/public/left-right.png differ
diff --git a/docs/guide/route.md b/docs/guide/route.md
index cb8b456c..8dd53fc3 100644
--- a/docs/guide/route.md
+++ b/docs/guide/route.md
@@ -198,7 +198,17 @@ const router = new VueRouter({
```
-接下来我们看看如何配置 `meta`。在单文件组件中可以通过``定义:
+我们使用`defineRouteMeta` 配置 `meta`:
+
+```js
+import { defineRouteMete } from '@fesjs/fes';
+defineRouteMeta({
+ name: "store",
+ title: "vuex测试"
+})
+```
+
+当然在单文件组件中,还可以通过``配置 `meta`:
```vue
@@ -209,15 +219,10 @@ const router = new VueRouter({
```
-在使用`jsx`或者`tsx`时,可以使用`defineRouteMeta` 定义:
+::: tip
+推荐使用`defineRouteMete`,有更好的提示。
+:::
-```jsx
-import { defineRouteMete } from '@fesjs/fes';
-defineRouteMeta({
- name: "store",
- title: "vuex测试"
-})
-```
路由元信息在编译后会附加到路由配置中:
diff --git a/docs/reference/plugin/plugins/layout.md b/docs/reference/plugin/plugins/layout.md
index 67609352..f13e3db8 100644
--- a/docs/reference/plugin/plugins/layout.md
+++ b/docs/reference/plugin/plugins/layout.md
@@ -1,16 +1,16 @@
# @fesjs/plugin-layout
## 介绍
-为了进一步降低研发成本,我们尝试将布局通过 fes 插件的方式内置,只需通过简单的配置即可拥有布局,包括导航以及侧边栏。从而做到用户无需关心布局。
+为了进一步降低研发成本,我们将布局利用 `fes.js` 插件的方式内置,只需通过简单的配置即可拥有布局,包括导航以及侧边栏。从而做到用户无需关心布局。
- 侧边栏菜单数据根据路由中的配置自动生成。
-- 布局,提供 `side`、 `top`、`mixin` 三种布局。
+- 布局,提供 `side`、 `top`、`mixin`、`left-right` 四种布局。
- 主题,提供 `light`、`dark` 两种主题。
- 默认实现对路由的 404、403 处理。
- 搭配 [@fesjs/plugin-access](./access.html) 插件使用,可以完成对路由的权限控制。
- 搭配 [@fesjs/plugin-locale](./locale.html) 插件使用,提供切换语言的能力。
-- 支持自定义头部区域。
-- 菜单支持配置icon
-- 菜单标题支持国际化
+- 支持自定义头部或者侧边栏区域。
+- 菜单支持配置icon。
+- 菜单标题支持国际化。
- 可配置页面是否需要 layout。
@@ -19,21 +19,14 @@
```json
{
"dependencies": {
- "@fesjs/fes": "^2.0.0",
- "@fesjs/plugin-layout": "^4.0.0"
+ "@fesjs/fes": "^3.0.0",
+ "@fesjs/plugin-layout": "^5.0.0"
},
}
```
## 布局类型
-配置参数是 `navigation`, 布局有三种类型 `side`、`mixin` 和 `top`, 默认是 `side`:
-```js
-export default {
- layout: {
- navigation: 'side'
- }
-}
-```
+配置参数是 `navigation`, 布局有三种类型 `side`、`mixin` 、`top` 和 `left-right`, 默认是 `side`。
### side
@@ -47,45 +40,57 @@ export default {
-### 页面禁用布局
-布局是默认开启的,但是可能某些页面不需要展示布局样式,比如登录页面。我们只需要在页面的`.vue`中添加如下配置:
-```vue
-
-{
- "layout": false
-}
-
-```
-如果只是不想展示`sidebar`,则:
+### left-right
+
+
+
+### 页面个性化
+
+可以为页面单独设置布局类型:
```
{
"layout": {
- "sidebar": false
+ "navigation": 'top'
}
}
```
-`layout`的可选配置有:
-
-- **sidebar**: 左侧区域,从v4.0.0开始,之前名称叫`side`
-
-- **header**: 头部区域,从v4.0.0开始,之前名称叫`top`
-
-- **logo**:logo和标题区域。
+当设置为 `null` 时,页面不使用布局。
-## keep-alive
-从 4.0.7 开始支持配置路由页面缓存:
-```
-
-{
+## 页面缓存
+
+支持配置页面缓存,通过[定义路由元信息](../../../guide/route.html#扩展路由元信息)开启缓存:
+```js
+import { defineRouteMete } from '@fesjs/fes';
+
+defineRouteMeta({
"keep-alive": true
-}
-
+})
```
-## 编译时配置
+### 处理嵌套路由
+Fes.js 里约定目录下有 `layout.vue` 时会生成嵌套路由,以 `layout.vue` 为该目录的公共父组件,layout.vue 中必须实现 ``。如果嵌套路由下的页面设置了 `keep-alive`,则需要用 `` 替换 ``,``实现了页面缓存。
+
+```vue
+
+
+
+
+```
+
+## 配置
+
+#### 编译时配置方式
+
在 `.fes.js` 中配置:
```js
export default {
@@ -95,17 +100,7 @@ export default {
// 底部文字
footer: 'Created by MumbleFE',
// 主题light
- theme: 'dark'
- // 是否开启 tabs
- multiTabs: false,
- // 布局类型
- navigation: 'side',
- // 是否固定头部
- fixedHeader: false,
- // 是否固定sidebar
- fixedSideBar: true,
- // sidebar的宽度
- sideWidth: 200,
+ theme: 'dark',
menus: [{
name: 'index'
}, {
@@ -115,14 +110,51 @@ export default {
}, {
name: 'simpleList'
}],
- menuConfig: {
- defaultExpandAll: false,
- expandedKeys: [],
- accordion: false
- }
+
},
```
+#### 运行时配置方式
+
+在 `app.js` 中配置:
+```js
+import UserCenter from '@/components/UserCenter';
+export const layout = {
+ renderHeader: ()=> ,
+ menus: [{
+ name: 'index'
+ }]
+};
+
+```
+在`fes.js`中,运行时配置有定义对象和函数两种方式,当使用函数配置`layout`时,`layoutConfig`是编译时配置结果,`initialState`是 `beforeRender.action`执行后创建的应用初始状态数据。
+。
+```js
+export const layout = (layoutConfig, { initialState }) => ({
+ renderHeader: () => ,
+ menus: () => {
+ const menusRef = ref(layoutConfig.menus);
+ watch(
+ () => initialState.userName,
+ () => {
+ menusRef.value = [
+ {
+ name: 'store',
+ },
+ ];
+ },
+ );
+ return menusRef;
+ },
+});
+```
+
+最终配置结果是运行时配置跟编译时配置合并的结果,运行时配置优先于编译时配置。
+
+实际上运行配置能做的事情更多,推荐用运行时配置方式。
+
+
+
### footer
- **类型**:`String`
@@ -144,14 +176,14 @@ export default {
- **详情**:页面布局类型,可选有 `side`、 `top`、 `mixin`
-### fixedHeader
+### isFixedHeader
- **类型**:`Boolean`
- **默认值**:`false`
- **详情**:是否固定头部,不跟随页面滚动。
-### fixedSideBar
+### isFixedSidebar
- **类型**:`Boolean`
- **默认值**:`true`
@@ -161,14 +193,14 @@ export default {
### title
- **类型**:`String`
-- **默认值**:`name` in package.json
+- **默认值**:默认为 [编译时配置title](../../../reference/config/#title)
-- **详情**:产品名,会显示在 Logo 旁边。
+- **详情**:产品名。
### logo
- **类型**:`String`
-- **默认值**:默认提供 fes.js 的 Logo
+- **默认值**:默认提供 `fes.js` 的 Logo
- **详情**:Logo的链接
@@ -181,7 +213,7 @@ export default {
- **详情**:是否开启多页。
### menus
-- **类型**:`Array`
+- **类型**:`[] | ()=> Ref<[]>`
- **默认值**:`[]`
@@ -203,13 +235,11 @@ export default {
- **title**:菜单的标题,如果同时使用[国际化插件](./locale.md),而且`title`的值以`$`开头,则使用`$`后面的内容去匹配语言设置。
- **icon**: 菜单的图标,只有一级标题展示图标。
- - 图标使用[fes-design icon](https://fes-design-4gvn317r3b6bfe17-1254145788.ap-shanghai.app.tcloudbase.com/zh/components/icon.html),在这里使用组件名称。
-```js
-{
- icon: "AppstoreOutlined"
-}
-```
+
+ - 图标使用[fes-design icon](https://fes-design-4gvn317r3b6bfe17-1254145788.ap-shanghai.app.tcloudbase.com/zh/components/icon.html),编译时配置使用组件名称,我们会自动引入组件。
+
- 图标使用本地或者远程svg图片。
+
```js
{
icon: "/wine-outline.svg"
@@ -218,7 +248,13 @@ export default {
- **children**:子菜单配置。
-### menusConfig
+:::tip
+函数类型仅在运行时可用,可以实现动态变更菜单。
+:::
+
+
+
+### menuProps
- **类型**:`Object`
- **默认值**:`{}`
@@ -231,84 +267,29 @@ export default {
- **accordion**:是否只保持一个子菜单的展开。
-## 运行时配置
-在 `app.js` 中配置:
-```js
-import UserCenter from '@/components/UserCenter';
-export const layout = {
- customHeader:
-};
-```
-
-### menus
-- **类型**:`(defaultMenus: [] )=> Ref | []`
+### sideWidth
+- **类型**:`Number`
-- **详情**:运行时修改菜单,入参是默认菜单配置(.fes.js中的menu配置),需要返回一个`Ref`或者数组。
+- **默认值**:`200`
-```js
-import { ClusterOutlined } from '@fesjs/fes-design/icon'
-export const layout = layoutConfig => ({
- ...layoutConfig,
- customHeader: ,
- menus: (defaultMenuData) => {
- const menusRef = ref(defaultMenuData);
- watch(() => layoutConfig.initialState.userName, () => {
- menusRef.value = [{
- name: 'store',
- icon:
- }];
- });
- return menusRef;
- }
-});
-
-```
-`layoutConfig.initialState` 是 `beforeRender.action`执行后创建的应用初始状态数据。
-
-如果菜单需要根据某些状态动态改变,则返回`Ref`,否则只需要返回数组。
-
-:::tip
-在运行时配置菜单中的icon,需要传组件本身,而不是组件的名称。
-:::
-
-
-### header
-- **类型**:`String`
+- **详情**:sidebar的宽度
-- **默认值**:`true`
-- **详情**:是否显示 header 区域。
-
-### sidebar
-- **类型**:`String`
-
-- **默认值**:`true`
-
-- **详情**:是否显示 sidebar 区域。
-
-### logo
-- **类型**:`String`
-
-- **默认值**:`true`
-
-- **详情**:是否显示 logo 区域。
-
-### customHeader
-- **类型**:Vue Component
+### renderCustom
+- **类型**: `()=> VNodes`
- **默认值**:`null`
-- **详情**:top的区域部分位置提供组件自定义功能。
+- **详情**: 自定义区域内容,仅运行时。
+
### unAccessHandler
-- **类型**:`Function`
+- **类型**:`({ to, from, next})=> void`
- **默认值**:`null`
-- **详情**:
-
- 当进入某个路由时,如果路由对应的页面不属于可见资源列表,则会暂停进入,调用 `unAccessHandler` 函数。
+- **详情**:仅运行时,当进入某个路由时,如果路由对应的页面不属于可见资源列表,则会暂停进入,调用 `unAccessHandler` 函数。
- **参数**
- router:createRouter 创建的路由实例
- to: 准备进入的路由
@@ -334,13 +315,11 @@ export const access = {
```
### noFoundHandler
-- **类型**:函数
+- **类型**:`({ to, from, next})=> void`
-- **默认值**:null
+- **默认值**:`null`
-- **详情**:
-
- 当进入某个路由时,如果路由对应的页面不存在,则会调用 `noFoundHandler` 函数。
+- **详情**:仅运行时,当进入某个路由时,如果路由对应的页面不存在,则会调用 `noFoundHandler` 函数。
- **参数**
- router:createRouter 创建的路由实例
- to: 准备进入的路由
@@ -361,13 +340,12 @@ export const access = {
```
-### logoUrl
-- **类型**:`String`
-
-- **默认值**:默认提供 fes.js 的 Logo
-- **详情**:Logo的链接。
+### 4.x 升级到 5.x
-
-### 其他运行时配置 (> 4.1.0)
-编译时配置的内容同样支持在运行时配置,但是`logo`除外,用`logoUrl`替代。
\ No newline at end of file
+1. 个性化 layout 配置改为使用传入 navigation
+2. renderHeader 改为 renderCustom
+3. fixedHeader 改为 isFixedHeader
+4. menusConfig 改为 menuProps
+5. fixedSideBar 改为 isFixedSidebar
+6. 去掉运行时 logo、header、sidebar 三个区域显示配置,请改为使用 navigation: left-right
\ No newline at end of file
diff --git a/package.json b/package.json
index 2a8dd1a8..66dcb49e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "fes.js",
- "version": "3.0.0-beta.9",
+ "version": "3.0.0-beta.10",
"description": "一个好用的前端管理台快速开发框架",
"preferGlobal": true,
"private": true,
diff --git a/packages/create-fes-app/package.json b/packages/create-fes-app/package.json
index 22cf44cd..adaa951c 100644
--- a/packages/create-fes-app/package.json
+++ b/packages/create-fes-app/package.json
@@ -1,6 +1,6 @@
{
"name": "@fesjs/create-fes-app",
- "version": "3.0.0-beta.3",
+ "version": "3.0.0-beta.4",
"description": "create a app base on fes.js",
"main": "lib/index.js",
"files": [
diff --git a/packages/create-fes-app/templates/app/h5/src/styles/common.less b/packages/create-fes-app/templates/app/h5/src/styles/common.less
index 8d2bd816..706444c2 100644
--- a/packages/create-fes-app/templates/app/h5/src/styles/common.less
+++ b/packages/create-fes-app/templates/app/h5/src/styles/common.less
@@ -26,8 +26,7 @@ a {
/* 适配 iPhone X 顶部填充*/
@supports (top: env(safe-area-inset-top)){
- body,
- .alien-screen-header {
+ body {
padding-top: constant(safe-area-inset-top, 40px);
padding-top: env(safe-area-inset-top, 40px);
padding-top: var(safe-area-inset-top, 40px);
@@ -36,10 +35,9 @@ a {
/* 判断iPhoneX 将 footer 的 padding-bottom 填充到最底部 */
@supports (bottom: env(safe-area-inset-bottom)){
- body,
- .alien-screen-footer {
+ body {
padding-bottom: constant(safe-area-inset-bottom, 20px);
padding-bottom: env(safe-area-inset-bottom, 20px);
- padding-top: var(safe-area-inset-bottom, 20px);
+ padding-bottom: var(safe-area-inset-bottom, 20px);
}
}
diff --git a/packages/fes-plugin-layout/src/index.js b/packages/fes-plugin-layout/src/index.js
index eff1a9f5..09b5935c 100644
--- a/packages/fes-plugin-layout/src/index.js
+++ b/packages/fes-plugin-layout/src/index.js
@@ -24,16 +24,16 @@ export default (api) => {
api.addRuntimePluginKey(() => 'layout');
- const absFilePath = join(namespace, 'index.jsx');
+ const absFilePath = join(namespace, 'views/index.jsx');
+
+ const absConfigFilePath = join(namespace, 'helpers/getConfig.js');
const absRuntimeFilePath = join(namespace, 'runtime.js');
api.onGenerateFiles(async () => {
- const HAS_LOCALE = api.hasPlugins(['@fesjs/plugin-locale']);
-
// .fes配置
const userConfig = {
- title: api.pkg.name,
+ title: api.title,
footer: 'Created by Fes.js',
...(api.config.layout || {}),
};
@@ -52,9 +52,15 @@ export default (api) => {
api.writeTmpFile({
path: absFilePath,
- content: Mustache.render(readFileSync(join(__dirname, 'runtime/index.tpl'), 'utf-8'), {
+ content: Mustache.render(readFileSync(join(__dirname, 'runtime/views/index.tpl'), 'utf-8'), {
+ REPLACE_USER_CONFIG: JSON.stringify(userConfig),
+ }),
+ });
+
+ api.writeTmpFile({
+ path: absConfigFilePath,
+ content: Mustache.render(readFileSync(join(__dirname, 'runtime/helpers/getConfig.tpl'), 'utf-8'), {
REPLACE_USER_CONFIG: JSON.stringify(userConfig),
- HAS_LOCALE,
}),
});
@@ -67,6 +73,13 @@ export default (api) => {
api.addRuntimePlugin(() => `@@/${absRuntimeFilePath}`);
+ api.addPluginExports(() => [
+ {
+ specifiers: ['Page'],
+ source: join(namespace, 'index.js'),
+ },
+ ]);
+
// 把BaseLayout插入到路由配置中,作为根路由
api.modifyRoutes((routes) => [
{
diff --git a/packages/fes-plugin-layout/src/node/helper.js b/packages/fes-plugin-layout/src/node/helper.js
index effedb72..67a318b0 100644
--- a/packages/fes-plugin-layout/src/node/helper.js
+++ b/packages/fes-plugin-layout/src/node/helper.js
@@ -1,19 +1,15 @@
-
export function getIconNamesFromMenu(data) {
if (!Array.isArray(data)) {
return [];
}
let icons = [];
- data.forEach((item = { path: '/' }) => {
+ data.forEach((item) => {
if (item.icon) {
const { icon } = item;
// 处理icon
if (icon) {
const urlReg = /^((https?|ftp|file):\/\/)?([\da-z.-]+)\.([a-z.]{2,6})([/\w .-]*)*\/?$/;
- if (
- typeof icon === 'string'
- && !(urlReg.test(icon) || icon.includes('.svg'))
- ) {
+ if (typeof icon === 'string' && !(urlReg.test(icon) || icon.includes('.svg'))) {
icons.push(icon);
}
}
diff --git a/packages/fes-plugin-layout/src/runtime/helpers/getConfig.tpl b/packages/fes-plugin-layout/src/runtime/helpers/getConfig.tpl
new file mode 100644
index 00000000..94934d50
--- /dev/null
+++ b/packages/fes-plugin-layout/src/runtime/helpers/getConfig.tpl
@@ -0,0 +1,15 @@
+import { plugin, ApplyPluginsType } from '@@/core/coreExports';
+import { initialState } from '@@/initialState';
+
+export default () => {
+ const initConfig = {{{REPLACE_USER_CONFIG}}}
+ const runtimeConfig = plugin.applyPlugins({
+ key: 'layout',
+ type: ApplyPluginsType.modify,
+ initialValue: initConfig,
+ args: {
+ initialState
+ }
+ });
+ return runtimeConfig;
+};
diff --git a/packages/fes-plugin-layout/src/runtime/helpers/getRuntimeConfig.js b/packages/fes-plugin-layout/src/runtime/helpers/getRuntimeConfig.js
deleted file mode 100644
index 1ca1ef5c..00000000
--- a/packages/fes-plugin-layout/src/runtime/helpers/getRuntimeConfig.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import { plugin, ApplyPluginsType } from '@@/core/coreExports';
-import { initialState } from '@@/initialState';
-
-let runtimeConfig;
-
-export default () => {
- if (!runtimeConfig) {
- runtimeConfig = plugin.applyPlugins({
- key: 'layout',
- type: ApplyPluginsType.modify,
- initialValue: {
- initialState,
- sidebar: true,
- header: true,
- logo: true,
- },
- });
- }
- return runtimeConfig;
-};
diff --git a/packages/fes-plugin-layout/src/runtime/helpers/pluginAccess.js b/packages/fes-plugin-layout/src/runtime/helpers/pluginAccess.js
index 7b14a599..a18b90bd 100644
--- a/packages/fes-plugin-layout/src/runtime/helpers/pluginAccess.js
+++ b/packages/fes-plugin-layout/src/runtime/helpers/pluginAccess.js
@@ -3,9 +3,7 @@ import { computed, ref } from 'vue';
import { useAccess } from '../../plugin-access/core';
if (!useAccess) {
- throw new Error(
- '[plugin-layout]: pLugin-layout depends on plugin-access,please install plugin-access first!'
- );
+ throw new Error('[plugin-layout]: pLugin-layout depends on plugin-access,please install plugin-access first!');
}
export const hasAccessByMenuItem = (item) => {
@@ -14,21 +12,26 @@ export const hasAccessByMenuItem = (item) => {
return useAccess(item.path);
}
if (hasChild) {
- return computed(() => item.children.some((child) => {
- const rst = hasAccessByMenuItem(child);
- return rst && rst.value;
- }));
+ return computed(() =>
+ item.children.some((child) => {
+ const rst = hasAccessByMenuItem(child);
+ return rst && rst.value;
+ }),
+ );
}
return ref(true);
};
-export const transform = menus => menus.map((menu) => {
- const hasAccess = hasAccessByMenuItem(menu);
- if (!hasAccess.value) {
- return false;
- }
- if (menu.children) {
- menu.children = transform(menu.children);
- }
- return menu;
-}).filter(Boolean);
+export const transform = (menus) =>
+ menus
+ .map((menu) => {
+ const hasAccess = hasAccessByMenuItem(menu);
+ if (!hasAccess.value) {
+ return false;
+ }
+ if (menu.children) {
+ menu.children = transform(menu.children);
+ }
+ return menu;
+ })
+ .filter(Boolean);
diff --git a/packages/fes-plugin-layout/src/runtime/helpers/pluginLocale.js b/packages/fes-plugin-layout/src/runtime/helpers/pluginLocale.js
index 4682d7d2..fc2a6693 100644
--- a/packages/fes-plugin-layout/src/runtime/helpers/pluginLocale.js
+++ b/packages/fes-plugin-layout/src/runtime/helpers/pluginLocale.js
@@ -12,14 +12,14 @@ export const transTitle = (name) => {
return name;
};
-
-export const transform = menus => menus.map((menu) => {
- const copy = {
- ...menu,
- label: transTitle(menu.label)
- };
- if (menu.children) {
- copy.children = transform(menu.children);
- }
- return copy;
-});
+export const transform = (menus) =>
+ menus.map((menu) => {
+ const copy = {
+ ...menu,
+ label: transTitle(menu.label),
+ };
+ if (menu.children) {
+ copy.children = transform(menu.children);
+ }
+ return copy;
+ });
diff --git a/packages/fes-plugin-layout/src/runtime/helpers/utils.js b/packages/fes-plugin-layout/src/runtime/helpers/utils.js
index e8b16aa7..29750c4d 100644
--- a/packages/fes-plugin-layout/src/runtime/helpers/utils.js
+++ b/packages/fes-plugin-layout/src/runtime/helpers/utils.js
@@ -1,9 +1,8 @@
-export const flatNodes = (nodes = []) => nodes.reduce((res, node) => {
- res.push(node);
- if (node.children) {
- res = res.concat(
- flatNodes(node.children)
- );
- }
- return res;
-}, []);
+export const flatNodes = (nodes = []) =>
+ nodes.reduce((res, node) => {
+ res.push(node);
+ if (node.children) {
+ res = res.concat(flatNodes(node.children));
+ }
+ return res;
+ }, []);
diff --git a/packages/fes-plugin-layout/src/runtime/index.js b/packages/fes-plugin-layout/src/runtime/index.js
new file mode 100644
index 00000000..72f0ee5a
--- /dev/null
+++ b/packages/fes-plugin-layout/src/runtime/index.js
@@ -0,0 +1 @@
+export { default as Page } from './views/page.vue';
diff --git a/packages/fes-plugin-layout/src/runtime/index.tpl b/packages/fes-plugin-layout/src/runtime/index.tpl
deleted file mode 100644
index 2ac3c057..00000000
--- a/packages/fes-plugin-layout/src/runtime/index.tpl
+++ /dev/null
@@ -1,79 +0,0 @@
-import { ref, defineComponent, computed } from 'vue';
-import { plugin, ApplyPluginsType, } from '@@/core/coreExports';
-import { getRoutes } from '@@/core/routes/routes'
-import BaseLayout from './views/BaseLayout.vue';
-import getRuntimeConfig from './helpers/getRuntimeConfig';
-import fillMenu from './helpers/fillMenu';
-
-const Layout = defineComponent({
- name: 'Layout',
- setup() {
- const userConfig = {{{REPLACE_USER_CONFIG}}};
- const runtimeConfig = getRuntimeConfig();
- const {
- menus,
- customHeader,
- menuConfig,
- // 非 BaseLayout需要的
- initialState,
- sidebar,
- header,
- logo,
- // 跟logo冲突,换个名字
- logoUrl,
- ...otherConfig
- } = runtimeConfig;
- if (logoUrl) {
- userConfig.logo = logoUrl;
- }
- if (menuConfig && typeof menuConfig === 'object') {
- Object.assign(userConfig.menuConfig, menuConfig);
- }
- Object.keys(otherConfig).forEach((p) => {
- if (otherConfig[p] !== undefined) {
- userConfig[p] = otherConfig[p];
- }
- });
- let menusRef = ref(userConfig.menus);
- // 如果运行时配置了menus,则需要处理
- if (menus && typeof menus === 'function') {
- menusRef = ref(menus(userConfig.menus));
- }
- // 把路由的meta合并到menu配置中
- const filledMenuRef = computed(() => {
- return fillMenu(menusRef.value, getRoutes());
- });
-
- const localeShared = plugin.getShared('locale');
- return () => {
- const slots = {
- customHeader: () => {
- if (runtimeConfig.customHeader) {
- return (
-
- );
- }
- return null;
- },
- locale: () => {
- if (localeShared) {
- return (
-
- );
- }
- return null;
- }
- };
- return (
-
- );
- };
- }
-});
-
-export default Layout;
diff --git a/packages/fes-plugin-layout/src/runtime/runtime.js b/packages/fes-plugin-layout/src/runtime/runtime.js
index f0430aa3..2e087953 100644
--- a/packages/fes-plugin-layout/src/runtime/runtime.js
+++ b/packages/fes-plugin-layout/src/runtime/runtime.js
@@ -2,7 +2,8 @@
import { access as accessApi } from '../plugin-access/core';
import Exception404 from './views/404.vue';
import Exception403 from './views/403.vue';
-import getRuntimeConfig from './helpers/getRuntimeConfig';
+// eslint-disable-next-line import/extensions
+import getConfig from './helpers/getConfig';
if (!accessApi) {
throw new Error('[plugin-layout]: pLugin-layout depends on plugin-access,please install plugin-access first!');
@@ -24,40 +25,41 @@ const handle = (type, router) => {
}
};
-export const access = (memo) => ({
- unAccessHandler({ router, to, from, next }) {
- const runtimeConfig = getRuntimeConfig();
- if (runtimeConfig.unAccessHandler && typeof runtimeConfig.unAccessHandler === 'function') {
- return runtimeConfig.unAccessHandler({
- router,
- to,
- from,
- next,
- });
- }
- if (to.path === '/404') {
- handle(404, router);
- return next('/404');
- }
- handle(403, router);
- next('/403');
- },
- noFoundHandler({ router, to, from, next }) {
- const runtimeConfig = getRuntimeConfig();
- if (runtimeConfig.noFoundHandler && typeof runtimeConfig.noFoundHandler === 'function') {
- return runtimeConfig.noFoundHandler({
- router,
- to,
- from,
- next,
- });
- }
- if (to.path === '/403') {
+export const access = (memo) => {
+ const runtimeConfig = getConfig();
+ return {
+ unAccessHandler({ router, to, from, next }) {
+ if (runtimeConfig.unAccessHandler && typeof runtimeConfig.unAccessHandler === 'function') {
+ return runtimeConfig.unAccessHandler({
+ router,
+ to,
+ from,
+ next,
+ });
+ }
+ if (to.path === '/404') {
+ handle(404, router);
+ return next('/404');
+ }
handle(403, router);
- return next('/403');
- }
- handle(404, router);
- next('/404');
- },
- ...memo,
-});
+ next('/403');
+ },
+ noFoundHandler({ router, to, from, next }) {
+ if (runtimeConfig.noFoundHandler && typeof runtimeConfig.noFoundHandler === 'function') {
+ return runtimeConfig.noFoundHandler({
+ router,
+ to,
+ from,
+ next,
+ });
+ }
+ if (to.path === '/403') {
+ handle(403, router);
+ return next('/403');
+ }
+ handle(404, router);
+ next('/404');
+ },
+ ...memo,
+ };
+};
diff --git a/packages/fes-plugin-layout/src/runtime/views/403.vue b/packages/fes-plugin-layout/src/runtime/views/403.vue
index b094bc16..04501ab3 100644
--- a/packages/fes-plugin-layout/src/runtime/views/403.vue
+++ b/packages/fes-plugin-layout/src/runtime/views/403.vue
@@ -6,15 +6,8 @@
d="M0 129.023v-2.084C0 58.364 55.591 2.774 124.165 2.774h2.085c68.574 0 124.165 55.59 124.165 124.165v2.084c0 68.575-55.59 124.166-124.165 124.166h-2.085C55.591 253.189 0 197.598 0 129.023"
fill="#E4EBF7"
>
-
-
+
+
-
+
-
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
+
-
+
diff --git a/packages/fes-template-h5/src/styles/common.less b/packages/fes-template-h5/src/styles/common.less
index 8d2bd816..7cc7d45a 100644
--- a/packages/fes-template-h5/src/styles/common.less
+++ b/packages/fes-template-h5/src/styles/common.less
@@ -26,8 +26,7 @@ a {
/* 适配 iPhone X 顶部填充*/
@supports (top: env(safe-area-inset-top)){
- body,
- .alien-screen-header {
+ body {
padding-top: constant(safe-area-inset-top, 40px);
padding-top: env(safe-area-inset-top, 40px);
padding-top: var(safe-area-inset-top, 40px);
@@ -36,10 +35,9 @@ a {
/* 判断iPhoneX 将 footer 的 padding-bottom 填充到最底部 */
@supports (bottom: env(safe-area-inset-bottom)){
- body,
- .alien-screen-footer {
+ body {
padding-bottom: constant(safe-area-inset-bottom, 20px);
padding-bottom: env(safe-area-inset-bottom, 20px);
- padding-top: var(safe-area-inset-bottom, 20px);
+ padding-bottom: var(safe-area-inset-bottom, 20px);
}
}
diff --git a/packages/fes-template-vite/src/app.jsx b/packages/fes-template-vite/src/app.jsx
index 9e119776..436427a1 100644
--- a/packages/fes-template-vite/src/app.jsx
+++ b/packages/fes-template-vite/src/app.jsx
@@ -23,5 +23,5 @@ export const beforeRender = {
};
export const layout = {
- customHeader: ,
+ renderCustom: () => ,
};
diff --git a/packages/fes-template/.fes.js b/packages/fes-template/.fes.js
index 09d1af45..16c808f3 100644
--- a/packages/fes-template/.fes.js
+++ b/packages/fes-template/.fes.js
@@ -72,7 +72,7 @@ export default {
name: 'pinia'
}
],
- menuConfig: {
+ menuProps: {
defaultExpandAll: false
}
},
diff --git a/packages/fes-template/src/app.js b/packages/fes-template/src/app.js
index 3779c8a2..78c1921a 100644
--- a/packages/fes-template/src/app.js
+++ b/packages/fes-template/src/app.js
@@ -1,5 +1,5 @@
import { access as accessApi, pinia, createWatermark } from '@fesjs/fes';
-import { ref } from 'vue';
+import { ref, watch } from 'vue';
import PageLoading from '@/components/PageLoading.vue';
import UserCenter from '@/components/UserCenter.vue';
import { useStore } from '@/store/main';
@@ -24,16 +24,21 @@ export const beforeRender = {
},
};
-export const layout = (layoutConfig) => ({
+export const layout = (layoutConfig, { initialState }) => ({
...layoutConfig,
- customHeader: ,
- menus: (defaultMenuData) => {
- const menusRef = ref(defaultMenuData);
- // watch(() => initialValue.initialState.userName, () => {
- // menusRef.value = [{
- // name: 'store'
- // }];
- // });
+ renderCustom: () => ,
+ menus: () => {
+ const menusRef = ref(layoutConfig.menus);
+ watch(
+ () => initialState.userName,
+ () => {
+ menusRef.value = [
+ {
+ name: 'store',
+ },
+ ];
+ },
+ );
return menusRef;
},
});
diff --git a/packages/fes-template/src/components/UserCenter.vue b/packages/fes-template/src/components/UserCenter.vue
index 6bbb7563..386f27f2 100644
--- a/packages/fes-template/src/components/UserCenter.vue
+++ b/packages/fes-template/src/components/UserCenter.vue
@@ -15,6 +15,6 @@ export default {
diff --git a/packages/fes-template/src/pages/index.vue b/packages/fes-template/src/pages/index.vue
index 5d9811a3..41275d99 100644
--- a/packages/fes-template/src/pages/index.vue
+++ b/packages/fes-template/src/pages/index.vue
@@ -5,17 +5,14 @@
-
-
-
-{
- "name": "index",
- "title": "$home"
-}
-
diff --git a/packages/fes-template/src/pages/pinia.vue b/packages/fes-template/src/pages/pinia.vue
index f55fc856..8b22688c 100644
--- a/packages/fes-template/src/pages/pinia.vue
+++ b/packages/fes-template/src/pages/pinia.vue
@@ -1,31 +1,32 @@
- {{store.counter}}
+ {{ store.counter }}
Button
{
"name": "pinia",
- "title": "pinia"
+ "title": "pinia",
+ "layout": {
+ "navigation": null
+ }
}
-
+
diff --git a/scripts/build.mjs b/scripts/build.mjs
index 58c7e3ee..27e2ceec 100644
--- a/scripts/build.mjs
+++ b/scripts/build.mjs
@@ -69,7 +69,9 @@ async function getPkgConfig(config, pkgName) {
const pkgConfigPath = path.join(getPkgPath(pkgName), CONFIG_FILE_NAME);
if (fs.existsSync(pkgConfigPath)) {
const content = await import(process.platform === 'win32' ? `file://${pkgConfigPath}` : pkgConfigPath);
- return merge(config, content.default);
+ const result = merge(config, content.default);
+ result.resolveCopy = result.copy.map((item) => path.join(getPkgPath(pkgName), 'src', item));
+ return result;
}
return config;
@@ -104,13 +106,17 @@ function cleanBeforeCompilerResult(pkgName, log) {
function transformFile(filePath, outputPath, config, log) {
if (/\.[jt]sx?$/.test(path.extname(filePath))) {
- const code = fs.readFileSync(filePath, 'utf-8');
- const shortFilePath = genShortPath(filePath);
- const transformedCode = compiler(code, config);
+ try {
+ const code = fs.readFileSync(filePath, 'utf-8');
+ const shortFilePath = genShortPath(filePath);
+ const transformedCode = compiler(code, config);
- const type = config.target === 'browser' ? ESM_OUTPUT_DIR : NODE_CJS_OUTPUT_DIR;
- log(`Transform to ${type} for ${config.target === 'browser' ? chalk.yellow(shortFilePath) : chalk.blue(shortFilePath)}`);
- fse.outputFileSync(outputPath, transformedCode);
+ const type = config.target === 'browser' ? ESM_OUTPUT_DIR : NODE_CJS_OUTPUT_DIR;
+ log(`Transform to ${type} for ${config.target === 'browser' ? chalk.yellow(shortFilePath) : chalk.blue(shortFilePath)}`);
+ fse.outputFileSync(outputPath, transformedCode);
+ } catch (error) {
+ console.error(error);
+ }
} else {
fse.copySync(filePath, outputPath);
}
@@ -140,12 +146,11 @@ function watchFile(dir, outputDir, config, log) {
})
.on('all', (event, changeFile) => {
// 修改的可能是一个目录,一个文件,一个需要 copy 的文件 or 目录
- const baseName = path.basename(changeFile);
const shortChangeFile = genShortPath(changeFile);
const outputPath = changeFile.replace(dir, outputDir);
const stat = fs.lstatSync(changeFile);
log(`[${event}] ${shortChangeFile}`);
- if (config.copy.includes(baseName)) {
+ if (config.resolveCopy.some((item) => changeFile.startsWith(item))) {
fse.copySync(changeFile, outputPath);
} else if (stat.isFile()) {
transformFile(changeFile, outputPath, config, log);