From 4d25799d703a47af2d9c128d99663814dc5d5fc7 Mon Sep 17 00:00:00 2001 From: wanchun <445436867@qq.com> Date: Thu, 16 Jun 2022 20:26:36 +0800 Subject: [PATCH] =?UTF-8?q?break:=20plugin-layout=E4=BC=98=E5=8C=96api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/reference/plugin/plugins/layout.md | 249 +++++++++--------- packages/fes-plugin-layout/src/index.js | 25 +- packages/fes-plugin-layout/src/node/helper.js | 8 +- .../src/runtime/helpers/getConfig.tpl | 15 ++ .../src/runtime/helpers/getRuntimeConfig.js | 20 -- .../src/runtime/helpers/pluginAccess.js | 37 +-- .../src/runtime/helpers/pluginLocale.js | 22 +- .../src/runtime/helpers/utils.js | 17 +- .../fes-plugin-layout/src/runtime/index.js | 3 + .../fes-plugin-layout/src/runtime/index.tpl | 79 ------ .../fes-plugin-layout/src/runtime/runtime.js | 76 +++--- .../src/runtime/views/403.vue | 104 ++------ .../src/runtime/views/404.vue | 87 ++---- .../src/runtime/views/BaseLayout.vue | 71 ++--- .../src/runtime/views/MultiTabProvider.vue | 30 +-- .../src/runtime/views/index.tpl | 44 ++++ .../src/runtime/views/page.vue | 64 +++++ packages/fes-template-vite/src/app.jsx | 2 +- packages/fes-template/.fes.js | 2 +- packages/fes-template/src/app.js | 25 +- packages/fes-template/src/pages/pinia.vue | 17 +- scripts/build.mjs | 16 +- 22 files changed, 460 insertions(+), 553 deletions(-) create mode 100644 packages/fes-plugin-layout/src/runtime/helpers/getConfig.tpl delete mode 100644 packages/fes-plugin-layout/src/runtime/helpers/getRuntimeConfig.js create mode 100644 packages/fes-plugin-layout/src/runtime/index.js delete mode 100644 packages/fes-plugin-layout/src/runtime/index.tpl create mode 100644 packages/fes-plugin-layout/src/runtime/views/index.tpl create mode 100644 packages/fes-plugin-layout/src/runtime/views/page.vue diff --git a/docs/reference/plugin/plugins/layout.md b/docs/reference/plugin/plugins/layout.md index 67609352..84ff6d3f 100644 --- a/docs/reference/plugin/plugins/layout.md +++ b/docs/reference/plugin/plugins/layout.md @@ -1,7 +1,7 @@ # @fesjs/plugin-layout ## 介绍 -为了进一步降低研发成本,我们尝试将布局通过 fes 插件的方式内置,只需通过简单的配置即可拥有布局,包括导航以及侧边栏。从而做到用户无需关心布局。 +为了进一步降低研发成本,我们将布局利用 `fes.js` 插件的方式内置,只需通过简单的配置即可拥有布局,包括导航以及侧边栏。从而做到用户无需关心布局。 - 侧边栏菜单数据根据路由中的配置自动生成。 - 布局,提供 `side`、 `top`、`mixin` 三种布局。 - 主题,提供 `light`、`dark` 两种主题。 @@ -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`, 默认是 `side`。 ### side @@ -47,8 +40,33 @@ export default { mixin -### 页面禁用布局 -布局是默认开启的,但是可能某些页面不需要展示布局样式,比如登录页面。我们只需要在页面的`.vue`中添加如下配置: +### 布局开关 + +布局默认开启,可以通过一些方式更改。 + +开关的可选配置有: + +- **sidebar**: 左侧区域 + +- **header**: 头部区域 + +- **logo**:logo和标题区域。 + +#### 全局定义 + +全局定义可以通过配置`switch`实现,在 `app.js` 中配置: +```js +import UserCenter from '@/components/UserCenter'; +export const layout = { + switch: { + header: false + } +}; + +``` + +#### 页面定义 +可以通过[定义路由元信息](../../../guide/route.html#扩展路由元信息)配置页面的布局开关,添加如下配置: ```vue { @@ -66,17 +84,15 @@ export default { } ``` -`layout`的可选配置有: -- **sidebar**: 左侧区域,从v4.0.0开始,之前名称叫`side` - -- **header**: 头部区域,从v4.0.0开始,之前名称叫`top` - -- **logo**:logo和标题区域。 +#### 地址参数定义 +通过路由的`query`参数定义,比如当访问`http://localhost:8080/#/?layout={%22sidebar%22:%20false,%20%22header%22:%20false}` 时,页面隐藏 `sidebar`和`header`区域。此种方式优先级最高! -## keep-alive -从 4.0.7 开始支持配置路由页面缓存: + +## 页面缓存 + +支持配置页面缓存,通过[定义路由元信息](../../../guide/route.html#扩展路由元信息)开启缓存: ``` { @@ -85,7 +101,10 @@ export default { ``` -## 编译时配置 +## 配置 + +#### 编译时配置方式 + 在 `.fes.js` 中配置: ```js export default { @@ -95,17 +114,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 +124,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 +190,14 @@ export default { - **详情**:页面布局类型,可选有 `side`、 `top`、 `mixin` -### fixedHeader +### isHeaderFixed - **类型**:`Boolean` - **默认值**:`false` - **详情**:是否固定头部,不跟随页面滚动。 -### fixedSideBar +### isSidebarFixed - **类型**:`Boolean` - **默认值**:`true` @@ -161,14 +207,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 +227,7 @@ export default { - **详情**:是否开启多页。 ### menus -- **类型**:`Array` +- **类型**:`[] | ()=> Ref<[]>` - **默认值**:`[]` @@ -203,13 +249,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 +262,13 @@ export default { - **children**:子菜单配置。 -### menusConfig +:::tip +函数类型仅在运行时可用,可以实现动态变更菜单。 +::: + + + +### menusProps - **类型**:`Object` - **默认值**:`{}` @@ -231,84 +281,42 @@ export default { - **accordion**:是否只保持一个子菜单的展开。 -## 运行时配置 -在 `app.js` 中配置: -```js -import UserCenter from '@/components/UserCenter'; -export const layout = { - customHeader: -}; -``` - -### menus -- **类型**:`(defaultMenus: [] )=> Ref | []` + ### switch +- **类型**:`Object` -- **详情**:运行时修改菜单,入参是默认菜单配置(.fes.js中的menu配置),需要返回一个`Ref`或者数组。 +- **默认值**:`{ logo: true, sidebar: true, header: true }` -```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` +- **详情**:布局的开关: -- **默认值**:`true` - -- **详情**:是否显示 header 区域。 - -### sidebar -- **类型**:`String` + - **logo**:是否展示logo区域。 -- **默认值**:`true` + - **sidebar**:配置默认展开的菜单,需要传子项是菜单路径的数组。 -- **详情**:是否显示 sidebar 区域。 + - **header**:是否只保持一个子菜单的展开。 -### logo -- **类型**:`String` +### sideWidth +- **类型**:`Number` -- **默认值**:`true` +- **默认值**:`200` -- **详情**:是否显示 logo 区域。 +- **详情**:sidebar的宽度 + -### customHeader -- **类型**:Vue Component +### renderHeader +- **类型**: `()=> VNodes` - **默认值**:`null` -- **详情**:top的区域部分位置提供组件自定义功能。 +- **详情**: 自定义`top`区域部分位置,仅运行时。 + ### unAccessHandler -- **类型**:`Function` +- **类型**:`({ to, from, next})=> void` - **默认值**:`null` -- **详情**: - - 当进入某个路由时,如果路由对应的页面不属于可见资源列表,则会暂停进入,调用 `unAccessHandler` 函数。 +- **详情**:仅运行时,当进入某个路由时,如果路由对应的页面不属于可见资源列表,则会暂停进入,调用 `unAccessHandler` 函数。 - **参数** - router:createRouter 创建的路由实例 - to: 准备进入的路由 @@ -334,13 +342,11 @@ export const access = { ``` ### noFoundHandler -- **类型**:函数 +- **类型**:`({ to, from, next})=> void` -- **默认值**:null +- **默认值**:`null` -- **详情**: - - 当进入某个路由时,如果路由对应的页面不存在,则会调用 `noFoundHandler` 函数。 +- **详情**:仅运行时,当进入某个路由时,如果路由对应的页面不存在,则会调用 `noFoundHandler` 函数。 - **参数** - router:createRouter 创建的路由实例 - to: 准备进入的路由 @@ -360,14 +366,3 @@ export const access = { }; ``` - -### logoUrl -- **类型**:`String` - -- **默认值**:默认提供 fes.js 的 Logo - -- **详情**:Logo的链接。 - - -### 其他运行时配置 (> 4.1.0) -编译时配置的内容同样支持在运行时配置,但是`logo`除外,用`logoUrl`替代。 \ No newline at end of file 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..61271e73 --- /dev/null +++ b/packages/fes-plugin-layout/src/runtime/index.js @@ -0,0 +1,3 @@ +import page from './views/page.vue'; + +export const Page = page; 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/scripts/build.mjs b/scripts/build.mjs index 58c7e3ee..39eee819 100644 --- a/scripts/build.mjs +++ b/scripts/build.mjs @@ -104,13 +104,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); }