mirror of
https://github.com/WeBankFinTech/fes.js.git
synced 2025-04-06 03:59:53 +08:00
Compare commits
No commits in common. "master" and "v3.1.6" have entirely different histories.
4
.eslintignore
Normal file
4
.eslintignore
Normal file
@ -0,0 +1,4 @@
|
||||
**/*.ts
|
||||
|
||||
lib
|
||||
node_modules
|
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -31,8 +31,5 @@
|
||||
"source": "./fixtures/output/**/*.*",
|
||||
"target": "./fixtures/input/<base>"
|
||||
}
|
||||
],
|
||||
"cSpell.words": [
|
||||
"unref"
|
||||
]
|
||||
}
|
||||
|
1345
CHANGELOG.md
1345
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
@ -97,17 +97,15 @@ npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## Project Demo
|
||||
## Start On Cloud IDE
|
||||
|
||||
| Project | Description |
|
||||
|----------------------------------------- | ----------------------------------------- |
|
||||
| <img src="https://docs.icegl.cn/logo.png" width="100px"> | [threejs webgl three three.js tres.js tvt.js](https://gitee.com/ice-gl/icegl-three-vue-tres) |
|
||||
[https://idegithub.com/WeBankFinTech/fes.js](https://idegithub.com/WeBankFinTech/fes.js)
|
||||
|
||||
## Feedback
|
||||
|
||||
| Github Issue | WeChat group | Fes.js 开源运营小助手 |
|
||||
| ------------------------------------ | --------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
|
||||
| [@fesjs/fes.js/issues](../../issues) | <img src="https://wanchun-1252303708.cos.ap-nanjing.myqcloud.com/WeChatb7bcfb33e47b8949ced831b8e79ffb0b.jpg" height="250"/> |
|
||||
| [@fesjs/fes.js/issues](../../issues) | <img src="https://i.loli.net/2020/09/11/2XhKtPZd6NFVbDE.png" width="250" /> | <img src="https://i.loli.net/2020/09/16/sxwr62CKhmYOUyV.jpg" height="250"/> |
|
||||
|
||||
## Contributing
|
||||
|
||||
@ -129,4 +127,4 @@ In order for the Fes.js open source project to run better, and to give back to t
|
||||
|
||||
The output of experience can also help your system accumulate your own projects, sort out your work ideas, and also help your technology blog to promote. Good practice cases will have the opportunity to be invited to participate in the project community technical meeting to share, hurry up and participate.
|
||||
|
||||
Please stamp: <https://mp.weixin.qq.com/s/nV4NG_OUUrdgtft8g_IW4g>
|
||||
Please stamp: https://mp.weixin.qq.com/s/nV4NG_OUUrdgtft8g_IW4g
|
||||
|
14
README.md
14
README.md
@ -8,7 +8,7 @@
|
||||
|
||||
<div align="center">
|
||||
|
||||
一个好用的前端应用解决方案
|
||||
一个优秀的前端解决方案
|
||||
|
||||
[](../../issues)
|
||||
[](http://opensource.org/licenses/MIT)
|
||||
@ -99,19 +99,15 @@ npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## 项目样例
|
||||
## 在 Cloud IDE 中预览
|
||||
|
||||
使用 fes.js 构建的优秀项目,欢迎联系。
|
||||
|
||||
| 项目 | 描述 |
|
||||
|----------------------------------------- | ----------------------------------------- |
|
||||
| <img src="https://docs.icegl.cn/logo.png" width="100px"> | [三维可视化项目快速落地の开源框架](https://gitee.com/ice-gl/icegl-three-vue-tres) |
|
||||
[https://idegithub.com/WeBankFinTech/fes.js](https://idegithub.com/WeBankFinTech/fes.js)
|
||||
|
||||
## 反馈
|
||||
|
||||
| Github Issue | Fes.js 开源运营小助手 |
|
||||
| ------------------------------------ | ------------------------------------------------------------------------------------------------ |
|
||||
| [@fesjs/fes.js/issues](../../issues) | <img src="https://wanchun-1252303708.cos.ap-nanjing.myqcloud.com/WeChatb7bcfb33e47b8949ced831b8e79ffb0b.jpg" height="250"/> |
|
||||
| [@fesjs/fes.js/issues](../../issues) | <img src="https://cos-1254145788.cos.ap-guangzhou.myqcloud.com/WechatIMG104.jpeg" height="250"/> |
|
||||
|
||||
## 参与共建
|
||||
|
||||
@ -132,4 +128,4 @@ npm run dev
|
||||
为了 Fes.js 开源项目更好的运转,同时回馈开源社区,社区推出有奖征文活动!欢迎大家投递实践经验,给社区用户,更广泛的开发者提供借鉴。
|
||||
|
||||
经验输出也可以帮助到你系统沉淀自有项目,梳理工作思路,也能够帮助你的技术博客做宣传。优秀的实践案例将有机会邀请参与项目社区技术会议分享,赶快来参与吧。
|
||||
请戳:<https://mp.weixin.qq.com/s/nV4NG_OUUrdgtft8g_IW4g>
|
||||
请戳:https://mp.weixin.qq.com/s/nV4NG_OUUrdgtft8g_IW4g
|
||||
|
@ -1,3 +1,4 @@
|
||||
|
||||
export const zh = {
|
||||
'/guide/': [
|
||||
{
|
||||
@ -5,12 +6,12 @@ export const zh = {
|
||||
items: [
|
||||
{
|
||||
text: '介绍',
|
||||
link: '/guide/index.md',
|
||||
link: '/guide/index.md'
|
||||
},
|
||||
{
|
||||
text: '快速上手',
|
||||
link: '/guide/getting-started.md',
|
||||
},
|
||||
link: '/guide/getting-started.md'
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
@ -18,44 +19,35 @@ export const zh = {
|
||||
items: [
|
||||
{
|
||||
text: '目录结构',
|
||||
link: '/guide/directory-structure.md',
|
||||
},
|
||||
{
|
||||
link: '/guide/directory-structure.md'
|
||||
},{
|
||||
text: 'Vite 和 Webpack 双构建',
|
||||
link: '/guide/builder.md',
|
||||
},
|
||||
{
|
||||
link: '/guide/builder.md'
|
||||
},{
|
||||
text: '编译时配置',
|
||||
link: '/guide/config.md',
|
||||
},
|
||||
{
|
||||
link: '/guide/config.md'
|
||||
},{
|
||||
text: '运行时配置',
|
||||
link: '/guide/runtime-config.md',
|
||||
},
|
||||
{
|
||||
link: '/guide/runtime-config.md'
|
||||
},{
|
||||
text: '环境变量',
|
||||
link: '/guide/env.md',
|
||||
},
|
||||
{
|
||||
link: '/guide/env.md'
|
||||
},{
|
||||
text: '路由',
|
||||
link: '/guide/route.md',
|
||||
},
|
||||
{
|
||||
link: '/guide/route.md'
|
||||
},{
|
||||
text: '插件',
|
||||
link: '/guide/plugin.md',
|
||||
},
|
||||
{
|
||||
link: '/guide/plugin.md'
|
||||
},{
|
||||
text: 'HTML 模板',
|
||||
link: '/guide/template.md',
|
||||
},
|
||||
{
|
||||
link: '/guide/template.md'
|
||||
},{
|
||||
text: 'Mock 数据',
|
||||
link: '/guide/mock.md',
|
||||
},
|
||||
{
|
||||
text: '从 2.x 迁移到 3.x',
|
||||
link: '/guide/upgrade3.md',
|
||||
},
|
||||
link: '/guide/mock.md'
|
||||
},{
|
||||
text: '从 2.0.x 迁移到 3.0.x',
|
||||
link: '/guide/upgrade3.md'
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
@ -63,102 +55,102 @@ export const zh = {
|
||||
items: [
|
||||
{
|
||||
text: '使用图片',
|
||||
link: '/guide/image.md',
|
||||
link: '/guide/image.md'
|
||||
},
|
||||
{
|
||||
text: '使用 css',
|
||||
link: '/guide/css.md',
|
||||
link: '/guide/css.md'
|
||||
},
|
||||
{
|
||||
text: '静态资源',
|
||||
link: '/guide/public.md',
|
||||
},
|
||||
link: '/guide/public.md'
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
text: '贡献指南',
|
||||
link: '/guide/contributing.md',
|
||||
link: '/guide/contributing.md'
|
||||
},
|
||||
{
|
||||
text: '常见问题',
|
||||
link: '/guide/faq.md',
|
||||
link: '/guide/faq.md'
|
||||
},
|
||||
],
|
||||
'/reference/plugin/': [
|
||||
{
|
||||
text: '介绍',
|
||||
link: '/reference/plugin/index.md',
|
||||
link: '/reference/plugin/index.md'
|
||||
},
|
||||
{
|
||||
text: 'Plugins',
|
||||
items: [
|
||||
{
|
||||
text: '@fesjs/plugin-access',
|
||||
link: '/reference/plugin/plugins/access.md',
|
||||
link: '/reference/plugin/plugins/access.md'
|
||||
},
|
||||
{
|
||||
text: '@fesjs/plugin-enums',
|
||||
link: '/reference/plugin/plugins/enums.md',
|
||||
link: '/reference/plugin/plugins/enums.md'
|
||||
},
|
||||
{
|
||||
text: '@fesjs/plugin-icon',
|
||||
link: '/reference/plugin/plugins/icon.md',
|
||||
link: '/reference/plugin/plugins/icon.md'
|
||||
},
|
||||
{
|
||||
text: '@fesjs/plugin-jest',
|
||||
link: '/reference/plugin/plugins/jest.md',
|
||||
link: '/reference/plugin/plugins/jest.md'
|
||||
},
|
||||
{
|
||||
text: '@fesjs/plugin-layout',
|
||||
link: '/reference/plugin/plugins/layout.md',
|
||||
link: '/reference/plugin/plugins/layout.md'
|
||||
},
|
||||
{
|
||||
text: '@fesjs/plugin-locale',
|
||||
link: '/reference/plugin/plugins/locale.md',
|
||||
link: '/reference/plugin/plugins/locale.md'
|
||||
},
|
||||
{
|
||||
text: '@fesjs/plugin-model',
|
||||
link: '/reference/plugin/plugins/model.md',
|
||||
link: '/reference/plugin/plugins/model.md'
|
||||
},
|
||||
{
|
||||
text: '@fesjs/plugin-request',
|
||||
link: '/reference/plugin/plugins/request.md',
|
||||
link: '/reference/plugin/plugins/request.md'
|
||||
},
|
||||
{
|
||||
text: '@fesjs/plugin-vuex',
|
||||
link: '/reference/plugin/plugins/vuex.md',
|
||||
link: '/reference/plugin/plugins/vuex.md'
|
||||
},
|
||||
{
|
||||
text: '@fesjs/plugin-qiankun',
|
||||
link: '/reference/plugin/plugins/qiankun.md',
|
||||
link: '/reference/plugin/plugins/qiankun.md'
|
||||
},
|
||||
{
|
||||
text: '@fesjs/plugin-windicss',
|
||||
link: '/reference/plugin/plugins/windicss.md',
|
||||
link: '/reference/plugin/plugins/windicss.md'
|
||||
},
|
||||
{
|
||||
text: '@fesjs/plugin-sass',
|
||||
link: '/reference/plugin/plugins/sass.md',
|
||||
link: '/reference/plugin/plugins/sass.md'
|
||||
},
|
||||
{
|
||||
text: '@fesjs/plugin-editor',
|
||||
link: '/reference/plugin/plugins/editor.md',
|
||||
link: '/reference/plugin/plugins/editor.md'
|
||||
},
|
||||
{
|
||||
text: '@fesjs/plugin-pinia',
|
||||
link: '/reference/plugin/plugins/pinia.md',
|
||||
link: '/reference/plugin/plugins/pinia.md'
|
||||
},
|
||||
{
|
||||
text: '@fesjs/plugin-watermark',
|
||||
link: '/reference/plugin/plugins/watermark.md',
|
||||
link: '/reference/plugin/plugins/watermark.md'
|
||||
},
|
||||
{
|
||||
text: '@fesjs/plugin-login',
|
||||
link: '/reference/plugin/plugins/login.md',
|
||||
link: '/reference/plugin/plugins/login.md'
|
||||
},
|
||||
{
|
||||
text: '@fesjs/plugin-swc',
|
||||
link: '/reference/plugin/plugins/swc.md',
|
||||
link: '/reference/plugin/plugins/swc.md'
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -166,10 +158,10 @@ export const zh = {
|
||||
text: '插件开发',
|
||||
items: [{
|
||||
text: '插件介绍',
|
||||
link: '/reference/plugin/dev/index.md',
|
||||
link: '/reference/plugin/dev/index.md'
|
||||
}, {
|
||||
text: '插件API',
|
||||
link: '/reference/plugin/dev/api.md',
|
||||
link: '/reference/plugin/dev/api.md'
|
||||
}],
|
||||
},
|
||||
],
|
||||
|
@ -6,12 +6,12 @@ import { withBase } from 'vitepress'
|
||||
|
||||
## 依赖环境
|
||||
|
||||
首先得有 [Node.js](https://nodejs.org/),并确保 node 版本是 `v18.12.0` 或以上。
|
||||
首先得有 [Node.js](https://nodejs.org/),并确保 node 版本是 12.13 或以上。
|
||||
|
||||
```bash
|
||||
# 打印 node 版本
|
||||
node -v
|
||||
v18.12.0
|
||||
v12.13.0
|
||||
```
|
||||
|
||||
推荐使用 [pnpm](https://pnpm.io/installation) 管理 npm 依赖
|
||||
|
@ -1,29 +1,28 @@
|
||||
# 从 2.x 迁移到 3.x
|
||||
# 从 2.0.x 迁移到 3.0.x
|
||||
|
||||
## 版本 3.x 的 break
|
||||
## 版本 3.0.x 的 break
|
||||
|
||||
1. 环境要求 `node >= v18.12.0`
|
||||
2. 编译时的 [base](../reference/config/index.md/#base) 配置,移到了 [router.base](../reference/config/index.md/#router) 下
|
||||
3. [webpack-dev-server](https://github.com/webpack/webpack-dev-server) 从 `v3.x` 升级到了 `v5.x`,如果遇到配置不兼容,可以查看[webpack-dev-server 3.x 升级 4.x](https://github.com/webpack/webpack-dev-server/blob/master/migration-v4.md)、[webpack-dev-server 4.x 升级 5.x](https://github.com/webpack/webpack-dev-server/blob/master/migration-v5.md)
|
||||
4. [layout 插件](../reference/plugin/plugins/layout.md#_4-x-升级到-5-x) 有一些属性变更
|
||||
5. [request 插件](../reference/plugin/plugins/request.md#_2-x-升级到-3-x) 有一些参数变更,升级请使用最新版本
|
||||
1. 编译时的 [base](../reference/config/index.md/#base) 配置,移到了 [router.base](../reference/config/index.md/#router) 下。
|
||||
2. [webpack-dev-server](https://github.com/webpack/webpack-dev-server) 从 `v3.x` 升级到了 `v4.x`,如果遇到配置不兼容,可以查看[webpack-dev-server 3.x 升级 4.x](https://github.com/webpack/webpack-dev-server/blob/master/migration-v4.md)。
|
||||
3. [layout 插件](../reference/plugin/plugins/layout.md#_4-x-升级到-5-x) 有一些属性变更
|
||||
3. [request 插件](../reference/plugin/plugins/request.md#_2-x-升级到-3-x) 有一些参数变更
|
||||
|
||||
## 继续使用 Webpack
|
||||
|
||||
1. 添加 Webpack 构建依赖包: `npm i @fesjs/builder-webpack -D`
|
||||
2. `dev` 的 `publicPath` 配置不能为 `./`,请更改为 `auto`
|
||||
3. 将 html 模版文件从 `public/index.html` 挪到项目根目录,移除 [html-webpack-plugin](https://github.com/jantimon/html-webpack-plugin) 相关配置,具体模版变量使用请查看[HTML 模版](../guide/template.html)
|
||||
1. 添加 Webpack 构建依赖包: `npm i @fesjs/builder-webpack -D`。
|
||||
2. 如果设置了 `publicPath: './'`,请更改为 `publicPath: ''`
|
||||
3. 如果有,将 `public/index.html` 文件挪到项目根目录,移除 [html-webpack-plugin](https://github.com/jantimon/html-webpack-plugin) 相关配置,具体模版变量使用请查看[HTML 模版](../guide/template.html)。
|
||||
|
||||
## 换成 Vite
|
||||
|
||||
1. 安装依赖包 `npm i @fesjs/builder-vite`
|
||||
2. 将 Webpack 相关的配置换成 Vite,具体可查看[配置](../reference/config/index.md)
|
||||
3. 将 html 模版文件从 `public/index.html` 挪到项目根目录,如果有相应的 [html-webpack-plugin](https://github.com/jantimon/html-webpack-plugin) 配置,需要改成 [vite-plugin-html](https://github.com/vbenjs/vite-plugin-html) 的写法
|
||||
4. 将 `require` 等 Vite 不支持的代码,改写成 Vite 支持的方式
|
||||
1. 安装依赖包 `npm i @fesjs/builder-vite`。
|
||||
2. 将 Webpack 相关的配置换成 Vite,具体可查看[配置](../reference/config/index.md)。
|
||||
3. 将 html 模版文件从 `public/index.html` 挪到项目根目录,如果有相应的 [html-webpack-plugin](https://github.com/jantimon/html-webpack-plugin) 配置,需要改成 [vite-plugin-html](https://github.com/vbenjs/vite-plugin-html) 的写法。
|
||||
4. 将 `require` 等 Vite 不支持的代码,改写成 Vite 支持的方式。
|
||||
|
||||
## 插件
|
||||
|
||||
插件都需要升级到 `3.x` 版本,新版添加了兼容`builder`的逻辑,但是提供的接口和配置没有变化,只需要升级版本即可使用。
|
||||
插件都需要升级到 `3.0.x` 版本,新版添加了兼容`builder`的逻辑,但是提供的接口和配置没有变化,只需要升级版本即可使用。
|
||||
|
||||
- [@fesjs/plugin-layout](../reference/plugin/plugins/layout.md) 需要升级到`5.0.x`版本。
|
||||
- [@fesjs/plugin-locale](../reference/plugin/plugins/locale.md) 需要升级到`4.0.x`版本。
|
||||
|
@ -64,6 +64,6 @@ npm run dev
|
||||
|
||||
| Github Issue | Fes.js 开源运营小助手 |
|
||||
| ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
|
||||
| [@fesjs/fes.js/issues](https://github.com/WeBankFinTech/fes.js/issues) | <img src="https://wanchun-1252303708.cos.ap-nanjing.myqcloud.com/WeChatb7bcfb33e47b8949ced831b8e79ffb0b.jpg" height="250"/> |
|
||||
| [@fesjs/fes.js/issues](https://github.com/WeBankFinTech/fes.js/issues) | <img src="https://cos-1254145788.cos.ap-guangzhou.myqcloud.com/WechatIMG104.jpeg" height="250"/> |
|
||||
|
||||
</HomeContent>
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 58 KiB |
@ -93,22 +93,6 @@ export default {
|
||||
};
|
||||
```
|
||||
|
||||
### console
|
||||
|
||||
- 类型: `object`
|
||||
- 默认值:`{}`
|
||||
- 详情:
|
||||
用于控制应用启动的时候在 console 中打印的信息,目前仅支持 version
|
||||
- 示例:
|
||||
|
||||
```js
|
||||
export default {
|
||||
console: {
|
||||
version: true
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### define
|
||||
|
||||
- 类型: `object`
|
||||
|
@ -9,7 +9,7 @@ import { withBase } from 'vitepress'
|
||||
为了进一步降低研发成本,我们将布局利用 `fes.js` 插件的方式内置,只需通过简单的配置即可拥有布局,包括导航以及侧边栏。从而做到用户无需关心布局。
|
||||
|
||||
- 侧边栏菜单数据根据路由中的配置自动生成。
|
||||
- 布局,提供 `side`、 `top`、`mixin`、`left-right`、`top-left-right` 五种布局。
|
||||
- 布局,提供 `side`、 `top`、`mixin`、`left-right` 四种布局。
|
||||
- 主题,提供 `light`、`dark` 两种主题。
|
||||
- 默认实现对路由的 404、403 处理。
|
||||
- 搭配 [@fesjs/plugin-access](./access.html) 插件使用,可以完成对路由的权限控制。
|
||||
@ -34,7 +34,7 @@ import { withBase } from 'vitepress'
|
||||
|
||||
## 布局类型
|
||||
|
||||
配置参数是 `navigation`, 布局有五种类型 `side`、`mixin` 、`top` 、`left-right`、`top-left-right`, 默认是 `side`。
|
||||
配置参数是 `navigation`, 布局有三种类型 `side`、`mixin` 、`top` 和 `left-right`, 默认是 `side`。
|
||||
|
||||
### side
|
||||
|
||||
@ -53,12 +53,9 @@ import { withBase } from 'vitepress'
|
||||
|
||||
### left-right
|
||||
|
||||
<!--  -->
|
||||
<!--  -->
|
||||
<img :src="withBase('left-right.png')" alt="left-right">
|
||||
|
||||
<!--  -->
|
||||
<img :src="withBase('top-left-right.png')" alt="top-left-right">
|
||||
|
||||
### 页面个性化
|
||||
|
||||
可以为页面单独设置布局类型:
|
||||
@ -130,14 +127,7 @@ export default {
|
||||
}, {
|
||||
name: 'simpleList'
|
||||
}],
|
||||
// 403 页面配置
|
||||
403: {
|
||||
title: '没有访问权限,请联系管理人员',
|
||||
},
|
||||
// 404 页面配置
|
||||
404: {
|
||||
title: '哎呀!这个页面找不到了',
|
||||
}
|
||||
|
||||
},
|
||||
};
|
||||
```
|
||||
@ -233,7 +223,7 @@ export function layout(layoutConfig, { initialState }) {
|
||||
- **类型**:`String`
|
||||
- **默认值**:默认为 [编译时配置 title](../../../reference/config/#title)
|
||||
|
||||
- **详情**:产品名,当配置为"$"开头时,开启国际化,使用`$`后面的内容去匹配语言设置。
|
||||
- **详情**:产品名。
|
||||
|
||||
### logo
|
||||
|
||||
@ -253,7 +243,7 @@ export const layout = {
|
||||
- **类型**:`boolean`
|
||||
- **默认值**:`false`
|
||||
|
||||
- **详情**:是否开启多页。可通过 tabReload: false 控制标签页是否重新加载。
|
||||
- **详情**:是否开启多页。
|
||||
|
||||
### menus
|
||||
|
||||
@ -268,10 +258,6 @@ export const layout = {
|
||||
|
||||
- **path**:菜单的路径,可配置第三方地址。
|
||||
|
||||
- **query**:同 vue-router 的 query 参数。
|
||||
|
||||
- **params**:同 vue-router 的 params 参数。
|
||||
|
||||
- **match (v4.0.0+)**:额外匹配的路径,当前路由命中匹配规则时,此菜单高亮。
|
||||
|
||||
```
|
||||
@ -300,7 +286,6 @@ export const layout = {
|
||||
```
|
||||
|
||||
- **children**:子菜单配置。
|
||||
- **_blank**:是否在新的窗口打开页面,默认 http 开头的链接在新窗口打开
|
||||
|
||||
:::tip
|
||||
函数类型仅在运行时可用,可以实现动态变更菜单。
|
||||
@ -391,7 +376,7 @@ export const layout = {
|
||||
|
||||
## API
|
||||
|
||||
### useTabTitle(建议使用useLayout)
|
||||
### useTabTitle
|
||||
|
||||
类型定义如下:
|
||||
|
||||
@ -412,18 +397,6 @@ titleRef.value = 'changed';
|
||||
</script>
|
||||
```
|
||||
|
||||
### useLayout
|
||||
|
||||
类型定义如下:
|
||||
|
||||
```ts
|
||||
function useLayout(options: { title?: string }): { title: Ref<string>; reloadTab: () => void; closeTab: () => void };
|
||||
```
|
||||
|
||||
- title: 更新当前页签的标题
|
||||
- reloadTab:重载当前页签
|
||||
- closeTab:关闭当前页签
|
||||
|
||||
## 4.x 升级到 5.x
|
||||
|
||||
1. 个性化 layout 配置改为使用传入 navigation
|
||||
|
@ -69,9 +69,11 @@ export default {
|
||||
|
||||
想了解更多语言信息配置、匹配规则,请参考 [Vue I18n](https://vue-i18n.intlify.dev/guide/essentials/syntax.html) 文档。
|
||||
|
||||
### 多层配置
|
||||
|
||||
### 多层配置
|
||||
如果国际化内容较多,希望模块化配置,则可以这样:
|
||||
|
||||
```
|
||||
src
|
||||
├── locales
|
||||
│ ├── zh-CN.js
|
||||
@ -82,7 +84,6 @@ src
|
||||
└── pages
|
||||
│ └── index.vue
|
||||
└── app.js
|
||||
|
||||
```
|
||||
|
||||
插件会把相同语言的配置合并在一起!
|
||||
@ -144,19 +145,7 @@ export default {
|
||||
|
||||
### 运行时配置
|
||||
|
||||
## onLocaleChange
|
||||
|
||||
当语言环境发生变化时,会触发此函数。
|
||||
|
||||
```js
|
||||
import { defineRuntimeConfig } from '@fesjs/fes';
|
||||
|
||||
export default defineRuntimeConfig({
|
||||
onLocaleChange: ({ t, locale }) => {
|
||||
|
||||
}
|
||||
});
|
||||
```
|
||||
暂无。
|
||||
|
||||
## API
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
import antfu from '@antfu/eslint-config';
|
||||
|
||||
export default await antfu({
|
||||
files: ['**/*.js', '**/*.jsx', '**/*.vue', '**/*.ts'],
|
||||
// TODO: 使用 ignore 代替 cli 命令中的配置
|
||||
stylistic: {
|
||||
indent: 4,
|
||||
|
11
package.json
11
package.json
@ -1,9 +1,8 @@
|
||||
{
|
||||
"name": "fes.js",
|
||||
"type": "module",
|
||||
"version": "3.4.11",
|
||||
"version": "3.1.6",
|
||||
"private": true,
|
||||
"packageManager": "pnpm@8.6.6",
|
||||
"description": "一个好用的前端管理台快速开发框架",
|
||||
"preferGlobal": true,
|
||||
"workspaces": [
|
||||
@ -40,18 +39,18 @@
|
||||
"semver": "^7.3.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@antfu/eslint-config": "^3.8.0",
|
||||
"@antfu/eslint-config": "^2.6.2",
|
||||
"@commitlint/cli": "^18.4.4",
|
||||
"@commitlint/config-conventional": "^18.4.4",
|
||||
"chokidar": "^3.5.3",
|
||||
"commitizen": "^4.3.1",
|
||||
"commitizen": "^4.3.0",
|
||||
"cz-conventional-changelog": "^3.3.0",
|
||||
"deepmerge": "^4.2.2",
|
||||
"eslint": "^9.13.0",
|
||||
"eslint": "^8.56.0",
|
||||
"fs-extra": "^11.1.1",
|
||||
"lint-staged": "^15.2.0",
|
||||
"simple-git-hooks": "^2.9.0",
|
||||
"typescript": "^5.6.3",
|
||||
"typescript": "^5.0.4",
|
||||
"vitepress": "1.0.0-alpha.73",
|
||||
"vue": "^3.3.4",
|
||||
"yargs-parser": "^21.1.1"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@fesjs/create-fes-app",
|
||||
"version": "3.0.6",
|
||||
"version": "3.0.2",
|
||||
"description": "create a app base on fes.js",
|
||||
"main": "lib/index.js",
|
||||
"files": [
|
||||
@ -30,7 +30,7 @@
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fesjs/utils": "^3.0.3",
|
||||
"@fesjs/utils": "^3.0.1",
|
||||
"fs-extra": "^11.1.1",
|
||||
"inquirer": "^7.3.3",
|
||||
"readline": "^1.3.0",
|
||||
|
@ -17,8 +17,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@fesjs/fes": "^3.0.0",
|
||||
"@fesjs/plugin-access": "^3.1.9",
|
||||
"@fesjs/plugin-layout": "^5.4.3",
|
||||
"@fesjs/plugin-access": "^3.0.0",
|
||||
"@fesjs/plugin-layout": "^5.0.0",
|
||||
"@fesjs/plugin-model": "^3.0.0",
|
||||
"@fesjs/plugin-enums": "^3.0.0",
|
||||
"@fesjs/fes-design": "^0.8.0",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@fesjs/builder-vite",
|
||||
"version": "4.0.5",
|
||||
"version": "4.0.2",
|
||||
"description": "@fesjs/builder-vite",
|
||||
"author": "qlin",
|
||||
"license": "MIT",
|
||||
@ -25,12 +25,12 @@
|
||||
"access": "public"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@fesjs/fes": "^3.1.12",
|
||||
"@fesjs/fes": "^3.1.8",
|
||||
"core-js": "^3.29.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.23.3",
|
||||
"@fesjs/utils": "^3.0.3",
|
||||
"@fesjs/utils": "^3.0.1",
|
||||
"@rollup/pluginutils": "^5.1.0",
|
||||
"@vitejs/plugin-basic-ssl": "^1.0.2",
|
||||
"@vitejs/plugin-legacy": "^5.2.0",
|
||||
|
@ -25,7 +25,7 @@ export default async (api, args) => {
|
||||
args: {},
|
||||
});
|
||||
|
||||
const isHTTPS = !!(process.env.HTTPS || args.https || api.config.viteOption.server?.https);
|
||||
const isHTTPS = !!(process.env.HTTPS || args.https);
|
||||
|
||||
const bundleConfig = deepmerge(getInnerCommonConfig(api), {
|
||||
mode: 'development',
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@fesjs/builder-webpack",
|
||||
"version": "3.1.0",
|
||||
"version": "3.0.12",
|
||||
"description": "@fesjs/builder-webpack",
|
||||
"author": "qlin",
|
||||
"license": "MIT",
|
||||
@ -26,7 +26,7 @@
|
||||
"access": "public"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@fesjs/fes": "^3.1.17",
|
||||
"@fesjs/fes": "^3.1.10",
|
||||
"core-js": "^3.29.1"
|
||||
},
|
||||
"dependencies": {
|
||||
@ -38,7 +38,7 @@
|
||||
"@babel/plugin-transform-runtime": "^7.23.2",
|
||||
"@babel/preset-env": "^7.23.2",
|
||||
"@babel/preset-typescript": "^7.23.2",
|
||||
"@fesjs/utils": "^3.0.3",
|
||||
"@fesjs/utils": "^3.0.1",
|
||||
"@vue/babel-plugin-jsx": "^1.2.2",
|
||||
"ajv": "^8.12.0",
|
||||
"autoprefixer": "^10.4.14",
|
||||
@ -52,7 +52,7 @@
|
||||
"fs-extra": "^11.1.1",
|
||||
"get-folder-size": "^2.0.1",
|
||||
"html-webpack-plugin": "^5.5.0",
|
||||
"html-webpack-tags-plugin": "^3.0.2",
|
||||
"html-webpack-tags-plugin": "^3.0.0",
|
||||
"less": "^4.1.3",
|
||||
"less-loader": "^11.1.0",
|
||||
"mini-css-extract-plugin": "^2.8.1",
|
||||
@ -66,7 +66,7 @@
|
||||
"webpack": "^5.90.3",
|
||||
"webpack-5-chain": "^8.0.1",
|
||||
"webpack-bundle-analyzer": "^4.4.0",
|
||||
"webpack-dev-server": "^5.1.0",
|
||||
"webpackbar": "^7.0.0"
|
||||
"webpack-dev-server": "^4.15.1",
|
||||
"webpackbar": "^5.0.2"
|
||||
}
|
||||
}
|
||||
|
@ -1,21 +1,13 @@
|
||||
import { extname } from 'node:path';
|
||||
import { extname } from 'path';
|
||||
import historyFallback from 'connect-history-api-fallback';
|
||||
|
||||
const ASSET_EXT_NAMES = ['.ico', '.png', '.jpg', '.jpeg', '.gif', '.svg'];
|
||||
|
||||
function proxyMiddleware(api) {
|
||||
return (req, res, next) => {
|
||||
const proxyMiddleware = (api) => (req, res, next) => {
|
||||
const proxyConfig = api.config.proxy;
|
||||
if (proxyConfig) {
|
||||
if (Array.isArray(proxyConfig)) {
|
||||
if (proxyConfig.some(item => item.context.some(path => path && req.url.startsWith(path)))) {
|
||||
if (proxyConfig && Object.keys(proxyConfig).some((path) => req.url.startsWith(path))) {
|
||||
return next();
|
||||
}
|
||||
}
|
||||
else if (Object.keys(proxyConfig).some(path => req.url.startsWith(path))) {
|
||||
return next();
|
||||
}
|
||||
}
|
||||
if (ASSET_EXT_NAMES.includes(extname(req.url))) {
|
||||
return next();
|
||||
}
|
||||
@ -23,6 +15,5 @@ function proxyMiddleware(api) {
|
||||
const history = historyFallback();
|
||||
history(req, res, next);
|
||||
};
|
||||
}
|
||||
|
||||
export default proxyMiddleware;
|
||||
|
@ -1,23 +1,6 @@
|
||||
import { chalk } from '@fesjs/utils';
|
||||
import webpack from 'webpack';
|
||||
import WebpackDevServer from 'webpack-dev-server';
|
||||
|
||||
function formatProxy(proxy) {
|
||||
if (!proxy) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (Array.isArray(proxy)) {
|
||||
return proxy;
|
||||
}
|
||||
|
||||
return Object.keys(proxy).map((apiPath) => {
|
||||
return {
|
||||
context: [apiPath],
|
||||
...proxy[apiPath],
|
||||
};
|
||||
});
|
||||
}
|
||||
import webpack from 'webpack';
|
||||
import { chalk } from '@fesjs/utils';
|
||||
|
||||
export function startDevServer({ webpackConfig, host, port, proxy, https, beforeMiddlewares, afterMiddlewares, customerDevServerConfig }) {
|
||||
const options = {
|
||||
@ -27,7 +10,6 @@ export function startDevServer({ webpackConfig, host, port, proxy, https, before
|
||||
client: {
|
||||
logging: 'error',
|
||||
overlay: false,
|
||||
progress: true,
|
||||
webSocketURL: {
|
||||
hostname: host,
|
||||
port,
|
||||
@ -45,20 +27,12 @@ export function startDevServer({ webpackConfig, host, port, proxy, https, before
|
||||
...(customerDevServerConfig || {}),
|
||||
port,
|
||||
host,
|
||||
proxy: formatProxy(proxy),
|
||||
proxy,
|
||||
};
|
||||
const compiler = webpack(webpackConfig);
|
||||
const server = new WebpackDevServer(options, compiler);
|
||||
if (options.host === '0.0.0.0') {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(chalk.green(' ➜ Local: '), chalk.cyan(`${options.server}://127.0.0.1:${options.port}`));
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(chalk.gray(' ➜ Network: '), chalk.gray(`${options.server}://${options.host}:${options.port}`));
|
||||
}
|
||||
else {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(chalk.green(' ➜ :Local: '), chalk.cyan(`${options.server}://${options.host}:${options.port}`));
|
||||
}
|
||||
|
||||
console.log(chalk.green('Server: '), chalk.blue(`${options.server}://${options.host}:${options.port}`));
|
||||
server.startCallback((err) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
|
@ -1,6 +1,5 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import process from 'node:process';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import { cleanTmpPathExceptCache, getBundleAndConfigs } from '../../common/buildDevUtils';
|
||||
import connectHistoryMiddleware from './connectHistoryMiddleware';
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { existsSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import webpack from 'webpack';
|
||||
import { existsSync } from 'node:fs';
|
||||
import Config from 'webpack-5-chain';
|
||||
import webpack from 'webpack';
|
||||
import createCssWebpackConfig from './css';
|
||||
import createDefineWebpackConfig from './define';
|
||||
import getBabelOpts from './getBabelOpts';
|
||||
import createHtmlWebpackConfig from './html';
|
||||
import createMinimizerWebpackConfig from './minimizer';
|
||||
import createVueWebpackConfig from './vue';
|
||||
import createDefineWebpackConfig from './define';
|
||||
import createMinimizerWebpackConfig from './minimizer';
|
||||
import createHtmlWebpackConfig from './html';
|
||||
|
||||
const DEFAULT_EXCLUDE_NODE_MODULES = [
|
||||
'vue',
|
||||
@ -124,14 +124,12 @@ export default async function getConfig({ api, cwd, config, env, entry = {}, mod
|
||||
webpackConfig.module
|
||||
.rule('esm')
|
||||
.test(/\.m?jsx?$/)
|
||||
.resolve
|
||||
.set('fullySpecified', false);
|
||||
.resolve.set('fullySpecified', false);
|
||||
|
||||
webpackConfig.module
|
||||
.rule('js')
|
||||
.test(/\.(js|mjs|jsx|ts|tsx)$/)
|
||||
.exclude
|
||||
.add((filepath) => {
|
||||
.exclude.add((filepath) => {
|
||||
// always transpile js in vue files
|
||||
if (/(\.vue|\.jsx)$/.test(filepath)) { return false; }
|
||||
|
||||
@ -149,11 +147,9 @@ export default async function getConfig({ api, cwd, config, env, entry = {}, mod
|
||||
webpackConfig.module
|
||||
.rule('js-in-node_modules')
|
||||
.test(/\.(js|mjs)$/)
|
||||
.include
|
||||
.add(/node_modules/)
|
||||
.include.add(/node_modules/)
|
||||
.end()
|
||||
.exclude
|
||||
.add((filepath) => {
|
||||
.exclude.add((filepath) => {
|
||||
if (transpileDepRegex && transpileDepRegex.test(filepath)) { return true; }
|
||||
|
||||
return false;
|
||||
|
@ -1,25 +1,25 @@
|
||||
{
|
||||
"name": "@fesjs/compiler",
|
||||
"version": "3.0.6",
|
||||
"version": "3.0.2",
|
||||
"description": "@fesjs/compiler",
|
||||
"author": "qlin",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/WeBankFinTech/fes.js#readme",
|
||||
"main": "lib/index.js",
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/WeBankFinTech/fes.js.git",
|
||||
"directory": "packages/fes-compiler"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/WeBankFinTech/fes.js/issues"
|
||||
},
|
||||
"keywords": [
|
||||
"fes"
|
||||
],
|
||||
"main": "lib/index.js",
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"author": "qlin",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/WeBankFinTech/fes.js/issues"
|
||||
},
|
||||
"homepage": "https://github.com/WeBankFinTech/fes.js#readme",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
@ -27,10 +27,11 @@
|
||||
"@babel/core": "^7.23.2",
|
||||
"@babel/preset-env": "^7.23.2",
|
||||
"@babel/register": "^7.22.15",
|
||||
"@fesjs/utils": "^3.0.3",
|
||||
"@fesjs/utils": "^3.0.1",
|
||||
"commander": "^7.0.0",
|
||||
"dotenv": "8.2.0",
|
||||
"joi": "17.3.0",
|
||||
"set-value": "3.0.2",
|
||||
"tapable": "^2.2.0"
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,17 @@
|
||||
import { lodash } from '@fesjs/utils';
|
||||
import set from 'set-value';
|
||||
|
||||
export function updateUserConfigWithKey({
|
||||
key,
|
||||
value,
|
||||
userConfig,
|
||||
userConfig
|
||||
}) {
|
||||
lodash.set(userConfig, key, value);
|
||||
set(userConfig, key, value);
|
||||
}
|
||||
|
||||
export function getUserConfigWithKey({
|
||||
key,
|
||||
userConfig,
|
||||
userConfig
|
||||
}) {
|
||||
return lodash.get(userConfig, key);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@fesjs/plugin-access",
|
||||
"version": "3.1.9",
|
||||
"version": "3.1.4",
|
||||
"description": "@fesjs/plugin-access",
|
||||
"main": "lib/index.js",
|
||||
"files": [
|
||||
@ -28,11 +28,11 @@
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fesjs/utils": "^3.0.3",
|
||||
"@fesjs/utils": "^3.0.1",
|
||||
"lodash-es": "^4.17.21"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@fesjs/fes": "^3.1.13",
|
||||
"@fesjs/fes": "^3.1.9",
|
||||
"vue": "^3.2.47",
|
||||
"vue-router": "^4.0.1"
|
||||
},
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { computed, reactive, unref } from "vue";
|
||||
import { isPlainObject } from "{{{ lodashPath }}}";
|
||||
import createComponent from "./createComponent";
|
||||
import { reactive, unref, computed, inject } from "vue";
|
||||
import createDirective from "./createDirective";
|
||||
import createComponent from "./createComponent";
|
||||
import {isPlainObject} from "{{{ lodashPath }}}";
|
||||
|
||||
function isPromise(obj) {
|
||||
return (
|
||||
@ -20,23 +20,12 @@ const state = reactive({
|
||||
const rolePromiseList = [];
|
||||
const accessPromiseList = [];
|
||||
|
||||
// 预设的 accessId,且不会被移除
|
||||
const presetAccessIds = []
|
||||
const setPresetAccess = (access) => {
|
||||
const accessIds = Array.isArray(access) ? access : [access];
|
||||
|
||||
presetAccessIds.push(...accessIds.filter(id => !presetAccessIds.includes(id)));
|
||||
}
|
||||
|
||||
const getAllowAccessIds = () => {
|
||||
const result = [...presetAccessIds, ...state.currentAccessIds];
|
||||
|
||||
const roleAccessIds = state.roles[state.currentRoleId];
|
||||
if (Array.isArray(roleAccessIds) && roleAccessIds.length > 0) {
|
||||
result.push(...roleAccessIds);
|
||||
return state.currentAccessIds.concat(roleAccessIds);
|
||||
}
|
||||
|
||||
return result;
|
||||
return state.currentAccessIds;
|
||||
};
|
||||
|
||||
const _syncSetAccessIds = (promise) => {
|
||||
@ -145,13 +134,8 @@ export const install = (app) => {
|
||||
app.component("Access", createComponent(useAccess));
|
||||
};
|
||||
|
||||
export const hasAccessSync = (path) => {
|
||||
return match(unref(path), getAllowAccessIds());
|
||||
}
|
||||
|
||||
export const access = {
|
||||
hasAccess,
|
||||
hasAccessSync,
|
||||
isDataReady,
|
||||
setRole,
|
||||
getRole: () => {
|
||||
@ -160,9 +144,12 @@ export const access = {
|
||||
setAccess,
|
||||
match,
|
||||
getAccess: getAllowAccessIds,
|
||||
setPresetAccess,
|
||||
};
|
||||
|
||||
export const hasAccessSync = (path) => {
|
||||
return match(unref(path), getAllowAccessIds());
|
||||
}
|
||||
|
||||
export const useAccess = (path) => {
|
||||
const allowPageIds = computed(getAllowAccessIds);
|
||||
const result = computed(() => {
|
||||
|
@ -13,10 +13,7 @@ export default function createDirective(useAccess) {
|
||||
beforeMount(el) {
|
||||
const ctx = {};
|
||||
ctx.watch = (path) => {
|
||||
// el._display = el._display || el.style.display; // 这种只能获取到行内样式 会导致保存不了组件加载时的初始display
|
||||
if (!el._display) {
|
||||
el._display = window.getComputedStyle(el).display
|
||||
}
|
||||
el._display = el._display || el.style.display;
|
||||
const access = useAccess(path);
|
||||
setDisplay(el, access);
|
||||
return watch(access, () => {
|
||||
|
4
packages/fes-plugin-access/types.d.ts
vendored
4
packages/fes-plugin-access/types.d.ts
vendored
@ -3,14 +3,10 @@ import type { Ref } from 'vue';
|
||||
|
||||
export const access: {
|
||||
hasAccess: (accessId: string | number) => Promise<boolean>;
|
||||
hasAccessSync: (accessId: string | number) => boolean;
|
||||
isDataReady: () => boolean;
|
||||
setRole: (roleId: string | Promise<string>) => void;
|
||||
getRole: () => string;
|
||||
setAccess: (accessIds: Array<string | number> | Promise<Array<string | number>>) => void;
|
||||
getAccess: () => string[];
|
||||
match: (path: string, accessIds: string[]) => boolean;
|
||||
setPresetAccess: (accessId: string | string[]) => void;
|
||||
};
|
||||
|
||||
export function useAccess(accessId: string | number): Ref<boolean>;
|
||||
|
@ -1,21 +1,7 @@
|
||||
{
|
||||
"name": "@fesjs/plugin-icon",
|
||||
"version": "4.0.0",
|
||||
"version": "3.0.0",
|
||||
"description": "@fesjs/plugin-icon",
|
||||
"author": "qlin",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/WeBankFinTech/fes.js#readme",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/WeBankFinTech/fes.js.git",
|
||||
"directory": "packages/fes-plugin-icon"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/WeBankFinTech/fes.js/issues"
|
||||
},
|
||||
"keywords": [
|
||||
"fes"
|
||||
],
|
||||
"main": "lib/index.js",
|
||||
"files": [
|
||||
"lib",
|
||||
@ -24,6 +10,20 @@
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/WeBankFinTech/fes.js.git",
|
||||
"directory": "packages/fes-plugin-icon"
|
||||
},
|
||||
"keywords": [
|
||||
"fes"
|
||||
],
|
||||
"author": "qlin",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/WeBankFinTech/fes.js/issues"
|
||||
},
|
||||
"homepage": "https://github.com/WeBankFinTech/fes.js#readme",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { basename, extname } from 'node:path';
|
||||
import { readFileSync, statSync } from 'node:fs';
|
||||
import { extname, basename } from 'path';
|
||||
import { statSync, readFileSync } from 'fs';
|
||||
import { optimize } from 'svgo';
|
||||
|
||||
const presetDefault = [
|
||||
@ -15,7 +15,7 @@ const presetDefault = [
|
||||
{
|
||||
name: 'removeAttrs',
|
||||
params: {
|
||||
attrs: '(class)',
|
||||
attrs: '(fill|stroke|class)',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { computed } from 'vue';
|
||||
|
||||
// eslint-disable-next-line
|
||||
import icons from '../icons';
|
||||
|
||||
function noop() {}
|
||||
const noop = () => {};
|
||||
|
||||
export default {
|
||||
name: 'FesIcon',
|
||||
|
@ -29,7 +29,6 @@
|
||||
&[tabindex] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&--spin {
|
||||
display: inline-block;
|
||||
animation: loadingCircle 1s infinite linear;
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@fesjs/plugin-layout",
|
||||
"version": "5.4.6",
|
||||
"version": "5.1.10",
|
||||
"description": "@fesjs/plugin-layout",
|
||||
"author": "harrywan",
|
||||
"license": "MIT",
|
||||
@ -28,15 +28,14 @@
|
||||
"access": "public"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@fesjs/fes": "^3.1.17",
|
||||
"@fesjs/fes": "^3.1.9",
|
||||
"@fesjs/fes-design": ">=0.7.0",
|
||||
"vue": "^3.2.47",
|
||||
"vue-router": "^4.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fesjs/utils": "^3.0.3",
|
||||
"@vueuse/core": "^10.7.0",
|
||||
"dompurify": "^3.1.7"
|
||||
"@fesjs/utils": "^3.0.1",
|
||||
"@vueuse/core": "^10.7.0"
|
||||
},
|
||||
"typings": "./types.d.ts"
|
||||
}
|
||||
|
@ -30,13 +30,6 @@ export default (api) => {
|
||||
|
||||
const absRuntimeFilePath = join(namespace, 'runtime.js');
|
||||
|
||||
api.register({
|
||||
key: 'addExtraLocales',
|
||||
fn: () => [
|
||||
join(api.paths.absTmpPath, namespace, 'locales'),
|
||||
],
|
||||
});
|
||||
|
||||
api.onGenerateFiles(async () => {
|
||||
// .fes配置
|
||||
const userConfig = {
|
||||
@ -122,7 +115,6 @@ export default (api) => {
|
||||
return [
|
||||
{
|
||||
path: '/',
|
||||
name: 'fesLayout',
|
||||
component: winPath(join(api.paths.absTmpPath || '', absFilePath)),
|
||||
children: routes,
|
||||
},
|
||||
|
@ -1,4 +1,4 @@
|
||||
function getMetaByName(config, name) {
|
||||
const getMetaByName = (config, name) => {
|
||||
let res = {};
|
||||
if (Array.isArray(config)) {
|
||||
for (let i = 0; i < config.length; i++) {
|
||||
@ -17,9 +17,9 @@ function getMetaByName(config, name) {
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
function fillMenuByRoute(menuConfig, routeConfig, dep = 0) {
|
||||
const fillMenuByRoute = (menuConfig, routeConfig, dep = 0) => {
|
||||
dep += 1;
|
||||
if (dep > 3) {
|
||||
console.warn('[plugin-layout]: 菜单层级最好不要超出三层!');
|
||||
@ -44,6 +44,6 @@ function fillMenuByRoute(menuConfig, routeConfig, dep = 0) {
|
||||
});
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
};
|
||||
|
||||
export default fillMenuByRoute;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { plugin } from '@@/core/coreExports';
|
||||
|
||||
export function transTitle(name) {
|
||||
export const transTitle = (name) => {
|
||||
if (!/^\$\S+$/.test(name)) {
|
||||
return name;
|
||||
}
|
||||
@ -10,10 +10,10 @@ export function transTitle(name) {
|
||||
return t(name.slice(1));
|
||||
}
|
||||
return name;
|
||||
}
|
||||
};
|
||||
|
||||
export function transform(menus) {
|
||||
return menus.map((menu) => {
|
||||
export const transform = (menus) =>
|
||||
menus.map((menu) => {
|
||||
const copy = {
|
||||
...menu,
|
||||
label: transTitle(menu.label),
|
||||
@ -23,4 +23,3 @@ export function transform(menus) {
|
||||
}
|
||||
return copy;
|
||||
});
|
||||
}
|
||||
|
@ -1,10 +1,8 @@
|
||||
import DOMPurify from 'dompurify';
|
||||
|
||||
const isStr = function (str) {
|
||||
return typeof str === 'string';
|
||||
};
|
||||
|
||||
export function isValid(elm) {
|
||||
export const isValid = (elm) => {
|
||||
if (elm.nodeType === 1) {
|
||||
if (elm.nodeName.toLowerCase() === 'script') {
|
||||
return false;
|
||||
@ -24,11 +22,11 @@ export function isValid(elm) {
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
export function validateContent(svgContent) {
|
||||
export const validateContent = (svgContent) => {
|
||||
const div = document.createElement('div');
|
||||
div.innerHTML = DOMPurify.sanitize(svgContent);
|
||||
div.innerHTML = svgContent;
|
||||
|
||||
// setup this way to ensure it works on our buddy IE
|
||||
for (let i = div.childNodes.length - 1; i >= 0; i--) {
|
||||
@ -48,4 +46,4 @@ export function validateContent(svgContent) {
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
@ -1,9 +1,8 @@
|
||||
export function flatNodes(nodes = []) {
|
||||
return nodes.reduce((res, node) => {
|
||||
export const flatNodes = (nodes = []) =>
|
||||
nodes.reduce((res, node) => {
|
||||
res.push(node);
|
||||
if (node.children) {
|
||||
res = res.concat(flatNodes(node.children));
|
||||
}
|
||||
return res;
|
||||
}, []);
|
||||
}
|
||||
|
@ -1,2 +1,3 @@
|
||||
export { default as Page } from './views/page.vue';
|
||||
export { useTabTitle } from './useTitle';
|
||||
export * from './useLayout';
|
||||
|
@ -1,6 +0,0 @@
|
||||
export default {
|
||||
pluginLayout: {
|
||||
closeOtherPage: 'Close Other Page',
|
||||
reloadPage: 'Reload Page',
|
||||
},
|
||||
};
|
@ -1,6 +0,0 @@
|
||||
export default {
|
||||
pluginLayout: {
|
||||
closeOtherPage: '关闭其他页签',
|
||||
reloadPage: '刷新当前页签',
|
||||
},
|
||||
};
|
@ -8,8 +8,13 @@ if (!accessApi) {
|
||||
|
||||
export const access = (memo) => {
|
||||
const runtimeConfig = getConfig();
|
||||
accessApi.setPresetAccess(['/403', '/404']);
|
||||
|
||||
const accessIds = accessApi.getAccess();
|
||||
if (!accessIds.includes('/403')) {
|
||||
accessApi.setAccess(accessIds.concat('/403'));
|
||||
}
|
||||
if (!accessIds.includes('/404')) {
|
||||
accessApi.setAccess(accessIds.concat('/404'));
|
||||
}
|
||||
return {
|
||||
unAccessHandler({ router, to, from, next }) {
|
||||
if (runtimeConfig.unAccessHandler && typeof runtimeConfig.unAccessHandler === 'function') {
|
||||
|
@ -1,31 +1,12 @@
|
||||
import { inject, ref } from 'vue';
|
||||
import { createSharedComposable } from '@vueuse/core';
|
||||
import { shallowReactive } from 'vue';
|
||||
|
||||
import { useRoute } from '@@/core/coreExports';
|
||||
function _useLayout() {
|
||||
const state = shallowReactive({
|
||||
closeTab: () => {},
|
||||
});
|
||||
|
||||
export const PLUGIN_LAYOUT_TITLE_KEY = Symbol('PLUGIN_LAYOUT_TITLE_KEY');
|
||||
|
||||
export const PLUGIN_LAYOUT_KEY = Symbol('PLUGIN_LAYOUT_KEY');
|
||||
|
||||
export function useTabTitle(title) {
|
||||
const titleMap = inject(PLUGIN_LAYOUT_TITLE_KEY);
|
||||
if (!titleMap) {
|
||||
console.warn('[plugin-layout]: 未正确获取到titleMap');
|
||||
return;
|
||||
}
|
||||
const route = useRoute();
|
||||
const titleRef = ref(title);
|
||||
const path = route.path;
|
||||
|
||||
titleMap.set(path, titleRef);
|
||||
|
||||
return titleRef;
|
||||
return state;
|
||||
}
|
||||
|
||||
export function useLayout(options) {
|
||||
const parent = inject(PLUGIN_LAYOUT_KEY, { reloadTab: () => void 0, closeTab: () => void 0 });
|
||||
const titleRef = useTabTitle(options?.title);
|
||||
return {
|
||||
...parent,
|
||||
title: titleRef,
|
||||
};
|
||||
}
|
||||
export const useLayout = createSharedComposable(_useLayout);
|
||||
|
18
packages/fes-plugin-layout/src/runtime/useTitle.js
Normal file
18
packages/fes-plugin-layout/src/runtime/useTitle.js
Normal file
@ -0,0 +1,18 @@
|
||||
import { reactive, ref } from 'vue';
|
||||
import { useRoute } from '@@/core/coreExports';
|
||||
|
||||
const cache = reactive(new Map());
|
||||
|
||||
export const getTitle = path => cache.get(path);
|
||||
|
||||
export const deleteTitle = patch => cache.delete(patch);
|
||||
|
||||
export function useTabTitle(title) {
|
||||
const route = useRoute();
|
||||
const titleRef = ref(title);
|
||||
const path = route.path;
|
||||
|
||||
cache.set(path, titleRef);
|
||||
|
||||
return titleRef;
|
||||
}
|
@ -1,10 +1,8 @@
|
||||
<template>
|
||||
<Wrapper :icon-src="img403" :title="title" sub-title="" />
|
||||
<Wrapper :iconSrc="img403" title="没有访问权限,请联系管理人员" subTitle="" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { computed, defineComponent } from 'vue';
|
||||
import getConfig from '../helpers/getConfig';
|
||||
import { defineComponent } from 'vue';
|
||||
import img403 from '../assets/403.png';
|
||||
import Wrapper from './components/Wrapper.vue';
|
||||
|
||||
@ -13,13 +11,8 @@ export default defineComponent({
|
||||
Wrapper,
|
||||
},
|
||||
setup() {
|
||||
const config = getConfig();
|
||||
const title = computed(() => {
|
||||
return config['403']?.title || '没有访问权限,请联系管理人员';
|
||||
});
|
||||
return {
|
||||
img403,
|
||||
title,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
@ -1,11 +1,9 @@
|
||||
<template>
|
||||
<Wrapper :icon-src="img404" :title="title" sub-title="" />
|
||||
<Wrapper :iconSrc="img404" title="哎呀!这个页面找不到了" subTitle="" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { computed, defineComponent } from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
import img404 from '../assets/404.png';
|
||||
import getConfig from '../helpers/getConfig';
|
||||
import Wrapper from './components/Wrapper.vue';
|
||||
|
||||
export default defineComponent({
|
||||
@ -13,14 +11,8 @@ export default defineComponent({
|
||||
Wrapper,
|
||||
},
|
||||
setup() {
|
||||
const config = getConfig();
|
||||
const title = computed(() => {
|
||||
return config['404']?.title || '哎呀!这个页面找不到了';
|
||||
});
|
||||
|
||||
return {
|
||||
img404,
|
||||
title,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
@ -11,8 +11,8 @@
|
||||
>
|
||||
<div class="layout-logo">
|
||||
<img v-if="logo" :src="logo" class="logo-img">
|
||||
<div v-if="transformedTitle" class="logo-name">
|
||||
{{ transformedTitle }}
|
||||
<div v-if="title" class="logo-name">
|
||||
{{ title }}
|
||||
</div>
|
||||
</div>
|
||||
<LayoutMenu
|
||||
@ -58,8 +58,8 @@
|
||||
<div>
|
||||
<div class="layout-logo">
|
||||
<img v-if="logo" :src="logo" class="logo-img">
|
||||
<div v-if="transformedTitle" class="logo-name">
|
||||
{{ transformedTitle }}
|
||||
<div v-if="title" class="logo-name">
|
||||
{{ title }}
|
||||
</div>
|
||||
</div>
|
||||
<LayoutMenu
|
||||
@ -98,8 +98,8 @@
|
||||
<FHeader ref="headerRef" class="layout-header" :inverted="theme === 'dark'" :fixed="currentFixedHeaderRef">
|
||||
<div class="layout-logo">
|
||||
<img v-if="logo" :src="logo" class="logo-img">
|
||||
<div v-if="transformedTitle" class="logo-name">
|
||||
{{ transformedTitle }}
|
||||
<div v-if="title" class="logo-name">
|
||||
{{ title }}
|
||||
</div>
|
||||
</div>
|
||||
<LayoutMenu
|
||||
@ -127,65 +127,12 @@
|
||||
</FFooter>
|
||||
</FLayout>
|
||||
</template>
|
||||
<template v-else-if="currentNavigation === 'top-left-right'">
|
||||
<FHeader ref="headerRef" class="layout-header" :inverted="theme === 'dark'" :fixed="currentFixedHeaderRef">
|
||||
<div class="layout-logo">
|
||||
<img v-if="logo" :src="logo" class="logo-img">
|
||||
<div v-if="transformedTitle" class="logo-name">
|
||||
{{ transformedTitle }}
|
||||
</div>
|
||||
</div>
|
||||
<LayoutMenu
|
||||
class="layout-menu"
|
||||
:menus="rootMenus"
|
||||
mode="horizontal"
|
||||
:inverted="theme === 'dark'"
|
||||
/>
|
||||
<div class="layout-header-custom">
|
||||
<slot name="renderCustom" :menus="menus" />
|
||||
</div>
|
||||
<template v-if="locale">
|
||||
<slot name="locale" />
|
||||
</template>
|
||||
</FHeader>
|
||||
<FLayout v-if="activeSubMenus.length" :embedded="!multiTabs" :fixed="currentFixedHeaderRef" :style="headerStyleRef">
|
||||
<FAside v-model:collapsed="collapsedRef" :inverted="theme === 'dark'" :fixed="isFixedSidebar" :width="`${sideWidth}px`" collapsible class="layout-aside">
|
||||
<LayoutMenu
|
||||
class="layout-menu"
|
||||
:menus="activeSubMenus"
|
||||
:collapsed="collapsedRef"
|
||||
mode="vertical"
|
||||
:expanded-keys="menuProps?.expandedKeys"
|
||||
:default-expand-all="menuProps?.defaultExpandAll"
|
||||
:accordion="menuProps?.accordion"
|
||||
:inverted="theme === 'dark'"
|
||||
/>
|
||||
</FAside>
|
||||
|
||||
<FLayout :embedded="!multiTabs" :fixed="isFixedSidebar" :style="sideStyleRef">
|
||||
<FMain class="layout-main">
|
||||
<MultiTabProvider :multi-tabs="multiTabs" />
|
||||
</FMain>
|
||||
<FFooter v-if="footer" class="layout-footer">
|
||||
{{ footer }}
|
||||
</FFooter>
|
||||
</FLayout>
|
||||
</FLayout>
|
||||
<FLayout v-else :embedded="!multiTabs" :fixed="currentFixedHeaderRef" :style="headerStyleRef">
|
||||
<FMain class="layout-main">
|
||||
<MultiTabProvider :multi-tabs="multiTabs" />
|
||||
</FMain>
|
||||
<FFooter v-if="footer" class="layout-footer">
|
||||
{{ footer }}
|
||||
</FFooter>
|
||||
</FLayout>
|
||||
</template>
|
||||
<template v-else-if="currentNavigation === 'mixin'">
|
||||
<FHeader ref="headerRef" class="layout-header" :fixed="currentFixedHeaderRef" :inverted="theme === 'dark'">
|
||||
<div class="layout-logo">
|
||||
<img v-if="logo" :src="logo" class="logo-img">
|
||||
<div v-if="transformedTitle" class="logo-name">
|
||||
{{ transformedTitle }}
|
||||
<div v-if="title" class="logo-name">
|
||||
{{ title }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="layout-header-custom">
|
||||
@ -230,8 +177,6 @@ import { useRoute, useRouter } from '@@/core/coreExports';
|
||||
import { FAside, FFooter, FHeader, FLayout, FMain } from '@fesjs/fes-design';
|
||||
import { computed, nextTick, ref, watch } from 'vue';
|
||||
import defaultLogo from '../assets/logo.png';
|
||||
import { flatNodes } from '../helpers/utils';
|
||||
import { transTitle } from '../helpers/pluginLocale';
|
||||
import LayoutMenu from './Menu.vue';
|
||||
import MultiTabProvider from './MultiTabProvider.vue';
|
||||
|
||||
@ -270,7 +215,7 @@ export default {
|
||||
},
|
||||
navigation: {
|
||||
type: String,
|
||||
default: 'side', // side 左右(上/下)、 top 上/下、 mixin 上/下(左/右)、top-left-right 上/下(左/右)
|
||||
default: 'side', // side 左右(上/下)、 top 上/下、 mixin 上/下(左/右)
|
||||
},
|
||||
navigationOnError: {
|
||||
type: [String, Function], // 403, 404 时的 navigation
|
||||
@ -303,10 +248,6 @@ export default {
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
const transformedTitle = computed(() => {
|
||||
return transTitle(props.title);
|
||||
});
|
||||
|
||||
const currentNavigation = computed(() => {
|
||||
if (route.meta.layout && route.meta.layout.navigation !== undefined) {
|
||||
return route.meta.layout.navigation;
|
||||
@ -341,56 +282,6 @@ export default {
|
||||
},
|
||||
);
|
||||
|
||||
const rootMenus = computed(() => {
|
||||
return props.menus.map((menu) => {
|
||||
const { children, match, ...others } = menu;
|
||||
let { path, query, params } = menu;
|
||||
const flatChildren = flatNodes(children || []);
|
||||
if (!menu.path) {
|
||||
const firstChild = flatChildren.find(item => item.path);
|
||||
if (firstChild) {
|
||||
path = firstChild.path;
|
||||
query = firstChild.query;
|
||||
params = firstChild.params;
|
||||
}
|
||||
}
|
||||
return {
|
||||
...others,
|
||||
path,
|
||||
query,
|
||||
params,
|
||||
match: (match || [])
|
||||
.concat(...flatChildren.map(item => []
|
||||
.concat(item.match || [])
|
||||
.concat(item.path)),
|
||||
),
|
||||
_children: children,
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
const activeRootMenu = computed(() => {
|
||||
const matchRootMenus = rootMenus.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);
|
||||
});
|
||||
});
|
||||
|
||||
return matchRootMenus[0] ?? null;
|
||||
});
|
||||
|
||||
const activeSubMenus = computed(() => {
|
||||
if (!activeRootMenu.value) {
|
||||
return [];
|
||||
}
|
||||
return activeRootMenu.value._children || [];
|
||||
});
|
||||
|
||||
return {
|
||||
headerRef,
|
||||
headerHeightRef,
|
||||
@ -400,9 +291,6 @@ export default {
|
||||
headerStyleRef,
|
||||
sideStyleRef,
|
||||
currentNavigation,
|
||||
rootMenus,
|
||||
activeSubMenus,
|
||||
transformedTitle,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<FMenu
|
||||
v-model:expanded-keys="expandedKeysRef"
|
||||
v-model="activeMenu"
|
||||
v-model:expandedKeys="expandedKeysRef"
|
||||
:model-value="activePath"
|
||||
:inverted="inverted"
|
||||
:mode="mode"
|
||||
:options="transformedMenus"
|
||||
@ -12,9 +12,9 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { useRoute, useRouter } from '@@/core/coreExports';
|
||||
import { computed, h, ref, watch } from 'vue';
|
||||
import { FMenu } from '@fesjs/fes-design';
|
||||
import { computed, h, nextTick, ref, watch } from 'vue';
|
||||
import { useRoute, useRouter } from '@@/core/coreExports';
|
||||
import { transform as transformByAccess } from '../helpers/pluginAccess';
|
||||
import { transform as transformByLocale } from '../helpers/pluginLocale';
|
||||
import { flatNodes } from '../helpers/utils';
|
||||
@ -79,7 +79,6 @@ export default {
|
||||
const router = useRouter();
|
||||
const transformedMenus = computed(() => transformByLocale(transformByAccess(transform(props.menus))));
|
||||
const menuArray = computed(() => flatNodes(transformedMenus.value));
|
||||
|
||||
const activePath = computed(() => {
|
||||
const matchMenus = menuArray.value.filter((menu) => {
|
||||
const match = menu.match;
|
||||
@ -97,12 +96,6 @@ export default {
|
||||
return matchMenus[0].path;
|
||||
});
|
||||
|
||||
const activeMenu = ref(activePath.value);
|
||||
|
||||
watch(activePath, () => {
|
||||
activeMenu.value = activePath.value;
|
||||
});
|
||||
|
||||
const expandedKeysRef = ref(props.expandedKeys);
|
||||
|
||||
watch(
|
||||
@ -132,32 +125,11 @@ export default {
|
||||
|
||||
const onMenuClick = (e) => {
|
||||
const path = e.value;
|
||||
const currentMenu = menuArray.value.find(item => item.value === path);
|
||||
if (currentMenu._blank) {
|
||||
const resolved = router.resolve({
|
||||
path,
|
||||
query: currentMenu?.query || {},
|
||||
params: currentMenu?.params || {},
|
||||
});
|
||||
// TODO 有受控模式之后优化
|
||||
nextTick(() => {
|
||||
activeMenu.value = activePath.value;
|
||||
});
|
||||
window.open(resolved.href, '_blank');
|
||||
}
|
||||
else if (/^https?:\/\//.test(path)) {
|
||||
// TODO 有受控模式之后优化
|
||||
nextTick(() => {
|
||||
activeMenu.value = activePath.value;
|
||||
});
|
||||
if (/^https?:\/\//.test(path)) {
|
||||
window.open(path, '_blank');
|
||||
}
|
||||
else if (/^\//.test(path)) {
|
||||
router.push({
|
||||
path,
|
||||
query: currentMenu?.query || {},
|
||||
params: currentMenu?.params || {},
|
||||
});
|
||||
router.push(path);
|
||||
}
|
||||
else {
|
||||
console.warn('[plugin-layout]: 菜单的path只能是以http(s)开头的网址或者路由地址');
|
||||
@ -165,7 +137,6 @@ export default {
|
||||
};
|
||||
|
||||
return {
|
||||
activeMenu,
|
||||
activePath,
|
||||
expandedKeysRef,
|
||||
transformedMenus,
|
||||
|
@ -1,11 +1,11 @@
|
||||
<script lang="jsx">
|
||||
import { isVNode, onBeforeMount, ref } from 'vue';
|
||||
|
||||
import { ref, onBeforeMount, isVNode } from 'vue';
|
||||
// eslint-disable-next-line import/extensions
|
||||
import Icons from '../icons';
|
||||
import { validateContent } from '../helpers/svg';
|
||||
|
||||
const urlReg = /^((https?|ftp|file):\/\/)?([\da-z.-]+)\.([a-z.]{2,6})([/\w .-]*)*\/?$/;
|
||||
const isUrlResource = name => urlReg.test(name) || name.includes('.svg');
|
||||
const isUrlResource = (name) => urlReg.test(name) || name.includes('.svg');
|
||||
|
||||
export default {
|
||||
props: {
|
||||
@ -25,8 +25,7 @@ export default {
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
AIconComponent.value = Icons[props.icon];
|
||||
}
|
||||
}
|
||||
@ -40,14 +39,13 @@ export default {
|
||||
return <AIconComponent.value />;
|
||||
}
|
||||
if (AText.value) {
|
||||
return <span class="fes-layout-icon" innerHTML={AText.value}></span>;
|
||||
return <span class={'fes-layout-icon'} innerHTML={AText.value}></span>;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.fes-layout-icon {
|
||||
display: inline-block;
|
||||
|
@ -7,12 +7,12 @@
|
||||
type="card"
|
||||
class="layout-content-tabs"
|
||||
@close="handleCloseTab"
|
||||
@update:model-value="switchPage"
|
||||
@update:modelValue="switchPage"
|
||||
>
|
||||
<FTabPane v-for="page in pageList" :key="page.path" :value="page.path" :closable="pageList.length > 1">
|
||||
<template #tab>
|
||||
{{ page.title }}
|
||||
<ReloadOutlined v-if="page.tabReload" v-show="route.path === page.path" class="layout-tabs-close-icon" @click="reloadPage(page.path)" />
|
||||
<ReloadOutlined v-show="route.path === page.path" class="layout-tabs-close-icon" @click="reloadPage(page.path)" />
|
||||
</template>
|
||||
</FTabPane>
|
||||
<template #suffix>
|
||||
@ -27,12 +27,13 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { computed, provide, reactive, ref, unref } from 'vue';
|
||||
import { computed, ref, unref } from 'vue';
|
||||
import { FDropdown, FTabPane, FTabs } from '@fesjs/fes-design';
|
||||
import { MoreOutlined, ReloadOutlined } from '@fesjs/fes-design/icon';
|
||||
import { plugin, useRoute, useRouter } from '@@/core/coreExports';
|
||||
import { useRoute, useRouter } from '@@/core/coreExports';
|
||||
import { transTitle } from '../helpers/pluginLocale';
|
||||
import { PLUGIN_LAYOUT_KEY, PLUGIN_LAYOUT_TITLE_KEY } from '../useLayout';
|
||||
import { deleteTitle, getTitle } from '../useTitle';
|
||||
import { useLayout } from '../useLayout';
|
||||
import Page from './page.vue';
|
||||
|
||||
let i = 0;
|
||||
@ -53,14 +54,7 @@ export default {
|
||||
const pageRef = ref();
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
const titleCache = reactive(new Map());
|
||||
|
||||
provide(PLUGIN_LAYOUT_TITLE_KEY, titleCache);
|
||||
|
||||
const getTitle = path => titleCache.get(path);
|
||||
|
||||
const deleteTitle = patch => titleCache.delete(patch);
|
||||
const layoutState = useLayout();
|
||||
|
||||
const createPage = (_route) => {
|
||||
const computedTitle = computed(() => {
|
||||
@ -73,28 +67,11 @@ export default {
|
||||
name: _route.meta.name ?? _route.name,
|
||||
title: computedTitle,
|
||||
key: getKey(),
|
||||
tabReload: _route.meta.tabReload ?? true,
|
||||
};
|
||||
};
|
||||
|
||||
const pageList = ref([createPage(router.currentRoute.value)]);
|
||||
|
||||
const actions = computed(() => {
|
||||
const sharedLocale = plugin.getShared('locale');
|
||||
if (sharedLocale) {
|
||||
const { t } = sharedLocale.locale;
|
||||
return [
|
||||
{
|
||||
value: 'closeOtherPage',
|
||||
label: t('pluginLayout.closeOtherPage'),
|
||||
},
|
||||
{
|
||||
value: 'reloadPage',
|
||||
label: t('pluginLayout.reloadPage'),
|
||||
},
|
||||
];
|
||||
}
|
||||
return [
|
||||
const actions = [
|
||||
{
|
||||
value: 'closeOtherPage',
|
||||
label: '关闭其他页签',
|
||||
@ -104,19 +81,16 @@ export default {
|
||||
label: '刷新当前页签',
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
const findPage = path => pageList.value.find(item => unref(item.path) === unref(path));
|
||||
|
||||
router.beforeEach((to) => {
|
||||
const page = findPage(to.path);
|
||||
if (!page) {
|
||||
if (!page)
|
||||
pageList.value = [...pageList.value, createPage(to)];
|
||||
}
|
||||
|
||||
else {
|
||||
else
|
||||
page.route = to;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
@ -135,33 +109,28 @@ export default {
|
||||
const handleCloseTab = async (targetKey) => {
|
||||
targetKey = targetKey || route.path;
|
||||
const selectedPage = findPage(targetKey);
|
||||
if (!selectedPage) {
|
||||
return;
|
||||
}
|
||||
const list = [...pageList.value];
|
||||
const index = list.indexOf(selectedPage);
|
||||
if (route.path === selectedPage.path) {
|
||||
if (list.length > 1) {
|
||||
if (list.length - 1 === index) {
|
||||
if (list.length - 1 === index)
|
||||
await switchPage(list[index - 1].path);
|
||||
}
|
||||
|
||||
else {
|
||||
else
|
||||
await switchPage(list[index + 1].path);
|
||||
}
|
||||
}
|
||||
}
|
||||
list.splice(index, 1);
|
||||
pageList.value = list;
|
||||
pageRef.value.removeKeepAlive(selectedPage.name);
|
||||
deleteTitle(selectedPage.path);
|
||||
};
|
||||
layoutState.closeTab = handleCloseTab;
|
||||
|
||||
const reloadPage = (path) => {
|
||||
const selectedPage = findPage(path || unref(route.path));
|
||||
if (selectedPage) {
|
||||
if (selectedPage)
|
||||
selectedPage.key = getKey();
|
||||
}
|
||||
};
|
||||
const closeOtherPage = (path) => {
|
||||
const selectedPage = findPage(path || unref(route.path));
|
||||
@ -170,9 +139,8 @@ export default {
|
||||
};
|
||||
const getPageKey = (_route) => {
|
||||
const selectedPage = findPage(_route.path);
|
||||
if (selectedPage) {
|
||||
if (selectedPage)
|
||||
return selectedPage.key;
|
||||
}
|
||||
|
||||
return '';
|
||||
};
|
||||
@ -188,11 +156,6 @@ export default {
|
||||
}
|
||||
};
|
||||
|
||||
provide(PLUGIN_LAYOUT_KEY, {
|
||||
closeTab: handleCloseTab,
|
||||
reloadTab: reloadPage,
|
||||
});
|
||||
|
||||
return {
|
||||
pageRef,
|
||||
route,
|
||||
|
4
packages/fes-plugin-layout/types.d.ts
vendored
4
packages/fes-plugin-layout/types.d.ts
vendored
@ -22,14 +22,12 @@ interface Menu {
|
||||
children?: Menu[];
|
||||
}
|
||||
|
||||
type Navigation = 'side' | 'mixin' | 'top' | 'left-right' | 'top-left';
|
||||
type Navigation = 'side' | 'mixin' | 'top' | 'left-right';
|
||||
|
||||
export const Page: Component;
|
||||
|
||||
export function useTabTitle(title: string | Ref<string>): void;
|
||||
|
||||
export function useLayout(options: { title?: string }): { title: Ref<string>; reloadTab: () => void; closeTab: () => void };
|
||||
|
||||
interface LayoutRuntimeConfig {
|
||||
footer?: string;
|
||||
theme?: 'dark' | 'light';
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@fesjs/plugin-locale",
|
||||
"version": "4.4.0",
|
||||
"version": "4.2.2",
|
||||
"description": "@fesjs/plugin-locale",
|
||||
"main": "lib/index.js",
|
||||
"files": [
|
||||
@ -28,12 +28,12 @@
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fesjs/utils": "^3.0.3",
|
||||
"@fesjs/utils": "^3.0.1",
|
||||
"vue-i18n": "^9.0.0",
|
||||
"lodash-es": "^4.17.21"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@fesjs/fes": "^3.1.12",
|
||||
"@fesjs/fes": "^3.1.9",
|
||||
"@fesjs/fes-design": ">=0.7.0",
|
||||
"vue": "^3.2.47"
|
||||
},
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
import { name } from '../package.json';
|
||||
|
||||
const namespace = 'plugin-locale';
|
||||
@ -24,8 +24,6 @@ export default (api) => {
|
||||
|
||||
api.addRuntimePluginKey(() => 'locale');
|
||||
|
||||
api.addRuntimePluginKey(() => 'onLocaleChange');
|
||||
|
||||
const absoluteFilePath = join(namespace, 'core.js');
|
||||
|
||||
const absRuntimeFilePath = join(namespace, 'runtime.js');
|
||||
@ -34,17 +32,10 @@ export default (api) => {
|
||||
return join(api.paths.absSrcPath, api.config.singular ? 'locale' : 'locales');
|
||||
}
|
||||
|
||||
api.register({
|
||||
key: 'addExtraLocales',
|
||||
fn: () => [
|
||||
getLocaleFileBasePath(),
|
||||
],
|
||||
});
|
||||
|
||||
// 监听 locale 文件改变,重新生成文件
|
||||
api.addTmpGenerateWatcherPaths(getLocaleFileBasePath);
|
||||
|
||||
api.onGenerateFiles(async () => {
|
||||
api.onGenerateFiles(() => {
|
||||
// .fes配置
|
||||
const userConfig = {
|
||||
locale: 'zh-CN', // default locale
|
||||
@ -54,13 +45,9 @@ export default (api) => {
|
||||
...api.config.locale,
|
||||
};
|
||||
|
||||
const additionalLocales = await api.applyPlugins({
|
||||
key: 'addExtraLocales',
|
||||
type: api.ApplyPluginsType.add,
|
||||
initialValue: [],
|
||||
});
|
||||
const localeConfigFileBasePath = getLocaleFileBasePath();
|
||||
|
||||
const { files, locales } = getLocales(additionalLocales);
|
||||
const { files, locales } = getLocales(localeConfigFileBasePath);
|
||||
|
||||
const { baseNavigator, ...otherConfig } = userConfig;
|
||||
|
||||
@ -68,7 +55,7 @@ export default (api) => {
|
||||
path: join(namespace, 'locales.js'),
|
||||
content: Mustache.render(readFileSync(join(__dirname, 'runtime/locales.js.tpl'), 'utf-8'), {
|
||||
REPLACE_IMPORTS: files,
|
||||
REPLACE_LOCALES: locales.map(item => ({
|
||||
REPLACE_LOCALES: locales.map((item) => ({
|
||||
locale: item.locale,
|
||||
importNames: item.importNames.join(', '),
|
||||
})),
|
||||
|
@ -8,7 +8,7 @@
|
||||
import { isRef, unref } from 'vue';
|
||||
import { createI18n, useI18n } from '{{{ VUE_I18N_PATH }}}';
|
||||
import locales from './locales'
|
||||
import { plugin, ApplyPluginsType } from '@@/core/coreExports';
|
||||
|
||||
|
||||
const defaultOptions = {{{REPLACE_DEFAULT_OPTIONS}}};
|
||||
|
||||
@ -19,22 +19,18 @@ const getDefaultLocale = () => {
|
||||
if (fes_locale) {
|
||||
return {
|
||||
locale: fes_locale,
|
||||
fallbackLocale: defaultOptions.fallbackLocale,
|
||||
fallbackLocale: fes_locale,
|
||||
};
|
||||
}
|
||||
if (BASE_NAVIGATOR) {
|
||||
const keys = locales.map(item=> item.locale);
|
||||
const findKey = keys.find(item=> item.includes(window.navigator.language))
|
||||
if(findKey){
|
||||
return {
|
||||
locale: findKey,
|
||||
fallbackLocale: defaultOptions.fallbackLocale,
|
||||
locale: window.navigator.language,
|
||||
fallbackLocale: window.navigator.language,
|
||||
};
|
||||
}
|
||||
}
|
||||
return {
|
||||
locale: defaultOptions.locale,
|
||||
fallbackLocale: defaultOptions.fallbackLocale,
|
||||
locale: 'zh-CN',
|
||||
fallbackLocale: 'zh-CN',
|
||||
};
|
||||
};
|
||||
|
||||
@ -51,8 +47,6 @@ const i18n = createI18n({
|
||||
messages,
|
||||
});
|
||||
|
||||
const t = i18n.global.t;
|
||||
|
||||
window.localStorage.setItem("fes_locale", unref(i18n.global.locale));
|
||||
const setLocale = ({ locale }) => {
|
||||
if (isRef(i18n.global.locale)) {
|
||||
@ -61,11 +55,6 @@ const setLocale = ({ locale }) => {
|
||||
i18n.global.locale = locale;
|
||||
}
|
||||
window.localStorage.setItem("fes_locale", locale);
|
||||
plugin.applyPlugins({
|
||||
key: 'onLocaleChange',
|
||||
type: ApplyPluginsType.event,
|
||||
args: { i18n, t, locale: unref(i18n.global.locale) },
|
||||
});
|
||||
};
|
||||
|
||||
const getLocale = () => {
|
||||
@ -89,20 +78,19 @@ const getAllLocales = () => {
|
||||
|
||||
const install = (app) => {
|
||||
app.use(i18n);
|
||||
plugin.applyPlugins({
|
||||
key: 'onLocaleChange',
|
||||
type: ApplyPluginsType.event,
|
||||
args: { i18n, t, locale: unref(i18n.global.locale) },
|
||||
});
|
||||
};
|
||||
|
||||
const t = (key) => {
|
||||
return i18n.global.t(key)
|
||||
}
|
||||
|
||||
const locale = {
|
||||
setLocale,
|
||||
getLocale,
|
||||
addLocale,
|
||||
getAllLocales,
|
||||
messages,
|
||||
t,
|
||||
t
|
||||
};
|
||||
|
||||
export { useI18n, locale, install };
|
||||
|
@ -126,7 +126,7 @@ export default {
|
||||
title: 'Nyelv',
|
||||
},
|
||||
'hy-AM': {
|
||||
lang: 'hy-AM',
|
||||
lang: 'hu-HU',
|
||||
label: 'Հայերեն',
|
||||
icon: '🇦🇲',
|
||||
title: 'Լեզու',
|
||||
@ -162,7 +162,7 @@ export default {
|
||||
title: 'Ziman',
|
||||
},
|
||||
'kn-IN': {
|
||||
lang: 'kn-IN',
|
||||
lang: 'zh-TW',
|
||||
label: 'ಕನ್ನಡ',
|
||||
icon: '🇮🇳',
|
||||
title: 'ಭಾಷೆ',
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { plugin } from '@@/core/coreExports';
|
||||
|
||||
import { install, locale, useI18n } from './core';
|
||||
// eslint-disable-next-line import/extensions
|
||||
import { useI18n, locale, install } from './core';
|
||||
import SelectLang from './views/SelectLang.vue';
|
||||
|
||||
// 共享出去
|
||||
|
@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<FTooltip v-model="isOpened" popper-class="lang-popper" mode="popover">
|
||||
<FTooltip v-model="isOpened" popperClass="lang-popper" mode="popover">
|
||||
<div class="lang-icon">
|
||||
<LanguageOutlined />
|
||||
</div>
|
||||
<template #content>
|
||||
<FScrollbar height="274" class="lang-container">
|
||||
<div v-for="item in configs" :key="item.lang" class="lang-option" :class="[item.lang === locale && 'is-selected']" @click="handleSelect(item)">
|
||||
<div v-for="item in configs" :key="item.lang" :class="['lang-option', item.lang === locale && 'is-selected']" @click="handleSelect(item)">
|
||||
<span>{{ item.icon }}</span>
|
||||
<span>{{ item.label }}</span>
|
||||
</div>
|
||||
@ -15,12 +15,12 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { FScrollbar, FTooltip } from '@fesjs/fes-design';
|
||||
import { FTooltip, FScrollbar } from '@fesjs/fes-design';
|
||||
import { LanguageOutlined } from '@fesjs/fes-design/icon';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { computed, ref } from 'vue';
|
||||
import langUConfigMap from '../langUConfigMap';
|
||||
|
||||
// eslint-disable-next-line import/extensions
|
||||
import { locale as _locale } from '../core';
|
||||
|
||||
export default {
|
||||
@ -55,13 +55,11 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.fes-tooltip.fes-tooltip-popover.lang-popper {
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.lang-icon {
|
||||
display: flex;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { basename, join } from 'node:path';
|
||||
import { join, basename } from 'path';
|
||||
import { glob, winPath } from '@fesjs/utils';
|
||||
|
||||
const ignore = /\.(d\.ts|\.test\.(js|ts))$/;
|
||||
@ -15,14 +15,13 @@ const getRouteName = function (path) {
|
||||
.replace(/\[...([a-zA-Z]*)\]/, 'FUZZYMATCH-$1');
|
||||
};
|
||||
|
||||
export function getLocales(cwdArray) {
|
||||
export function getLocales(cwd) {
|
||||
const map = {};
|
||||
const files = [];
|
||||
cwdArray.forEach((cwd) => {
|
||||
glob.sync('**/*.js', {
|
||||
cwd,
|
||||
})
|
||||
.filter(file => !ignore.test(file))
|
||||
.filter((file) => !ignore.test(file))
|
||||
.forEach((fileName) => {
|
||||
const locale = basename(fileName, '.js');
|
||||
const importName = getRouteName(fileName).replace('.js', '');
|
||||
@ -37,10 +36,9 @@ export function getLocales(cwdArray) {
|
||||
}
|
||||
map[locale].push(importName);
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
locales: Object.keys(map).map(key => ({ locale: key, importNames: map[key] })),
|
||||
locales: Object.keys(map).map((key) => ({ locale: key, importNames: map[key] })),
|
||||
files,
|
||||
};
|
||||
}
|
||||
|
6
packages/fes-plugin-locale/types.d.ts
vendored
6
packages/fes-plugin-locale/types.d.ts
vendored
@ -1,5 +1,3 @@
|
||||
import type { VueI18n } from 'vue-i18n';
|
||||
|
||||
export { useI18n } from 'vue-i18n';
|
||||
|
||||
export const locale: {
|
||||
@ -7,7 +5,6 @@ export const locale: {
|
||||
addLocale: ({ locale, messages }: { locale: string; messages: object }) => void;
|
||||
getAllLocales: () => string[];
|
||||
messages: Record<string, object>;
|
||||
t: VueI18n['t'];
|
||||
};
|
||||
|
||||
declare module '@fesjs/fes' {
|
||||
@ -21,7 +18,4 @@ declare module '@fesjs/fes' {
|
||||
}
|
||||
| false;
|
||||
}
|
||||
interface PluginRuntimeConfig {
|
||||
onLocaleChange: (params: { t: VueI18n['t']; locale: string }) => void;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@fesjs/plugin-login",
|
||||
"version": "3.0.2",
|
||||
"version": "3.0.0",
|
||||
"description": "@fesjs/plugin-login",
|
||||
"main": "lib/index.js",
|
||||
"files": [
|
||||
@ -29,7 +29,7 @@
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@fesjs/fes": "^3.0.0",
|
||||
"@fesjs/plugin-request": "^4.0.0-rc.3",
|
||||
"@fesjs/plugin-request": "^3.0.0",
|
||||
"vue": "^3.2.47"
|
||||
},
|
||||
"typings": "./types.d.ts"
|
||||
|
@ -1,12 +1,8 @@
|
||||
import { request } from '@@/core/pluginExports';
|
||||
import { ApplyPluginsType, getRouter, plugin } from '@fesjs/fes';
|
||||
|
||||
let config;
|
||||
function getLoginConfig() {
|
||||
if (config) {
|
||||
return config;
|
||||
}
|
||||
|
||||
if (config) return config;
|
||||
config = plugin.applyPlugins({
|
||||
key: 'login',
|
||||
type: ApplyPluginsType.modify,
|
||||
@ -18,8 +14,27 @@ function getLoginConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
const defaultExport = {
|
||||
onRouterCreated({ router }) {
|
||||
// ACCESS
|
||||
|
||||
export function request(memo) {
|
||||
if (!memo.responseInterceptors) {
|
||||
memo.responseInterceptors = [];
|
||||
}
|
||||
memo.responseInterceptors.push([
|
||||
(response) => response,
|
||||
(error) => {
|
||||
if (error?.response?.status === 401) {
|
||||
const router = getRouter();
|
||||
const { loginPath } = getLoginConfig();
|
||||
router.push({ path: loginPath });
|
||||
}
|
||||
throw error;
|
||||
},
|
||||
]);
|
||||
return memo;
|
||||
}
|
||||
|
||||
export function onRouterCreated({ router }) {
|
||||
const { hasLogin, loginPath } = getLoginConfig();
|
||||
if (hasLogin && loginPath) {
|
||||
let isAuthenticated;
|
||||
@ -33,52 +48,4 @@ const defaultExport = {
|
||||
next();
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// ACCESS
|
||||
|
||||
if (request.version) {
|
||||
defaultExport.request = (memo) => {
|
||||
const config = getLoginConfig();
|
||||
if (config.ignore401Redirect) {
|
||||
return memo;
|
||||
}
|
||||
|
||||
const errorHandler = memo.errorHandler;
|
||||
memo.errorHandler = (error) => {
|
||||
if (error?.response?.status === 401) {
|
||||
const router = getRouter();
|
||||
const { loginPath } = getLoginConfig();
|
||||
router.push({ path: loginPath });
|
||||
}
|
||||
errorHandler && errorHandler(error);
|
||||
};
|
||||
return memo;
|
||||
};
|
||||
}
|
||||
else {
|
||||
defaultExport.request = (memo) => {
|
||||
const config = getLoginConfig();
|
||||
if (config.ignore401Redirect) {
|
||||
return memo;
|
||||
}
|
||||
if (!memo.responseInterceptors) {
|
||||
memo.responseInterceptors = [];
|
||||
}
|
||||
memo.responseInterceptors.push([
|
||||
response => response,
|
||||
(error) => {
|
||||
if (error?.response?.status === 401) {
|
||||
const router = getRouter();
|
||||
const { loginPath } = getLoginConfig();
|
||||
router.push({ path: loginPath });
|
||||
}
|
||||
throw error;
|
||||
},
|
||||
]);
|
||||
return memo;
|
||||
};
|
||||
}
|
||||
|
||||
export default defaultExport;
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@fesjs/plugin-model",
|
||||
"version": "3.0.3",
|
||||
"version": "3.0.1",
|
||||
"description": "@fesjs/plugin-model",
|
||||
"main": "lib/index.js",
|
||||
"files": [
|
||||
@ -28,10 +28,10 @@
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fesjs/utils": "^3.0.3"
|
||||
"@fesjs/utils": "^3.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@fesjs/fes": "^3.1.12",
|
||||
"@fesjs/fes": "^3.1.4",
|
||||
"vue": "^3.2.47"
|
||||
},
|
||||
"typings": "./types.d.ts"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@fesjs/plugin-monaco-editor",
|
||||
"version": "3.0.3",
|
||||
"version": "3.0.1",
|
||||
"description": "@fesjs/plugin-monaco-editor",
|
||||
"main": "lib/index.js",
|
||||
"files": [
|
||||
@ -26,14 +26,14 @@
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fesjs/utils": "^3.0.3",
|
||||
"@fesjs/utils": "^3.0.1",
|
||||
"lodash-es": "^4.17.21",
|
||||
"monaco-editor": "^0.36.1",
|
||||
"monaco-editor-webpack-plugin": "^7.0.1",
|
||||
"vite-plugin-monaco-editor": "^1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@fesjs/fes": "^3.1.12",
|
||||
"@fesjs/fes": "^3.1.4",
|
||||
"vue": "^3.2.47"
|
||||
},
|
||||
"typings": "./types.d.ts"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@fesjs/plugin-pinia",
|
||||
"version": "3.0.3",
|
||||
"version": "3.0.1",
|
||||
"description": "@fesjs/plugin-pinia",
|
||||
"main": "lib/index.js",
|
||||
"files": [
|
||||
@ -28,10 +28,10 @@
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fesjs/utils": "^3.0.3"
|
||||
"@fesjs/utils": "^3.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@fesjs/fes": "^3.1.12",
|
||||
"@fesjs/fes": "^3.1.4",
|
||||
"pinia": "^2.0.11",
|
||||
"vue": "^3.2.47"
|
||||
},
|
||||
|
@ -1,2 +1 @@
|
||||
PORT=9000
|
||||
HOST=127.0.0.1
|
||||
|
@ -1,2 +1 @@
|
||||
PORT=9001
|
||||
HOST=127.0.0.1
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@fesjs/plugin-qiankun",
|
||||
"version": "3.1.6",
|
||||
"version": "3.1.1",
|
||||
"description": "@fesjs/plugin-qiankun",
|
||||
"main": "lib/index.js",
|
||||
"files": [
|
||||
@ -32,7 +32,7 @@
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fesjs/utils": "^3.0.3",
|
||||
"@fesjs/utils": "^3.0.1",
|
||||
"address": "^1.1.2",
|
||||
"lodash-es": "^4.17.21",
|
||||
"qiankun": "^2.7.0",
|
||||
@ -42,7 +42,7 @@
|
||||
"npm-run-all": "^4.1.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@fesjs/fes": "^3.1.13",
|
||||
"@fesjs/fes": "^3.1.4",
|
||||
"@fesjs/fes-design": ">=0.7.20",
|
||||
"vue": "^3.2.47"
|
||||
},
|
||||
|
@ -9,7 +9,7 @@ import {
|
||||
shallowRef,
|
||||
} from "vue";
|
||||
import { loadMicroApp } from "{{{QIANKUN}}}";
|
||||
import { mergeWith, cloneDeep, isEqual, concat } from "{{{LODASH_ES}}}";
|
||||
import { mergeWith, cloneDeep, isEqual } from "{{{LODASH_ES}}}";
|
||||
// eslint-disable-next-line import/extensions
|
||||
import { getMasterOptions } from "./masterOptions";
|
||||
|
||||
|
@ -3,9 +3,6 @@ import { cloneDeep } from 'lodash-es'
|
||||
let initState = reactive({});
|
||||
const setModelState = (props) => {
|
||||
// 使用深拷贝去掉主应用数据和子应用数据的引用关系,避免出现副作用。
|
||||
Object.keys(initState).forEach(p=>{
|
||||
delete initState[p]
|
||||
})
|
||||
Object.assign(initState, cloneDeep(props))
|
||||
};
|
||||
|
||||
|
@ -1,21 +1,7 @@
|
||||
{
|
||||
"name": "@fesjs/plugin-request",
|
||||
"version": "4.0.1",
|
||||
"version": "4.0.0-rc.1",
|
||||
"description": "@fesjs/plugin-request",
|
||||
"author": "qlin",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/WeBankFinTech/fes.js#readme",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/WeBankFinTech/fes.js.git",
|
||||
"directory": "packages/fes-plugin-request"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/WeBankFinTech/fes.js/issues"
|
||||
},
|
||||
"keywords": [
|
||||
"fes"
|
||||
],
|
||||
"main": "lib/index.js",
|
||||
"files": [
|
||||
"lib",
|
||||
@ -24,16 +10,30 @@
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/WeBankFinTech/fes.js.git",
|
||||
"directory": "packages/fes-plugin-request"
|
||||
},
|
||||
"keywords": [
|
||||
"fes"
|
||||
],
|
||||
"author": "qlin",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/WeBankFinTech/fes.js/issues"
|
||||
},
|
||||
"homepage": "https://github.com/WeBankFinTech/fes.js#readme",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@fesjs/fes": "^3.1.12",
|
||||
"@fesjs/fes": "^3.1.4",
|
||||
"vue": "^3.2.37"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fesjs/utils": "^3.0.3",
|
||||
"@qlin/request": "^0.3.1"
|
||||
"@fesjs/utils": "^3.0.1",
|
||||
"@qlin/request": "^0.1.2"
|
||||
},
|
||||
"typings": "./types.d.ts"
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { join } from 'node:path';
|
||||
import { join } from 'path';
|
||||
import { name } from '../package.json';
|
||||
|
||||
export default (api) => {
|
||||
@ -9,9 +9,7 @@ export default (api) => {
|
||||
|
||||
let generatedOnce = false;
|
||||
api.onGenerateFiles(() => {
|
||||
if (generatedOnce) {
|
||||
return;
|
||||
}
|
||||
if (generatedOnce) return;
|
||||
generatedOnce = true;
|
||||
api.copyTmpFiles({
|
||||
namespace,
|
||||
|
@ -1,44 +1,39 @@
|
||||
import { ApplyPluginsType, plugin } from '@fesjs/fes';
|
||||
import { createRequest } from '@qlin/request';
|
||||
|
||||
import { ref, shallowRef } from 'vue';
|
||||
|
||||
import { createRequest } from '@qlin/request';
|
||||
|
||||
function getRequestInstance() {
|
||||
const defaultConfig = plugin.applyPlugins({
|
||||
key: 'request',
|
||||
type: ApplyPluginsType.modify,
|
||||
initialValue: {
|
||||
timeout: 10000,
|
||||
responseType: 'json',
|
||||
},
|
||||
});
|
||||
|
||||
return createRequest(defaultConfig);
|
||||
}
|
||||
|
||||
// 不能立马初始化,用户配置可能还没准备好
|
||||
let currentRequest;
|
||||
|
||||
function _rawRequest(url, data, options = {}) {
|
||||
export const rawRequest = (url, data, options = {}) => {
|
||||
if (typeof options === 'string') {
|
||||
options = {
|
||||
method: options,
|
||||
};
|
||||
}
|
||||
if (!currentRequest) {
|
||||
currentRequest = getRequestInstance();
|
||||
}
|
||||
return currentRequest(url, data, options);
|
||||
}
|
||||
};
|
||||
|
||||
// 代理 request 上的属性
|
||||
export const rawRequest = new Proxy(_rawRequest, {
|
||||
get(_, key) {
|
||||
if (!currentRequest) {
|
||||
currentRequest = getRequestInstance();
|
||||
}
|
||||
return currentRequest[key];
|
||||
},
|
||||
});
|
||||
|
||||
export async function request(url, data, options = {}) {
|
||||
export const request = async (url, data, options = {}) => {
|
||||
const response = await rawRequest(url, data, options);
|
||||
return response.data;
|
||||
}
|
||||
};
|
||||
|
||||
request.version = '4.0.0';
|
||||
|
||||
@ -46,15 +41,14 @@ function isPromiseLike(obj) {
|
||||
return !!obj && typeof obj === 'object' && typeof obj.then === 'function';
|
||||
}
|
||||
|
||||
export function useRequest(url, data, options = {}) {
|
||||
export const useRequest = (url, data, options = {}) => {
|
||||
const loadingRef = ref(true);
|
||||
const errorRef = ref(null);
|
||||
const dataRef = shallowRef(null);
|
||||
let promise;
|
||||
if (isPromiseLike(url)) {
|
||||
promise = url;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
promise = request(url, data, options);
|
||||
}
|
||||
promise
|
||||
@ -72,4 +66,4 @@ export function useRequest(url, data, options = {}) {
|
||||
error: errorRef,
|
||||
data: dataRef,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@fesjs/plugin-swc",
|
||||
"version": "3.0.5",
|
||||
"version": "3.0.3",
|
||||
"description": "@fesjs/plugin-swc",
|
||||
"main": "lib/index.js",
|
||||
"types": "types.d.ts",
|
||||
@ -26,7 +26,7 @@
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fesjs/utils": "^3.0.3",
|
||||
"@fesjs/utils": "^3.0.1",
|
||||
"@swc/core": "^1.3.49",
|
||||
"@swc/css": "^0.0.20",
|
||||
"css-minimizer-webpack-plugin": "^5.0.0",
|
||||
@ -35,6 +35,6 @@
|
||||
"terser-webpack-plugin": "^5.3.7"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@fesjs/fes": "^3.1.12"
|
||||
"@fesjs/fes": "^3.1.4"
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@fesjs/plugin-vuex",
|
||||
"version": "3.0.3",
|
||||
"version": "3.0.1",
|
||||
"description": "@fesjs/plugin-vuex",
|
||||
"main": "lib/index.js",
|
||||
"files": [
|
||||
@ -28,10 +28,10 @@
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fesjs/utils": "^3.0.3"
|
||||
"@fesjs/utils": "^3.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@fesjs/fes": "^3.1.12",
|
||||
"@fesjs/fes": "^3.1.4",
|
||||
"vue": "^3.2.47",
|
||||
"vuex": "^4.0.0"
|
||||
},
|
||||
|
@ -1,15 +1,12 @@
|
||||
import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import { parser, winPath } from '@fesjs/utils';
|
||||
import { readdirSync, readFileSync, statSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
/**
|
||||
* 获取文件夹所有JS文件路径
|
||||
* @param {string} dir
|
||||
*/
|
||||
function getDirFilePaths(dir) {
|
||||
if (!existsSync(dir)) {
|
||||
return [];
|
||||
}
|
||||
const dirs = readdirSync(dir);
|
||||
let pathList = [];
|
||||
for (const name of dirs) {
|
||||
@ -17,8 +14,7 @@ function getDirFilePaths(dir) {
|
||||
const info = statSync(path);
|
||||
if (info.isDirectory()) {
|
||||
pathList = pathList.concat(getDirFilePaths(path));
|
||||
}
|
||||
else if (path.endsWith('.js')) {
|
||||
} else if (path.endsWith('.js')) {
|
||||
pathList.push(path);
|
||||
}
|
||||
}
|
||||
@ -33,8 +29,8 @@ function pathToHump(path, root) {
|
||||
return path
|
||||
.replace(root, '')
|
||||
.replace('.js', '')
|
||||
.replace(RegExp('(/|\\.|-|_)\\S', 'g'), text => text[1].toUpperCase())
|
||||
.replace(/\S/, text => text.toLowerCase());
|
||||
.replace(RegExp('(/|\\.|-|_)\\S', 'g'), (text) => text[1].toUpperCase())
|
||||
.replace(/\S/, (text) => text.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -49,7 +45,7 @@ function getModelTypes(ast, name, namespace = '') {
|
||||
getters: {},
|
||||
};
|
||||
let namespaced = false;
|
||||
if (ast.type !== 'ObjectExpression') { return types; }
|
||||
if (ast.type !== 'ObjectExpression') return types;
|
||||
ast.properties.forEach((node) => {
|
||||
if (node.key.name === 'namespaced' && node.value.value) {
|
||||
namespaced = true;
|
||||
@ -60,6 +56,7 @@ function getModelTypes(ast, name, namespace = '') {
|
||||
if (namespaced) {
|
||||
type = types[node.key.name][name];
|
||||
if (!type) {
|
||||
// eslint-disable-next-line no-multi-assign
|
||||
type = types[node.key.name][name] = {};
|
||||
}
|
||||
}
|
||||
@ -80,8 +77,7 @@ function getModelTypes(ast, name, namespace = '') {
|
||||
...subTypes[key],
|
||||
...types[key][name],
|
||||
};
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
types[key] = {
|
||||
...subTypes[key],
|
||||
...types[key],
|
||||
@ -116,9 +112,8 @@ function parseModel(paths = [], root) {
|
||||
sourceType: 'module',
|
||||
plugins: ['jsx', 'typescript'],
|
||||
});
|
||||
ast = ast.program.body.filter(body => body.type === 'ExportDefaultDeclaration')[0];
|
||||
}
|
||||
catch (err) { }
|
||||
ast = ast.program.body.filter((body) => body.type === 'ExportDefaultDeclaration')[0];
|
||||
} catch (err) { }
|
||||
if (ast) {
|
||||
const { mutations, actions, getters } = getModelTypes(ast.declaration, moduleName);
|
||||
MUTATION_TYPES = {
|
||||
@ -160,10 +155,9 @@ export function parseStore(root) {
|
||||
const modelPaths = [];
|
||||
const pluginPaths = [];
|
||||
paths.forEach((path) => {
|
||||
if (path.includes('plugin')) {
|
||||
if (path.indexOf('plugin') > -1) {
|
||||
pluginPaths.push(path);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
modelPaths.push(path);
|
||||
}
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@fesjs/plugin-watermark",
|
||||
"version": "3.0.3",
|
||||
"version": "3.0.1",
|
||||
"description": "@fesjs/plugin-watermark",
|
||||
"main": "lib/index.js",
|
||||
"files": [
|
||||
@ -28,11 +28,11 @@
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fesjs/utils": "^3.0.3",
|
||||
"@fesjs/utils": "^3.0.1",
|
||||
"lodash-es": "^4.17.21"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@fesjs/fes": "^3.1.12",
|
||||
"@fesjs/fes": "^3.1.4",
|
||||
"vue": "^3.2.47"
|
||||
},
|
||||
"typings": "./types.d.ts"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@fesjs/preset-built-in",
|
||||
"version": "3.1.14",
|
||||
"version": "3.1.8",
|
||||
"description": "@fesjs/preset-built-in",
|
||||
"author": "qlin",
|
||||
"license": "MIT",
|
||||
@ -29,13 +29,13 @@
|
||||
"vue": "^3.2.47"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fesjs/compiler": "^3.0.6",
|
||||
"@fesjs/runtime": "^3.0.1",
|
||||
"@fesjs/utils": "^3.0.3",
|
||||
"@fesjs/compiler": "^3.0.2",
|
||||
"@fesjs/runtime": "^3.0.0",
|
||||
"@fesjs/utils": "^3.0.1",
|
||||
"@vue/compiler-sfc": "^3.3.4",
|
||||
"@wll8/better-mock": "0.3.3-alpha",
|
||||
"envinfo": "^7.7.3",
|
||||
"express": "^4.17.3"
|
||||
"express": "^4.17.3",
|
||||
"mockjs": "^1.1.0"
|
||||
},
|
||||
"typings": "./types.d.ts"
|
||||
}
|
||||
|
@ -16,7 +16,6 @@ export default function () {
|
||||
require.resolve('./plugins/features/alias'),
|
||||
require.resolve('./plugins/features/autoprefixer'),
|
||||
require.resolve('./plugins/features/define'),
|
||||
require.resolve('./plugins/features/console'),
|
||||
require.resolve('./plugins/features/dynamicImport'),
|
||||
require.resolve('./plugins/features/globalCSS'),
|
||||
require.resolve('./plugins/features/inlineLimit'),
|
||||
|
@ -12,8 +12,6 @@ import DefaultContainer from './defaultContainer.vue';
|
||||
|
||||
{{{ entryCodeAhead }}}
|
||||
|
||||
{{{ CONSOLE }}}
|
||||
|
||||
const renderClient = (opts = {}) => {
|
||||
const { plugin, routes, rootElement } = opts;
|
||||
const rootContainer = plugin.applyPlugins({
|
||||
|
@ -13,15 +13,6 @@ export function importsToStr(imports) {
|
||||
});
|
||||
}
|
||||
|
||||
function getConsoleInfo(config, pkg) {
|
||||
if (config.console?.version) {
|
||||
return `
|
||||
console.log('%c[${pkg.name}]%c${pkg.version}', 'background-color: #1677ff; border-top-left-radius: 6px; border-bottom-left-radius: 6px; color: white; padding: 4px', 'background-color: #42b983; border-top-right-radius: 6px; border-bottom-right-radius: 6px; color: white; padding: 4px');
|
||||
`;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
export default function (api) {
|
||||
const {
|
||||
utils: { Mustache },
|
||||
@ -33,7 +24,6 @@ export default function (api) {
|
||||
path: 'fes.js',
|
||||
content: Mustache.render(fesTpl, {
|
||||
enableTitle: api.config.title !== false,
|
||||
CONSOLE: getConsoleInfo(api.config, api.pkg),
|
||||
defaultTitle: api.config.title || 'fes.js',
|
||||
runtimePath,
|
||||
rootElement: `#${api.config.mountElementId || 'app'}`,
|
||||
|
@ -1,13 +0,0 @@
|
||||
export default (api) => {
|
||||
api.describe({
|
||||
key: 'console',
|
||||
config: {
|
||||
default: {
|
||||
version: false,
|
||||
},
|
||||
schema(joi) {
|
||||
return joi.object().description('output info in console, default version');
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
@ -122,7 +122,7 @@ export default (api) => {
|
||||
api.logger.info('mock.js should export Function');
|
||||
return;
|
||||
}
|
||||
const mockjs = require('@wll8/better-mock');
|
||||
const mockjs = require('mockjs');
|
||||
initFunction({ cgiMock, mockjs, utils });
|
||||
} catch (err) {
|
||||
api.logger.error('mock.js run fail!');
|
||||
|
9
packages/fes-preset-built-in/types.d.ts
vendored
9
packages/fes-preset-built-in/types.d.ts
vendored
@ -1,8 +1,8 @@
|
||||
import type { App, Component, DefineComponent } from 'vue';
|
||||
import type { createMemoryHistory, createWebHashHistory, createWebHistory, Router, RouteRecordRaw, RouterHistory } from 'vue-router';
|
||||
import { Component, DefineComponent, Component, App } from 'vue';
|
||||
import { RouteRecordRaw, Router, RouterHistory, createMemoryHistory, createWebHashHistory, createWebHistory } from 'vue-router';
|
||||
|
||||
// @ts-ignore
|
||||
import type { Plugin } from '@fesjs/runtime';
|
||||
import { Plugin } from '@fesjs/runtime';
|
||||
|
||||
interface BeforeRenderConfig {
|
||||
loading: Component;
|
||||
@ -44,9 +44,6 @@ declare module '@fesjs/fes' {
|
||||
interface PluginBuildConfig {
|
||||
globalCSS?: 'beforeImports' | 'afterImports';
|
||||
alias?: Record<string, string>;
|
||||
console?: {
|
||||
version?: boolean;
|
||||
};
|
||||
autoprefixer?: {
|
||||
/** environment for `Browserslist` */
|
||||
env?: string;
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@fesjs/runtime",
|
||||
"version": "3.0.1",
|
||||
"version": "3.0.0",
|
||||
"description": "@fesjs/runtime",
|
||||
"main": "es/index.js",
|
||||
"module": "es/index.js",
|
||||
|
8
packages/fes-runtime/types.d.ts
vendored
8
packages/fes-runtime/types.d.ts
vendored
@ -1,4 +1,4 @@
|
||||
export { Plugin } from './es/index';
|
||||
export { Plugin } from './es/index'
|
||||
|
||||
export {
|
||||
useRoute,
|
||||
@ -15,7 +15,7 @@ export {
|
||||
} from 'vue-router';
|
||||
|
||||
export interface ApplyPluginsType {
|
||||
compose: 'compose';
|
||||
event: 'event';
|
||||
modify: 'modify';
|
||||
compose: 'compose',
|
||||
event: 'event',
|
||||
modify: 'modify'
|
||||
};
|
||||
|
@ -54,7 +54,6 @@ export default defineBuildConfig({
|
||||
{
|
||||
title: '子菜单',
|
||||
path: '/menuTest',
|
||||
query: { id: 1 },
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -23,9 +23,8 @@ export const beforeRender = {
|
||||
};
|
||||
|
||||
export const layout = {
|
||||
// eslint-disable-next-line node/prefer-global/process
|
||||
logo: `${process.env.BASE_URL}logo.png`,
|
||||
renderCustom: () => {
|
||||
logo: `${process.env.BASE_URL}wine-outline.svg`,
|
||||
renderCustom: (props) => {
|
||||
return <UserCenter />;
|
||||
},
|
||||
};
|
||||
|
@ -8,9 +8,6 @@ export default defineBuildConfig({
|
||||
define: {
|
||||
__DEV__: false,
|
||||
},
|
||||
console: {
|
||||
version: true,
|
||||
},
|
||||
html: {
|
||||
title: '海贼王',
|
||||
},
|
||||
@ -36,7 +33,7 @@ export default defineBuildConfig({
|
||||
},
|
||||
},
|
||||
layout: {
|
||||
title: '$home',
|
||||
title: 'Fes.js',
|
||||
footer: 'Created by MumbleFE',
|
||||
multiTabs: true,
|
||||
navigation: 'mixin',
|
||||
@ -50,7 +47,6 @@ export default defineBuildConfig({
|
||||
{
|
||||
name: 'editor',
|
||||
icon: '/wine-outline.svg',
|
||||
_blank: true,
|
||||
},
|
||||
{
|
||||
title: '$externalLink',
|
||||
@ -74,7 +70,6 @@ export default defineBuildConfig({
|
||||
},
|
||||
{
|
||||
name: 'pinia',
|
||||
_blank: true,
|
||||
},
|
||||
],
|
||||
menuProps: {
|
||||
|
@ -3,11 +3,6 @@ import { ref, watch } from 'vue';
|
||||
import PageLoading from '@/components/pageLoading.vue';
|
||||
import UserCenter from '@/components/userCenter.vue';
|
||||
|
||||
export function onLocaleChange({ locale, t }) {
|
||||
// 切换语言
|
||||
console.log(locale, t);
|
||||
}
|
||||
|
||||
export const beforeRender = {
|
||||
loading: <PageLoading />,
|
||||
action() {
|
||||
@ -25,12 +20,8 @@ export const beforeRender = {
|
||||
},
|
||||
};
|
||||
|
||||
export function layout(layoutConfig, { initialState }) {
|
||||
return {
|
||||
export const layout = (layoutConfig, { initialState }) => ({
|
||||
...layoutConfig,
|
||||
403: {
|
||||
title: 'hello word',
|
||||
},
|
||||
renderCustom: (props) => {
|
||||
console.log(props);
|
||||
return <UserCenter />;
|
||||
@ -49,5 +40,4 @@ export function layout(layoutConfig, { initialState }) {
|
||||
);
|
||||
return menusRef;
|
||||
},
|
||||
};
|
||||
}
|
||||
});
|
||||
|
@ -5,5 +5,5 @@ html, body {
|
||||
|
||||
.page {
|
||||
height: 1000px;
|
||||
background: url("@/images/hello.png");
|
||||
background-image: url('~@/images/hello.png');
|
||||
}
|
||||
|
@ -4,6 +4,6 @@ export default {
|
||||
externalLink: 'externalLink',
|
||||
mock: 'mock',
|
||||
test: {
|
||||
test: 'test',
|
||||
b: 1,
|
||||
},
|
||||
};
|
||||
|
@ -4,6 +4,6 @@ export default {
|
||||
externalLink: '外部链接',
|
||||
mock: '代理',
|
||||
test: {
|
||||
test: '测试',
|
||||
b: 1,
|
||||
},
|
||||
};
|
||||
|
@ -13,7 +13,7 @@ import { FButton } from '@fesjs/fes-design';
|
||||
|
||||
defineRouteMeta({
|
||||
name: 'index',
|
||||
title: '$test.test',
|
||||
title: '$home',
|
||||
});
|
||||
|
||||
console.log('123123'.replaceAll('123', '234'));
|
||||
@ -27,5 +27,6 @@ function go() {
|
||||
<style lang="less">
|
||||
.page {
|
||||
height: 1000px;
|
||||
background-image: url('@/images/hello.png');
|
||||
}
|
||||
</style>
|
||||
|
@ -1,23 +1,19 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
menuTest: {{ route.params }} <input style="border: 1px solid red">
|
||||
</div>
|
||||
<div class="page">menuTest: {{ route.params }} <input style="border: 1px solid red" /></div>
|
||||
</template>
|
||||
|
||||
<config>
|
||||
{
|
||||
"title": "menuTest-详情"
|
||||
}
|
||||
</config>
|
||||
|
||||
<script>
|
||||
import { useLayout, useRoute } from '@fesjs/fes';
|
||||
import { useRoute, useTabTitle } from '@fesjs/fes';
|
||||
|
||||
export default {
|
||||
components: {},
|
||||
setup() {
|
||||
const route = useRoute();
|
||||
const { title } = useLayout({ title: `详情-${route.params?.id}` });
|
||||
const title = useTabTitle(`详情-${route.params?.id}`);
|
||||
|
||||
setTimeout(() => {
|
||||
title.value = `详情-${route.params?.id}-changed`;
|
||||
|
@ -2,25 +2,17 @@
|
||||
<div class="page">
|
||||
menuTest-index
|
||||
<div style="display: flex; flex-direction: column">
|
||||
<router-link to="/menuTest/1">
|
||||
Go to 1
|
||||
</router-link>
|
||||
<router-link to="/menuTest/2">
|
||||
Go to 2
|
||||
</router-link>
|
||||
<router-link to="/menuTest/3">
|
||||
Go to 3
|
||||
</router-link>
|
||||
<router-link to="/menuTest/1">Go to 1</router-link>
|
||||
<router-link to="/menuTest/2">Go to 2</router-link>
|
||||
<router-link to="/menuTest/3">Go to 3</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<config>
|
||||
{
|
||||
"title": "menuTest"
|
||||
}
|
||||
</config>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
components: {},
|
||||
|
@ -1,10 +1,7 @@
|
||||
<template>
|
||||
<div>{{ store.counter }}</div>
|
||||
<FButton class="m-2" @click="store.increment">
|
||||
Button
|
||||
</FButton>
|
||||
<FButton class="m-2" @click="store.increment">Button</FButton>
|
||||
</template>
|
||||
|
||||
<config>
|
||||
{
|
||||
"name": "pinia",
|
||||
@ -14,7 +11,6 @@
|
||||
}
|
||||
}
|
||||
</config>
|
||||
|
||||
<script>
|
||||
import { FButton } from '@fesjs/fes-design';
|
||||
import { useStore } from '@/store/main';
|
||||
|
@ -1,25 +1,26 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"jsx": "preserve",
|
||||
"lib": ["esnext", "dom"],
|
||||
"experimentalDecorators": true,
|
||||
"baseUrl": ".",
|
||||
"outDir": "build/dist",
|
||||
"module": "esnext",
|
||||
"target": "esnext",
|
||||
"lib": ["esnext", "dom"],
|
||||
"sourceMap": true,
|
||||
"baseUrl": ".",
|
||||
"jsx": "preserve",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"moduleResolution": "node",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noImplicitReturns": true,
|
||||
"suppressImplicitAnyIndexErrors": true,
|
||||
"noUnusedLocals": true,
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"experimentalDecorators": true,
|
||||
"strict": true,
|
||||
"paths": {
|
||||
"@/*": ["./src/*"],
|
||||
"@@/*": ["./src/.fes/*"]
|
||||
},
|
||||
"allowJs": true,
|
||||
"strict": true,
|
||||
"noImplicitReturns": true,
|
||||
"noUnusedLocals": true,
|
||||
"outDir": "build/dist",
|
||||
"sourceMap": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"skipLibCheck": true
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@fesjs/utils",
|
||||
"version": "3.0.3",
|
||||
"version": "3.0.1",
|
||||
"description": "@fesjs/utils",
|
||||
"main": "lib/index.js",
|
||||
"files": [
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user