mirror of
https://github.com/WeBankFinTech/fes.js.git
synced 2025-04-06 03:59:53 +08:00
Merge branch 'vue3' into vue3
This commit is contained in:
commit
2be3058c54
@ -15,6 +15,7 @@ export const zh: SidebarConfig = {
|
||||
text: '基础',
|
||||
children: [
|
||||
'/zh/guide/directory-structure.md',
|
||||
'/zh/guide/config.md',
|
||||
'/zh/guide/route.md',
|
||||
'/zh/guide/plugin.md',
|
||||
'/zh/guide/template.md',
|
||||
|
79
docs/zh/guide/config.md
Normal file
79
docs/zh/guide/config.md
Normal file
@ -0,0 +1,79 @@
|
||||
# 配置
|
||||
|
||||
`fes` 在 `.fes.js` 文件中添加项目基础配置。一份常见的配置示例如下:
|
||||
```js
|
||||
export default {
|
||||
base: '/foo/',
|
||||
publicPath: '/',
|
||||
devServer: {
|
||||
port: 8080
|
||||
}
|
||||
mock: {
|
||||
prefix: '/v2'
|
||||
},
|
||||
proxy: {
|
||||
'/v2': {
|
||||
'target': 'https://api.douban.com/',
|
||||
'changeOrigin': true,
|
||||
},
|
||||
},
|
||||
layout: {
|
||||
title: "Fes.js",
|
||||
footer: 'Created by MumbelFe',
|
||||
multiTabs: false,
|
||||
menus: [{
|
||||
name: 'index'
|
||||
}, {
|
||||
name: 'onepiece'
|
||||
}, {
|
||||
name: 'store'
|
||||
}, {
|
||||
name: 'simpleList'
|
||||
}]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 配置文件
|
||||
可以新建 `.fes.local.js` 作为本地临时配置文件。这份配置会和 `.fes.js` 做 deep merge 后形成最终配置。
|
||||
```js
|
||||
// .fes.js
|
||||
export default { mock: false };
|
||||
|
||||
// .fes.local.js
|
||||
export default {
|
||||
mock: true,
|
||||
dvServer: { port: 8080 }
|
||||
};
|
||||
```
|
||||
最终的配置是:
|
||||
```js
|
||||
{
|
||||
mock: true,
|
||||
devServer: { port: 8080 }
|
||||
};
|
||||
```
|
||||
::: tip
|
||||
`.fes.local.js` 仅在 fes dev 时有效。
|
||||
|
||||
`.fes.local.js` 是本地验证使用的临时配置,请将其添加到 `.gitignore`,务必不要提交到 git 仓库中。
|
||||
|
||||
`.fes.local.js` 配置的优先级最高,比 `FES_ENV` 指定的配置更高。
|
||||
:::
|
||||
|
||||
## 多环境多份配置
|
||||
可以通过环境变量 `FES_ENV` 区分不同环境,来指定配置文件。
|
||||
```js
|
||||
// .fes.js
|
||||
export default { mock: false };
|
||||
|
||||
// .fes.local.js
|
||||
export default {
|
||||
mock: true,
|
||||
dvServer: { port: 8080 }
|
||||
};
|
||||
```
|
||||
根据指定的 `FES_ENV` 拿对应的配置,这份配置会和 `.fes.js` 做 deep merge 后形成最终配。
|
||||
::: tip
|
||||
`FES_ENV` 指定的配置优先级高于 `.fes.js` 文件的配置
|
||||
:::
|
@ -4,574 +4,281 @@ sidebar: auto
|
||||
|
||||
# 配置
|
||||
|
||||
VuePress 配置的参考文档,可以通过配置文件来设置这些配置。 VuePress 约定的配置文件为(按照优先顺序):
|
||||
以下配置项通过字母排序。
|
||||
|
||||
- 当前工作目录 `cwd` 下:
|
||||
- `vuepress.config.ts`
|
||||
- `vuepress.config.js`
|
||||
- 源文件目录 `sourceDir` 下:
|
||||
- `.vuepress/config.ts`
|
||||
- `.vuepress/config.js`
|
||||
## alias
|
||||
|
||||
你也可以通过 [命令行接口](./cli.md) 的 `--config` 选项来指定配置文件。
|
||||
- 类型: `object`
|
||||
- 默认值: `{}`
|
||||
- 详情:
|
||||
|
||||
## 站点配置
|
||||
配置别名,对引用路径进行映射。
|
||||
|
||||
### base
|
||||
- 示例:
|
||||
```js
|
||||
export default {
|
||||
alias: {
|
||||
main: 'src/assets/styles/main'
|
||||
}
|
||||
}
|
||||
```
|
||||
然后 `import('main')`,实际上是 `import('src/assets/styles/main')`。
|
||||
|
||||
## base
|
||||
|
||||
- 类型: `string`
|
||||
|
||||
- 默认值: `/`
|
||||
|
||||
- 详情:
|
||||
|
||||
部署站点的基础路径。
|
||||
|
||||
如果你想让你的网站部署到一个子路径下,你将需要设置它。它的值应当总是以斜杠开始,并以斜杠结束。举例来说,如果你想将你的网站部署到 `https://foo.github.io/bar/`,那么 `base` 应该被设置成 `"/bar/"`。
|
||||
|
||||
`base` 将会作为前缀自动地插入到所有以 `/` 开始的其他选项的链接中,所以你只需要指定一次。
|
||||
|
||||
- 参考:
|
||||
- [指南 > 静态资源 > Base Helper](../guide/assets.md#base-helper)
|
||||
- [指南 > 部署](../guide/deployment.md)
|
||||
|
||||
### lang
|
||||
|
||||
- 类型: `string`
|
||||
|
||||
- 默认值: `en-US`
|
||||
|
||||
- 详情:
|
||||
|
||||
站点的语言。
|
||||
|
||||
它将会在最终渲染出的 HTML 中作为 `<html>` 标签的 `lang` 属性。
|
||||
|
||||
它可以设置在不同语言的 locales 中。
|
||||
|
||||
- 参考:
|
||||
- [配置 > locales](#locales)
|
||||
|
||||
### title
|
||||
|
||||
- 类型: `string`
|
||||
|
||||
- 默认值: `''`
|
||||
- 详情:
|
||||
|
||||
- 详情:
|
||||
|
||||
站点的标题。
|
||||
|
||||
它将会作为所有页面标题的后缀,并且在默认主题的导航栏中显示。
|
||||
|
||||
它可以设置在不同语言的 locales 中。
|
||||
|
||||
- 参考:
|
||||
- [配置 > locales](#locales)
|
||||
|
||||
### description
|
||||
|
||||
- 类型: `string`
|
||||
设置路由前缀,通常用于部署到非根目录。比如你有路由 `/pageA`、`/pageB`,然后设置了 `base` 为 `/manage/`,那么就可以通过 `/manage/pageA`、`/manage/pageB` 访问到它们。
|
||||
|
||||
## cssLoader
|
||||
|
||||
- 类型: `object`
|
||||
- 默认值: `''`
|
||||
- 详情:
|
||||
|
||||
- 详情:
|
||||
设置 [css-loader 配置项](https://github.com/webpack-contrib/css-loader#options)。
|
||||
|
||||
站点的描述。
|
||||
|
||||
它将会在最终渲染出的 HTML 中作为 `<meta name="description" />` 标签的 `content` 属性。它会被每个页面的 Frontmatter 中的 `description` 字段覆盖。
|
||||
|
||||
它可以设置在不同语言的 locales 中。
|
||||
|
||||
- 参考:
|
||||
- [配置 > locales](#locales)
|
||||
- [Frontmatter > description](./frontmatter.md#description)
|
||||
|
||||
### head
|
||||
|
||||
- 类型: `HeadConfig[]`
|
||||
## copy
|
||||
|
||||
- 类型: `Array(string) || Array(object)`
|
||||
- 默认值: `[]`
|
||||
|
||||
- 详情:
|
||||
|
||||
在最终渲染出的 HTML 的 `<head>` 标签内加入的额外标签。
|
||||
|
||||
你可以通过 `[tagName, { attrName: attrValue }, innerHTML?]` 的格式来添加标签。
|
||||
|
||||
它可以设置在不同语言的 locales 中。
|
||||
|
||||
设置要复制到输出目录的文件、文件夹。
|
||||
|
||||
配置约定 `from-to` 规则, 其中 `from` 是相对于 `cwd` 的路径,`to` 是相对于输出路径的路径。
|
||||
- 示例:
|
||||
|
||||
增加一个自定义的 favicon :
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
head: [
|
||||
['link', { rel: 'icon', href: '/logo.png' }]
|
||||
]
|
||||
export default {
|
||||
copy: {
|
||||
from: '/src/assets/images',
|
||||
to: 'assets/images'
|
||||
}
|
||||
}
|
||||
```
|
||||
上面示例中,实现了将 `cwd` 路径中的 `/src/assets/images` 文件夹,在编译完成后,`copy` 到输出路径下的 `assets/images` 文件夹。
|
||||
|
||||
渲染为:
|
||||
|
||||
```html
|
||||
<head>
|
||||
<link rel="icon" href="/logo.png" />
|
||||
</head>
|
||||
```
|
||||
|
||||
- 参考:
|
||||
- [配置 > locales](#locales)
|
||||
- [Frontmatter > head](./frontmatter.md#head)
|
||||
|
||||
### locales
|
||||
|
||||
- 类型: `{ [path: string]: Partial<SiteLocaleData> }`
|
||||
## define
|
||||
|
||||
- 类型: `object`
|
||||
- 默认值: `{}`
|
||||
|
||||
- 详情:
|
||||
|
||||
多语言支持的各个语言 locales 。
|
||||
|
||||
可以使用的字段有:
|
||||
|
||||
- [lang](#lang)
|
||||
- [title](#title)
|
||||
- [description](#description)
|
||||
- [head](#head)
|
||||
|
||||
- 参考:
|
||||
- [指南 > I18n](../guide/i18n.md)
|
||||
|
||||
## 主题配置
|
||||
|
||||
### theme
|
||||
|
||||
- 类型: `string`
|
||||
|
||||
- 默认值: `'@vuepress/default'`
|
||||
|
||||
- 详情:
|
||||
|
||||
你想要使用的主题的名称或绝对路径。
|
||||
|
||||
这个选项可以接收主题名称、主题简称或主题的绝对路径。
|
||||
|
||||
|
||||
用于提供给代码中可用的变量。
|
||||
- 示例:
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
theme: 'vuepress-theme-foo',
|
||||
theme: 'bar',
|
||||
theme: '/path/to/local/theme',
|
||||
export default {
|
||||
define: {
|
||||
__DEV__: 'development'
|
||||
}
|
||||
}
|
||||
```
|
||||
然后你代码里写 `console.log(__DEV__)`,会被编译成 `console.log('development')`。
|
||||
|
||||
- 参考:
|
||||
- [指南 > 主题](../guide/theme.md)
|
||||
|
||||
### themeConfig
|
||||
|
||||
- 类型: `ThemeConfig`
|
||||
## devServer
|
||||
|
||||
- 类型: `object`
|
||||
- 默认值: `{}`
|
||||
|
||||
- 详情:
|
||||
|
||||
配置开发服务器。支持以下子配置项:
|
||||
|
||||
为当前使用的主题提供的配置项。具体的配置项取决于你使用的主题。
|
||||
- port,端口号,默认 `8000`
|
||||
- host,默认 `localhost`
|
||||
- https,是否启用 https server,同时也会开启 HTTP/2
|
||||
|
||||
- 参考:
|
||||
- [默认主题 > 配置](./default-theme/config.md)
|
||||
启用 port 和 host 也可以通过环境变量 `PORT` 和 `HOST` 临时指定。
|
||||
|
||||
## 打包工具配置
|
||||
|
||||
### bundler
|
||||
## devtool
|
||||
|
||||
- 类型: `string`
|
||||
|
||||
- 默认值: `'@vuepress/webpack'`
|
||||
|
||||
- 默认值: `cheap-module-source-map` in dev, `undefined` in build
|
||||
- 详情:
|
||||
|
||||
你想要使用的打包工具的名称。
|
||||
用户配置 sourcemap 类型。详见 [ webpack#devtool 配置](https://webpack.js.org/configuration/devtool/#devtool)。
|
||||
|
||||
可以使用打包工具名称的简称。
|
||||
## extraPostCSSPlugins
|
||||
|
||||
- 参考:
|
||||
- [指南 > 打包工具](../guide/bundler.md)
|
||||
- 类型: `array`
|
||||
- 默认值: `[]`
|
||||
- 详情:
|
||||
|
||||
### bundlerConfig
|
||||
设置额外的 [postcss 插件](https://github.com/postcss/postcss/blob/master/docs/plugins.md)。
|
||||
|
||||
- 类型: `BundlerConfig`
|
||||
|
||||
- 默认值: `{}`
|
||||
|
||||
- 详情:
|
||||
|
||||
为当前使用的打包工具提供的配置项。具体的配置项取决于你使用的打包工具。
|
||||
|
||||
## 目录配置
|
||||
|
||||
### dest
|
||||
|
||||
- 类型: `string`
|
||||
|
||||
- 默认值: `` `${sourceDir}/.vuepress/dist` ``
|
||||
|
||||
- 详情:
|
||||
|
||||
指定 `vuepress build` 命令的输出目录。
|
||||
|
||||
### temp
|
||||
|
||||
- 类型: `string`
|
||||
|
||||
- 默认值: `` `${sourceDir}/.vuepress/.temp` ``
|
||||
|
||||
- 详情:
|
||||
|
||||
指定临时文件目录。
|
||||
|
||||
### cache
|
||||
|
||||
- 类型: `string`
|
||||
|
||||
- 默认值: `` `${sourceDir}/.vuepress/.cache` ``
|
||||
|
||||
- 详情:
|
||||
|
||||
指定缓存目录。
|
||||
|
||||
### public
|
||||
|
||||
- 类型: `string`
|
||||
|
||||
- 默认值: `` `${sourceDir}/.vuepress/public` ``
|
||||
|
||||
- 详情:
|
||||
|
||||
指定 Public 文件目录。
|
||||
|
||||
- 参考:
|
||||
- [指南 > 静态资源 > Public 文件](../guide/assets.md#public-文件)
|
||||
|
||||
## Markdown 配置
|
||||
|
||||
### markdown
|
||||
|
||||
- 类型: `MarkdownOptions`
|
||||
|
||||
- 默认值: `{}`
|
||||
|
||||
- 详情:
|
||||
|
||||
对 VuePress 内置的 Markdown 语法扩展进行配置。
|
||||
|
||||
- 参考:
|
||||
- [指南 > Markdown > 语法扩展](../guide/markdown.md#语法扩展)
|
||||
|
||||
#### markdown.anchor
|
||||
|
||||
- 类型: `AnchorPluginOptions | false`
|
||||
|
||||
- 详情:
|
||||
|
||||
[markdown-it-anchor](https://github.com/valeriangalliat/markdown-it-anchor) 的配置项。
|
||||
|
||||
设置为 `false` 可以禁用该插件。
|
||||
|
||||
- 参考:
|
||||
- [指南 > Markdown > 语法扩展 > 标题锚点](../guide/markdown.md#标题锚点)
|
||||
|
||||
#### markdown.assets
|
||||
|
||||
- 类型: `AssetsPluginOptions | false`
|
||||
|
||||
- 详情:
|
||||
|
||||
VuePress 内置的 markdown-it assets 插件的配置项。
|
||||
|
||||
设置为 `false` 可以禁用该插件。
|
||||
|
||||
::: danger
|
||||
除非你了解它的用途,否则你不应该设置该配置项。
|
||||
:::
|
||||
|
||||
#### markdown.code
|
||||
|
||||
- 类型: `CodePluginOptions | false`
|
||||
|
||||
- 详情:
|
||||
|
||||
VuePress 内置的 markdown-it code 插件的配置项。
|
||||
|
||||
设置为 `false` 可以禁用该插件。
|
||||
|
||||
- 参考:
|
||||
- [指南 > Markdown > 语法扩展 > 代码块](../guide/markdown.md#代码块)
|
||||
|
||||
##### markdown.code.highlight
|
||||
|
||||
- 类型: `boolean`
|
||||
|
||||
- 默认值: `true`
|
||||
|
||||
- 详情:
|
||||
|
||||
是否启用代码块语法高亮。
|
||||
|
||||
如果你想在客户端进行语法高翔,你可以禁用该配置项。比如使用 [Prismjs](https://prismjs.com/) 或 [highlight.js](https://highlightjs.org/) 。
|
||||
|
||||
- 参考:
|
||||
- [指南 > Markdown > 语法扩展 > 代码块 > 语法高亮](../guide/markdown.md#语法高亮)
|
||||
|
||||
##### markdown.code.highlightLines
|
||||
|
||||
- 类型: `boolean`
|
||||
|
||||
- 默认值: `true`
|
||||
|
||||
- 详情:
|
||||
|
||||
是否启用代码块行高亮。
|
||||
|
||||
- 参考:
|
||||
- [指南 > Markdown > 语法扩展 > 代码块 > 行高亮](../guide/markdown.md#行高亮)
|
||||
|
||||
##### markdown.code.lineNumbers
|
||||
|
||||
- 类型: `boolean`
|
||||
|
||||
- 默认值: `true`
|
||||
|
||||
- 详情:
|
||||
|
||||
是否启用代码块行号。
|
||||
|
||||
- 参考:
|
||||
- [指南 > Markdown > 语法扩展 > 代码块 > 行号](../guide/markdown.md#行号)
|
||||
|
||||
##### markdown.code.preWrapper
|
||||
|
||||
- 类型: `boolean`
|
||||
|
||||
- 默认值: `true`
|
||||
|
||||
- 详情:
|
||||
|
||||
是否在 `<pre>` 标签外额外包裹一层。
|
||||
|
||||
`highlightLines` 和 `lineNumbers` 依赖于这个额外的包裹层。这换句话说,如果你禁用了 `preWrapper` ,那么行高亮和行号也会被同时禁用。
|
||||
|
||||
如果你想要在客户端来实现这些功能时,可以禁用该配置项。比如使用 [Prismjs Line Highlight](https://prismjs.com/plugins/line-highlight/) 或者 [Prismjs Line Numbers](https://prismjs.com/plugins/line-numbers/)。
|
||||
|
||||
##### markdown.code.vPre
|
||||
|
||||
- 类型: `boolean`
|
||||
|
||||
- 默认值: `true`
|
||||
|
||||
- 详情:
|
||||
|
||||
是否在 `<pre>` 标签上添加 `v-pre` 指令。
|
||||
|
||||
- 参考:
|
||||
- [指南 > Markdown > 语法扩展 > 代码块 > 添加 v-pre](../guide/markdown.md#添加-v-pre)
|
||||
|
||||
#### markdown.customComponent
|
||||
|
||||
- 类型: `undefined | false`
|
||||
|
||||
- 详情:
|
||||
|
||||
VuePress 内置的 markdown-it custom-component 插件的配置项。
|
||||
|
||||
设置为 `false` 可以禁用该插件。
|
||||
|
||||
::: danger
|
||||
除非你了解它的用途,否则你不应该设置该配置项。
|
||||
:::
|
||||
|
||||
#### markdown.emoji
|
||||
|
||||
- 类型: `EmojiPluginOptions | false`
|
||||
|
||||
- 详情:
|
||||
|
||||
[markdown-it-emoji](https://github.com/markdown-it/markdown-it-emoji) 的配置项。
|
||||
|
||||
设置为 `false` 可以禁用该插件。
|
||||
|
||||
- 参考:
|
||||
- [指南 > Markdown > 语法扩展 > Emoji](../guide/markdown.md#emoji)
|
||||
|
||||
#### markdown.extractHeaders
|
||||
|
||||
- 类型: `ExtractHeadersPluginOptions | false`
|
||||
|
||||
- 详情:
|
||||
|
||||
VuePress 内置的 markdown-it extract-headers 插件的配置项。
|
||||
|
||||
它将会把页面的标题提取到 Page Data 中,可以用于生成侧边栏、目录等。比如当前页面的侧边栏,就是由这个插件提取出的标题来自动生成的。
|
||||
|
||||
设置为 `false` 可以禁用该插件。
|
||||
|
||||
#### markdown.hoistTags
|
||||
|
||||
- 类型: `HoistTagsPluginOptions | false`
|
||||
|
||||
- 详情:
|
||||
|
||||
VuePress 内置的 markdown-it hoist-tags 插件的配置项。
|
||||
|
||||
它将会把你的 Markdown 中特定的 HTML 标签提升到 SFC 的顶层。默认情况下,只有 `<script>` 和 `<style>` 标签会被提升。你可以通过这个配置项,在 Markdown 中使用 SFC 自定义块。
|
||||
|
||||
设置为 `false` 可以禁用该插件。
|
||||
|
||||
- 参考:
|
||||
- [深入 > Markdown 与 Vue SFC](../guide/advanced/markdown.md)
|
||||
|
||||
#### markdown.links
|
||||
|
||||
- 类型: `LinksPluginOptions | false`
|
||||
|
||||
- 详情:
|
||||
|
||||
VuePress 内置的 markdown-it 链接插件的配置项。
|
||||
|
||||
它将会把站内链接转换为 `<RouterLink>` ,并且会在站外链接上添加额外的属性。
|
||||
|
||||
设置为 `false` 可以禁用该插件。
|
||||
|
||||
- 参考:
|
||||
- [指南 > Markdown > 语法扩展 > 链接](../guide/markdown.md#链接)
|
||||
|
||||
#### markdown.toc
|
||||
|
||||
- 类型: `TocPluginOptions | false`
|
||||
|
||||
- 详情:
|
||||
|
||||
VuePress 内置的 markdown-it 目录插件的配置项。
|
||||
|
||||
设置为 `false` 可以禁用该插件。
|
||||
|
||||
- 参考:
|
||||
- [指南 > Markdown > 语法扩展 > 目录](../guide/markdown.md#目录)
|
||||
|
||||
## 开发配置项
|
||||
|
||||
### debug
|
||||
|
||||
- 类型: `boolean`
|
||||
|
||||
- 默认值: `false`
|
||||
|
||||
- 详情:
|
||||
|
||||
是否启用 Debug 模式。
|
||||
|
||||
该配置项主要提供给开发者使用。同时,我们使用了 [debug](https://github.com/visionmedia/debug) 模块打印 Debug 日志,可以通过 `DEBUG=vuepress*` 环境变量来启用。
|
||||
|
||||
### host
|
||||
|
||||
- 类型: `string`
|
||||
|
||||
- 默认值: `'0.0.0.0'`
|
||||
|
||||
- 详情:
|
||||
|
||||
指定开发服务器的主机名。
|
||||
|
||||
### port
|
||||
## inlineLimit
|
||||
|
||||
- 类型: `number`
|
||||
|
||||
- 默认值: `8080`
|
||||
|
||||
- 默认值: `8192`(8k)
|
||||
- 详情:
|
||||
|
||||
指定开发服务器的端口号。
|
||||
|
||||
### open
|
||||
|
||||
- 类型: `boolean`
|
||||
|
||||
- 默认值: `false`
|
||||
配置图片文件是否走 base64 编译的阈值。默认是 `8192` 字节,小于它会被编译为 base64 编码,否则会生成单独的文件。
|
||||
|
||||
## lessLoader
|
||||
|
||||
- 类型: `object`
|
||||
- 默认值: `{}`
|
||||
- 详情:
|
||||
|
||||
是否在开发服务器启动后打开浏览器。
|
||||
设置 [less-loader 配置项](https://github.com/webpack-contrib/less-loader)。
|
||||
|
||||
### evergreen
|
||||
|
||||
- 类型: `boolean`
|
||||
|
||||
- 默认值: `true`
|
||||
## mock
|
||||
|
||||
- 类型: `object || boolean`
|
||||
- 默认值: `{}`
|
||||
- 详情:
|
||||
|
||||
如果你的对象只有那些 “常青树” 浏览器,你可以将其设置成 `true` 。这将会禁用一些转译过程和 Polyfills ,带来更快的构建速度和更小的文件体积。
|
||||
配置 mock 属性。
|
||||
|
||||
### pagePatterns
|
||||
- 当 mock 为 `boolean` 类型时,`true` 表示打开 mock,`false` 表示关闭 mock。
|
||||
- 当 mock 为 `object` 类型时,默认打开 mock。也可以通过子属性 `prefix` 添加过滤条件,满足条件的走 mock 文件。
|
||||
|
||||
- 类型: `string[]`
|
||||
- 示例:
|
||||
```js
|
||||
export default {
|
||||
mock: {
|
||||
prefix: '/api/auth'
|
||||
}
|
||||
}
|
||||
```
|
||||
然后所有以 `/api/users` 开始的请求,就能进入 mock.js 文件处理。
|
||||
|
||||
- 默认值: `['**/*.md', '!.vuepress', '!node_modules']`
|
||||
|
||||
- 详情:
|
||||
|
||||
指定页面文件的 Patterns 。这些 Patterns 是相对于 Source 目录的。
|
||||
|
||||
### templateDev
|
||||
## mountElementId
|
||||
|
||||
- 类型: `string`
|
||||
|
||||
- 默认值: `'@vuepress/client/templates/index.dev.html'`
|
||||
|
||||
- 默认值: `app`
|
||||
- 详情:
|
||||
|
||||
指定开发时使用的 HTML 模板。
|
||||
指定渲染到的 HTML 元素 id。
|
||||
|
||||
### templateSSR
|
||||
## nodeModulesTransform
|
||||
|
||||
- 类型: `object`
|
||||
- 默认值: `{ type: 'all' }`
|
||||
- 详情:
|
||||
|
||||
设置 node_modules 目录下依赖文件的编译方式。子配置项包含:
|
||||
- `type`,编译模式类型,可选 `all` 和 `none`。
|
||||
- 默认值是 `all`,全部编译,然后可以通过 `exclude` 忽略不需要编译的依赖库。
|
||||
- 当切换为 `none`,默认值编译 [es5-imcompatible-versions](https://github.com/umijs/es5-imcompatible-versions) 里声明的依赖,可通过 `exclude` 配置添加额外需要编译的。
|
||||
|
||||
- `exclude`,忽略的依赖库,包名,暂不支持绝对路径。
|
||||
|
||||
前者速度较慢,但可规避常见的兼容性等问题,后者反之。
|
||||
|
||||
## outputPath
|
||||
|
||||
- 类型: `string`
|
||||
|
||||
- 默认值: `'@vuepress/client/templates/index.ssr.html'`
|
||||
|
||||
- 默认值: `dist`
|
||||
- 详情:
|
||||
|
||||
指定构建时 (SSR) 使用的 HTML 模板。
|
||||
指定输出路径。
|
||||
|
||||
### shouldPreload
|
||||
::: tip
|
||||
不允许设定为 `src`、`public`、`pages` 等约定目录。
|
||||
:::
|
||||
|
||||
- 类型: `((file: string, type: string) => boolean)) | boolean`
|
||||
|
||||
- 默认值: `true`
|
||||
## postcssLoader
|
||||
|
||||
- 类型: `object`
|
||||
- 默认值: `{}`
|
||||
- 详情:
|
||||
|
||||
一个函数,用来控制哪些文件是需要生成对应的 `<link rel="preload">` 标签的。设置为 `true` 或者 `false` 来完全启用或禁用它。
|
||||
设置 [postcss-loader 配置项](https://github.com/postcss/postcss-loader#options)。
|
||||
|
||||
默认情况下,只有当前页面所需的文件会被预加载。所以在绝大部分情况下,你只需要使用 `true` 就可以了。
|
||||
## proxy
|
||||
|
||||
### shouldPrefetch
|
||||
- 类型: `object`
|
||||
- 默认值: `{}`
|
||||
- 详情:
|
||||
|
||||
- 类型: `((file: string, type: string) => boolean)) | boolean`
|
||||
配置代理能力。
|
||||
|
||||
- 示例:
|
||||
```js
|
||||
export default {
|
||||
proxy: {
|
||||
'/v2': {
|
||||
'target': 'https://api.douban.com/',
|
||||
'changeOrigin': true,
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
然后访问 `/v2/movie/in_theaters_proxy` 就能访问到 [http://api.douban.com/v2/movie/in_theaters_proxy](http://api.douban.com/v2/movie/in_theaters_proxy) 的数据。
|
||||
|
||||
## publicpath
|
||||
|
||||
- 类型: `publicPath`
|
||||
- 默认值: `/`
|
||||
- 详情:
|
||||
|
||||
配置 webpack 的 publicPath。当打包的时候,webpack 会在静态文件路径前面添加 `publicPath` 的值,当你需要修改静态文件地址时,比如使用 CDN 部署,把 `publicPath` 的值设为 CDN 的值就可以。
|
||||
|
||||
## singular
|
||||
- 类型: `boolean`
|
||||
- 默认值: `false`
|
||||
|
||||
- 详情:
|
||||
|
||||
一个函数,用来控制哪些文件是需要生成对应的 `<link rel="prefetch">` 标签的。设置为 `true` 或者 `false` 来完全启用或禁用它。
|
||||
配置是否启用单数模式的目录。 比如 `src/pages` 的约定在开启后为 `src/page` 目录,@webank/fes-plugins 插件也遵照此配置的约定。
|
||||
|
||||
如果你将它设置为 `true` ,所有其它页面所需的文件都会被预拉取。这对于小型站点来说是十分有帮助的,因为它会大大提升页面切换的速度。但是在你的网站有很多页面时不建议你这么做。
|
||||
## targets
|
||||
- 类型: `object`
|
||||
- 默认值: `{}`
|
||||
- 详情:
|
||||
|
||||
## 插件 API
|
||||
配置需要兼容的浏览器最低版本,会自动引入 polyfill 和做语法转换。
|
||||
|
||||
用户配置文件同样可以作为一个 VuePress 插件,所以除了 `name` 和 `multiple` 配置项以外的所有插件 API 都可以在配置文件中使用。
|
||||
## terserOptions
|
||||
|
||||
前往 [插件 API 参考](./plugin-api.md) 查看所有插件 API 。
|
||||
- 类型: `object`
|
||||
- 默认值:
|
||||
```js
|
||||
const defaultTerserOptions = {
|
||||
compress: {
|
||||
// turn off flags with small gains to speed up minification
|
||||
arrows: false,
|
||||
collapse_vars: false, // 0.3kb
|
||||
comparisons: false,
|
||||
computed_props: false,
|
||||
hoist_funs: false,
|
||||
hoist_props: false,
|
||||
hoist_vars: false,
|
||||
inline: false,
|
||||
loops: false,
|
||||
negate_iife: false,
|
||||
properties: false,
|
||||
reduce_funcs: false,
|
||||
reduce_vars: false,
|
||||
switches: false,
|
||||
toplevel: false,
|
||||
typeofs: false,
|
||||
|
||||
// a few flags with noticeable gains/speed ratio
|
||||
// numbers based on out of the box vendor bundle
|
||||
booleans: true, // 0.7kb
|
||||
if_return: true, // 0.4kb
|
||||
sequences: true, // 0.7kb
|
||||
unused: true, // 2.3kb
|
||||
|
||||
// required features to drop conditional branches
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true
|
||||
},
|
||||
mangle: {
|
||||
safari10: true
|
||||
}
|
||||
}
|
||||
```
|
||||
- 详情:
|
||||
|
||||
配置 [压缩器 terser 的配置项](https://github.com/terser/terser#minify-options)。
|
||||
## title
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `''`
|
||||
- 详情:
|
||||
|
||||
配置标题。
|
@ -1,7 +1,32 @@
|
||||
# @webank/fes-plugin-icon
|
||||
|
||||
## 介绍
|
||||
|
||||
提供以 `component` 的方式,直接使用 svg icon 的能力。
|
||||
## 启用方式
|
||||
|
||||
## 配置
|
||||
在 `package.json` 中引入依赖:
|
||||
```json
|
||||
{
|
||||
"dependencies": {
|
||||
"@webank/fes": "^2.0.0",
|
||||
"@webank/fes-plugin-icon": "^2.0.0"
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## API
|
||||
## 使用
|
||||
|
||||
新建 `src/icons` 目录,将 svg 文件放入其中,在 `component` 中引用:
|
||||
|
||||
```jsx
|
||||
<fes-icon type="iconName" />
|
||||
```
|
||||
|
||||
### 属性
|
||||
|
||||
| 属性 | 说明 | 类型 |
|
||||
| :-----| :---- | :---- |
|
||||
| type | svg 文件名 | `string` |
|
||||
| spin | 是否无限旋转 | `boolean` |
|
||||
| rotate | 旋转角度 | `number` |
|
||||
|
@ -1,8 +1,157 @@
|
||||
# @webank/fes-plugin-request
|
||||
|
||||
|
||||
基于 axios 封装的 request,内置防止重复请求、请求节流、错误处理等功能。
|
||||
## 启用方式
|
||||
|
||||
在 `package.json` 中引入依赖:
|
||||
```json
|
||||
{
|
||||
"dependencies": {
|
||||
"@webank/fes": "^2.0.0",
|
||||
"@webank/fes-plugin-request": "^2.0.0"
|
||||
},
|
||||
}
|
||||
```
|
||||
## 配置
|
||||
|
||||
## API
|
||||
### 构建时配置
|
||||
|
||||
```js
|
||||
export default {
|
||||
request: {
|
||||
dataField: 'result',
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
#### dataField
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `''`
|
||||
- 详情:
|
||||
|
||||
`dataField` 对应接口统一格式中的数据字段,比如接口如果统一的规范是 `{ success: boolean, result: any}` ,那么就不需要配置,这样你通过 `useRequest` 消费的时候会生成一个默认的 `formatResult`,直接返回 `result` 中的数据,方便使用。如果你的后端接口不符合这个规范,可以自行配置 `dataField`。配置为 `''`(空字符串)的时候不做处理。
|
||||
|
||||
### 运行时配置
|
||||
|
||||
在 `app.js` 中进行运行时配置。
|
||||
|
||||
```js
|
||||
export const request = {
|
||||
// 格式化 response.data (只有 response.data 类型为 object 才会调用)
|
||||
responseDataAdaptor: (data) => {
|
||||
|
||||
},
|
||||
// 请求拦截器
|
||||
requestInterceptors: [],
|
||||
// 相应拦截器
|
||||
responseInterceptors: [],
|
||||
// 错误处理
|
||||
// 内部以 reponse.data.code === '0' 判断请求是否成功
|
||||
// 若使用其他字段判断,可以使用 responseDataAdaptor 对响应数据进行格式
|
||||
errorHandler: {
|
||||
11199: (response) => {
|
||||
|
||||
},
|
||||
404: (error) => {
|
||||
|
||||
}
|
||||
},
|
||||
// 其他 axios 配置
|
||||
...otherConfigs
|
||||
}
|
||||
```
|
||||
## 使用
|
||||
|
||||
### 发起一个普通 post 请求
|
||||
|
||||
```js
|
||||
import {request} from '@webank/fes';
|
||||
|
||||
request('/api/login', {
|
||||
username: 'robby',
|
||||
password: '123456'
|
||||
}).then((res) => {
|
||||
// do something
|
||||
}).catch((err) => {
|
||||
// 处理异常
|
||||
})
|
||||
```
|
||||
|
||||
### 请求节流
|
||||
|
||||
```js
|
||||
import {request} from '@webank/fes';
|
||||
|
||||
request('/api/login', {
|
||||
username: 'robby',
|
||||
password: '123456'
|
||||
}, {
|
||||
throttle: 1000, // 1 秒内只能发起一次请求
|
||||
}).then((res) => {
|
||||
// do something
|
||||
}).catch((err) => {
|
||||
// 处理异常
|
||||
})
|
||||
```
|
||||
|
||||
### 请求缓存
|
||||
|
||||
```js
|
||||
import {request} from '@webank/fes';
|
||||
|
||||
request('/api/login', {
|
||||
username: 'robby',
|
||||
password: '123456'
|
||||
}, {
|
||||
cache: {
|
||||
cacheType: 'ram', // ram: 内存,session: sessionStorage,local:localStorage
|
||||
cacheTime: 1000 * 60 * 3 // 缓存时间,默认3min
|
||||
},
|
||||
}).then((res) => {
|
||||
// do something
|
||||
}).catch((err) => {
|
||||
// 处理异常
|
||||
})
|
||||
```
|
||||
|
||||
若 `cache` 传 `true`,则默认使用 `ram` 缓存类型,缓存时间 3min。
|
||||
|
||||
### 结合 use 使用
|
||||
|
||||
```js
|
||||
import {useRequest} from '@webank/fes';
|
||||
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
const {loading, data, error} = useRequest('/api/login', {
|
||||
username: 'robby',
|
||||
password: '123456'
|
||||
})
|
||||
|
||||
return {
|
||||
loading,
|
||||
data,
|
||||
error
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### request
|
||||
|
||||
- **类型**:函数
|
||||
|
||||
- **详情**:请求后端接口
|
||||
- **参数**:
|
||||
- url: 后端接口 url
|
||||
- data: 参数
|
||||
- options: 配置( 支持 axios 所有配置)
|
||||
- **返回值**: Promise
|
||||
|
||||
### useRequest
|
||||
|
||||
request 的封装,返回响应式 `loading`、`error`、 `data`
|
||||
|
@ -73,7 +73,6 @@ export default {
|
||||
locale.setLocale({ lang: 'en-US' });
|
||||
locale.addLocale({ lang: 'ja-JP', messages: { test: 'テスト' } });
|
||||
console.log(locale.getAllLocales());
|
||||
access.addAccess('/onepiece1');
|
||||
}, 2000);
|
||||
setTimeout(() => {
|
||||
accessId.value = '11';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { reactive, computed, inject } from "vue";
|
||||
import { reactive, unref, computed, inject } from "vue";
|
||||
import createDirective from "./createDirective";
|
||||
import createComponent from "./createComponent";
|
||||
|
||||
@ -56,12 +56,9 @@ const setAccess = (accessIds) => {
|
||||
state.currentAccessIds = accessIds;
|
||||
};
|
||||
|
||||
const addAccess = (accessId) => {
|
||||
if (typeof accessId !== 'string') {
|
||||
throw new Error("[plugin-access]: argument to the addAccess() must be string");
|
||||
}
|
||||
state.currentAccessIds.push(accessId);
|
||||
};
|
||||
const getAccess = () => {
|
||||
return state.currentAccessIds.slice(0)
|
||||
}
|
||||
|
||||
const _syncSetRoleId = (promise) => {
|
||||
rolePromiseList.push(promise);
|
||||
@ -116,12 +113,12 @@ const match = (path, accessIds) => {
|
||||
return false;
|
||||
};
|
||||
|
||||
const hasLoading = () => {
|
||||
const isDataReady = () => {
|
||||
return rolePromiseList.length || accessPromiseList.length;
|
||||
};
|
||||
|
||||
const hasAccess = async (path) => {
|
||||
if (!hasLoading()) {
|
||||
if (!isDataReady()) {
|
||||
return match(path, getAllowAccessIds());
|
||||
}
|
||||
await Promise.all(rolePromiseList.concat(accessPromiseList));
|
||||
@ -132,7 +129,7 @@ export const install = (app) => {
|
||||
const allowPageIds = computed(getAllowAccessIds);
|
||||
const useAccess = (path) => {
|
||||
const result = computed(() => {
|
||||
return match(path, allowPageIds.value);
|
||||
return match(unref(path), allowPageIds.value);
|
||||
});
|
||||
return result;
|
||||
};
|
||||
@ -143,10 +140,10 @@ export const install = (app) => {
|
||||
|
||||
export const access = {
|
||||
hasAccess,
|
||||
hasLoading,
|
||||
isDataReady,
|
||||
setRole,
|
||||
setAccess,
|
||||
addAccess
|
||||
getAccess,
|
||||
};
|
||||
|
||||
export const useAccess = (path) => {
|
||||
|
@ -3,6 +3,18 @@ import { access, install } from './core';
|
||||
|
||||
export function onRouterCreated({ router }) {
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
const runtimeConfig = plugin.applyPlugins({
|
||||
key: 'access',
|
||||
type: ApplyPluginsType.modify,
|
||||
initialValue: {}
|
||||
});
|
||||
if (to.matched.length === 0) {
|
||||
if (runtimeConfig.noFoundHandler && typeof runtimeConfig.noFoundHandler === 'function') {
|
||||
return runtimeConfig.noFoundHandler({
|
||||
router, to, from, next
|
||||
});
|
||||
}
|
||||
}
|
||||
let path;
|
||||
if (to.matched.length === 1) {
|
||||
path = to.matched[0].path;
|
||||
@ -11,21 +23,14 @@ export function onRouterCreated({ router }) {
|
||||
}
|
||||
const canRoute = await access.hasAccess(path);
|
||||
if (canRoute) {
|
||||
next();
|
||||
} else {
|
||||
const runtimeConfig = plugin.applyPlugins({
|
||||
key: 'access',
|
||||
type: ApplyPluginsType.modify,
|
||||
initialValue: {}
|
||||
});
|
||||
if (runtimeConfig.noAccessHandler && typeof runtimeConfig.noAccessHandler === 'function') {
|
||||
runtimeConfig.noAccessHandler({
|
||||
router, to, from, next
|
||||
});
|
||||
} else {
|
||||
next(false);
|
||||
}
|
||||
return next();
|
||||
}
|
||||
if (runtimeConfig.unAccessHandler && typeof runtimeConfig.unAccessHandler === 'function') {
|
||||
return runtimeConfig.unAccessHandler({
|
||||
router, to, from, next
|
||||
});
|
||||
}
|
||||
next(false);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,8 @@ export default (api) => {
|
||||
|
||||
const absFilePath = join(namespace, 'index.js');
|
||||
|
||||
const absRuntimeFilePath = join(namespace, 'runtime.js');
|
||||
|
||||
api.onGenerateFiles(() => {
|
||||
const { name } = api.pkg;
|
||||
|
||||
@ -53,6 +55,7 @@ export default (api) => {
|
||||
});
|
||||
});
|
||||
|
||||
api.addRuntimePlugin(() => `@@/${absRuntimeFilePath}`);
|
||||
|
||||
// 把BaseLayout插入到路由配置中,作为根路由
|
||||
api.modifyRoutes(routes => [
|
||||
|
@ -27,7 +27,7 @@ const matchPath = (config, path) => {
|
||||
for (let i = 0; i < config.length; i++) {
|
||||
const item = config[i];
|
||||
if (item.path && item.path === path) {
|
||||
res = item.meta;
|
||||
res = item.meta || {};
|
||||
res.path = item.path;
|
||||
break;
|
||||
}
|
||||
|
@ -7,29 +7,29 @@ if (!useAccess) {
|
||||
);
|
||||
}
|
||||
|
||||
const hasAccess = (item) => {
|
||||
export const hasAccessByMenuItem = (item) => {
|
||||
let res;
|
||||
if (item.path && (!item.children || item.children.length === 0)) {
|
||||
res = useAccess(item.path);
|
||||
} else if (item.children && item.children.length > 0) {
|
||||
res = computed(() => item.children.some(child => hasAccess(child)));
|
||||
res = computed(() => item.children.some(child => hasAccessByMenuItem(child)));
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
const addAcessTag = (arr) => {
|
||||
const _addAccessTag = (arr) => {
|
||||
if (Array.isArray(arr)) {
|
||||
arr.forEach((item) => {
|
||||
item.access = hasAccess(item);
|
||||
item.access = hasAccessByMenuItem(item);
|
||||
if (item.children && item.children.length > 0) {
|
||||
addAcessTag(item.children);
|
||||
_addAccessTag(item.children);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default function (menus) {
|
||||
export const addAccessTag = (menus) => {
|
||||
const originData = unref(menus);
|
||||
addAcessTag(originData);
|
||||
_addAccessTag(originData);
|
||||
return originData;
|
||||
}
|
||||
};
|
69
packages/fes-plugin-layout/src/runtime/runtime.js
Normal file
69
packages/fes-plugin-layout/src/runtime/runtime.js
Normal file
@ -0,0 +1,69 @@
|
||||
import { plugin, ApplyPluginsType } from '@@/core/coreExports';
|
||||
import { access as accessApi } from '../plugin-access/core';
|
||||
import Exception404 from './views/404';
|
||||
import Exception403 from './views/403';
|
||||
|
||||
if (!accessApi) {
|
||||
throw new Error(
|
||||
'[plugin-layout]: pLugin-layout depends on plugin-access,please install plugin-access first!'
|
||||
);
|
||||
}
|
||||
|
||||
const handle = (type, router) => {
|
||||
const accesssIds = accessApi.getAccess();
|
||||
const path = `/${type}`;
|
||||
const name = `Exception${type}`;
|
||||
const components = {
|
||||
404: Exception404,
|
||||
403: Exception403
|
||||
};
|
||||
if (!accesssIds.includes(path)) {
|
||||
accessApi.setAccess(accesssIds.concat([path]));
|
||||
}
|
||||
if (!router.hasRoute(name)) {
|
||||
router.addRoute({ path, name, component: components[type] });
|
||||
}
|
||||
};
|
||||
|
||||
export const access = {
|
||||
unAccessHandler({
|
||||
router, to, from, next
|
||||
}) {
|
||||
const runtimeConfig = plugin.applyPlugins({
|
||||
key: 'layout',
|
||||
type: ApplyPluginsType.modify,
|
||||
initialValue: {}
|
||||
});
|
||||
if (runtimeConfig.unAccessHandler && typeof runtimeConfig.unAccessHandler === 'function') {
|
||||
return runtimeConfig.unAccessHandler({
|
||||
router, to, from, next
|
||||
});
|
||||
}
|
||||
if (to.path === '/404') {
|
||||
handle(404, router);
|
||||
return next('/404');
|
||||
}
|
||||
handle(403, router);
|
||||
next('/403');
|
||||
},
|
||||
noFoundHandler({
|
||||
router, to, from, next
|
||||
}) {
|
||||
const runtimeConfig = plugin.applyPlugins({
|
||||
key: 'layout',
|
||||
type: ApplyPluginsType.modify,
|
||||
initialValue: {}
|
||||
});
|
||||
if (runtimeConfig.noFoundHandler && typeof runtimeConfig.noFoundHandler === 'function') {
|
||||
return runtimeConfig.noFoundHandler({
|
||||
router, to, from, next
|
||||
});
|
||||
}
|
||||
if (to.path === '/403') {
|
||||
handle(403, router);
|
||||
return next('/403');
|
||||
}
|
||||
handle(404, router);
|
||||
next('/404');
|
||||
}
|
||||
};
|
35
packages/fes-plugin-layout/src/runtime/views/403.vue
Normal file
35
packages/fes-plugin-layout/src/runtime/views/403.vue
Normal file
@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<a-result status="403" title="403" sub-title="对不起,您没有权限访问此页面。">
|
||||
<template #extra>
|
||||
<a-button type="primary" @click="click">上一页</a-button>
|
||||
</template>
|
||||
</a-result>
|
||||
</template>
|
||||
<config>
|
||||
{
|
||||
"layout": false
|
||||
}
|
||||
</config>
|
||||
<script>
|
||||
import { useRouter } from '@@/core/coreExports';
|
||||
import Result from 'ant-design-vue/lib/result';
|
||||
import 'ant-design-vue/lib/result/style';
|
||||
import Button from 'ant-design-vue/lib/button';
|
||||
import 'ant-design-vue/lib/button/style';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
[Result.name]: Result,
|
||||
[Button.name]: Button
|
||||
},
|
||||
setup() {
|
||||
const router = useRouter();
|
||||
const click = () => {
|
||||
router.back();
|
||||
};
|
||||
return {
|
||||
click
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
35
packages/fes-plugin-layout/src/runtime/views/404.vue
Normal file
35
packages/fes-plugin-layout/src/runtime/views/404.vue
Normal file
@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<a-result status="404" title="404" sub-title="对不起,您访问的页面不存在。">
|
||||
<template #extra>
|
||||
<a-button type="primary" @click="click">上一页</a-button>
|
||||
</template>
|
||||
</a-result>
|
||||
</template>
|
||||
<config>
|
||||
{
|
||||
"layout": false
|
||||
}
|
||||
</config>
|
||||
<script>
|
||||
import { useRouter } from '@@/core/coreExports';
|
||||
import Result from 'ant-design-vue/lib/result';
|
||||
import 'ant-design-vue/lib/result/style';
|
||||
import Button from 'ant-design-vue/lib/button';
|
||||
import 'ant-design-vue/lib/button/style';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
[Result.name]: Result,
|
||||
[Button.name]: Button
|
||||
},
|
||||
setup() {
|
||||
const router = useRouter();
|
||||
const click = () => {
|
||||
router.back();
|
||||
};
|
||||
return {
|
||||
click
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<a-menu
|
||||
:selectedKeys="selectedKeys"
|
||||
@click="onMenuClick"
|
||||
:theme="theme"
|
||||
mode="inline"
|
||||
@click="onMenuClick"
|
||||
>
|
||||
<template v-for="(item, index) in menus" :key="index">
|
||||
<template v-for="(item, index) in fixedMenus" :key="index">
|
||||
<template v-if="item.access">
|
||||
<a-sub-menu v-if="item.children" :title="item.title">
|
||||
<template
|
||||
@ -52,7 +52,7 @@ import 'ant-design-vue/lib/menu/style';
|
||||
import {
|
||||
UserOutlined
|
||||
} from '@ant-design/icons-vue';
|
||||
import addAccessTag from '../helpers/addAccessTag';
|
||||
import { addAccessTag } from '../helpers/pluginAccess';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@ -93,7 +93,7 @@ export default {
|
||||
const selectedKeys = computed(() => [route.path]);
|
||||
return {
|
||||
selectedKeys,
|
||||
menus: fixedMenus,
|
||||
fixedMenus,
|
||||
onMenuClick
|
||||
};
|
||||
}
|
||||
|
@ -1,18 +1,18 @@
|
||||
<template>
|
||||
<a-tabs
|
||||
:activeKey="route.path"
|
||||
@tabClick="switchPage"
|
||||
class="layout-content-tabs"
|
||||
hide-add
|
||||
type="editable-card"
|
||||
@tabClick="switchPage"
|
||||
>
|
||||
<a-tab-pane v-for="page in pageList" :key="page.path" closable>
|
||||
<template #tab>
|
||||
{{page.name}}
|
||||
<ReloadOutlined
|
||||
v-show="route.path === page.path"
|
||||
@click="reloadPage(page.path)"
|
||||
class="layout-tabs-close-icon"
|
||||
@click="reloadPage(page.path)"
|
||||
/>
|
||||
</template>
|
||||
</a-tab-pane>
|
||||
@ -36,7 +36,7 @@
|
||||
</a-tabs>
|
||||
<router-view v-slot="{ Component, route }">
|
||||
<keep-alive>
|
||||
<component :key="getPageKey(route)" :is="Component" />
|
||||
<component :is="Component" :key="getPageKey(route)" />
|
||||
</keep-alive>
|
||||
</router-view>
|
||||
</template>
|
||||
|
@ -84,8 +84,6 @@ export function trimObj(obj) {
|
||||
obj[key] = value.trim();
|
||||
} else if (isObject(value)) {
|
||||
trimObj(value);
|
||||
} else if (Array.isArray(value)) {
|
||||
trimObj(value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -46,7 +46,6 @@ async function axiosMiddleware(context, next) {
|
||||
function getRequestInstance() {
|
||||
const {
|
||||
responseDataAdaptor,
|
||||
errorConfig,
|
||||
requestInterceptors = [],
|
||||
responseInterceptors = [],
|
||||
errorHandler,
|
||||
@ -82,7 +81,6 @@ function getRequestInstance() {
|
||||
defaultConfig,
|
||||
dataField: REPLACE_DATA_FIELD, // eslint-disable-line
|
||||
responseDataAdaptor,
|
||||
errorConfig,
|
||||
errorHandler
|
||||
},
|
||||
request: scheduler.compose()
|
||||
|
@ -43,6 +43,7 @@ export default function () {
|
||||
require.resolve('./plugins/features/nodeModulesTransform'),
|
||||
require.resolve('./plugins/features/vueLoader'),
|
||||
require.resolve('./plugins/features/mock'),
|
||||
require.resolve('./plugins/features/dynamicImport'),
|
||||
|
||||
// misc
|
||||
require.resolve('./plugins/misc/route'),
|
||||
|
@ -0,0 +1,12 @@
|
||||
|
||||
export default (api) => {
|
||||
api.describe({
|
||||
key: 'dynamicImport',
|
||||
config: {
|
||||
schema(joi) {
|
||||
return joi.boolean();
|
||||
}
|
||||
},
|
||||
default: false
|
||||
});
|
||||
};
|
@ -57,14 +57,15 @@ const getRoutePath = function (parentRoutePath, fileName) {
|
||||
if (fileName === 'index') {
|
||||
fileName = '';
|
||||
}
|
||||
let routePath = posix.join(parentRoutePath, fileName);
|
||||
// /@id.vue -> /:id
|
||||
routePath = routePath.replace(/@/g, ':');
|
||||
// /*.vue -> *
|
||||
if (routePath === '/*') {
|
||||
routePath = '*';
|
||||
if (fileName.startsWith('@')) {
|
||||
fileName = fileName.replace(/@/, ':');
|
||||
}
|
||||
return routePath;
|
||||
// /*.vue -> :pathMatch(.*)
|
||||
if (fileName.includes('*')) {
|
||||
fileName = fileName.replace('*', ':pathMatch(.*)');
|
||||
}
|
||||
return posix.join(parentRoutePath, fileName);
|
||||
};
|
||||
|
||||
// TODO 约定 layout 目录作为布局文件夹,
|
||||
@ -140,7 +141,7 @@ const genRoutes = function (parentRoutes, path, parentRoutePath, config) {
|
||||
|
||||
* @param {*} routes
|
||||
*/
|
||||
const fix = function (routes) {
|
||||
const rank = function (routes) {
|
||||
routes.forEach((item) => {
|
||||
const path = item.path;
|
||||
let arr = path.split('/');
|
||||
@ -150,9 +151,9 @@ const fix = function (routes) {
|
||||
let count = 0;
|
||||
arr.forEach((sonPath) => {
|
||||
count += 4;
|
||||
if (sonPath.indexOf(':') !== -1) {
|
||||
if (sonPath.indexOf(':') !== -1 && sonPath.indexOf(':pathMatch(.*)') === -1) {
|
||||
count += 2;
|
||||
} else if (sonPath.indexOf('*') !== -1) {
|
||||
} else if (sonPath.indexOf(':pathMatch(.*)') !== -1) {
|
||||
count -= 1;
|
||||
} else if (sonPath === '') {
|
||||
count += 1;
|
||||
@ -162,7 +163,7 @@ const fix = function (routes) {
|
||||
});
|
||||
item.count = count;
|
||||
if (item.children && item.children.length) {
|
||||
fix(item.children);
|
||||
rank(item.children);
|
||||
}
|
||||
});
|
||||
routes = routes.sort((a, b) => b.count - a.count);
|
||||
@ -175,7 +176,7 @@ const getRoutes = function ({ config, absPagesPath }) {
|
||||
|
||||
const routes = [];
|
||||
genRoutes(routes, absPagesPath, '/', config);
|
||||
fix(routes);
|
||||
rank(routes);
|
||||
return routes;
|
||||
};
|
||||
|
||||
|
@ -12,7 +12,7 @@ export default {
|
||||
publicPath: '/',
|
||||
access: {
|
||||
roles: {
|
||||
admin: ["/", "/onepiece", '/store']
|
||||
admin: ["/"]
|
||||
}
|
||||
},
|
||||
request: {
|
||||
@ -52,5 +52,6 @@ export default {
|
||||
},
|
||||
vuex: {
|
||||
strict: true
|
||||
}
|
||||
},
|
||||
dynamicImport: true
|
||||
};
|
||||
|
@ -1,13 +1,13 @@
|
||||
|
||||
|
||||
import { access } from '@webank/fes';
|
||||
import { access as accessApi } from '@webank/fes';
|
||||
import PageLoading from '@/components/PageLoading';
|
||||
import UserCenter from '@/components/UserCenter';
|
||||
|
||||
export const beforeRender = {
|
||||
loading: <PageLoading />,
|
||||
action() {
|
||||
const { setRole } = access;
|
||||
const { setRole } = accessApi;
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
setRole('admin');
|
||||
@ -21,4 +21,10 @@ export const beforeRender = {
|
||||
|
||||
export const layout = {
|
||||
customHeader: <UserCenter />
|
||||
// unAccessHandler({ next }) {
|
||||
// next(false);
|
||||
// },
|
||||
// noFoundHandler({ next }) {
|
||||
// next(false);
|
||||
// }
|
||||
};
|
||||
|
@ -81,12 +81,10 @@ export default {
|
||||
locale.setLocale({ lang: 'en-US' });
|
||||
locale.addLocale({ lang: 'ja-JP', messages: { test: 'テスト' } });
|
||||
console.log(locale.getAllLocales());
|
||||
access.addAccess('/onepiece1');
|
||||
}, 2000);
|
||||
setTimeout(() => {
|
||||
accessId.value = '11';
|
||||
}, 4000);
|
||||
// router.push('/onepiece');
|
||||
|
||||
console.log('测试 mock!!');
|
||||
request('/v2/file').then((data) => {
|
||||
|
34
yarn.lock
34
yarn.lock
@ -8149,6 +8149,11 @@ es-module-lexer@^0.4.0:
|
||||
resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.4.1.tgz#dda8c6a14d8f340a24e34331e0fab0cb50438e0e"
|
||||
integrity sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA==
|
||||
|
||||
es-module-lexer@^0.4.0:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.4.1.tgz#dda8c6a14d8f340a24e34331e0fab0cb50438e0e"
|
||||
integrity sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA==
|
||||
|
||||
es-to-primitive@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a"
|
||||
@ -17408,6 +17413,35 @@ webpack@^5.21.2, webpack@^5.24.2:
|
||||
watchpack "^2.0.0"
|
||||
webpack-sources "^2.1.1"
|
||||
|
||||
webpack@^5.24.2:
|
||||
version "5.24.3"
|
||||
resolved "https://registry.npmjs.org/webpack/-/webpack-5.24.3.tgz#6ec0f5059f8d7c7961075fa553cfce7b7928acb3"
|
||||
integrity sha512-x7lrWZ7wlWAdyKdML6YPvfVZkhD1ICuIZGODE5SzKJjqI9A4SpqGTjGJTc6CwaHqn19gGaoOR3ONJ46nYsn9rw==
|
||||
dependencies:
|
||||
"@types/eslint-scope" "^3.7.0"
|
||||
"@types/estree" "^0.0.46"
|
||||
"@webassemblyjs/ast" "1.11.0"
|
||||
"@webassemblyjs/wasm-edit" "1.11.0"
|
||||
"@webassemblyjs/wasm-parser" "1.11.0"
|
||||
acorn "^8.0.4"
|
||||
browserslist "^4.14.5"
|
||||
chrome-trace-event "^1.0.2"
|
||||
enhanced-resolve "^5.7.0"
|
||||
es-module-lexer "^0.4.0"
|
||||
eslint-scope "^5.1.1"
|
||||
events "^3.2.0"
|
||||
glob-to-regexp "^0.4.1"
|
||||
graceful-fs "^4.2.4"
|
||||
json-parse-better-errors "^1.0.2"
|
||||
loader-runner "^4.2.0"
|
||||
mime-types "^2.1.27"
|
||||
neo-async "^2.6.2"
|
||||
schema-utils "^3.0.0"
|
||||
tapable "^2.1.1"
|
||||
terser-webpack-plugin "^5.1.1"
|
||||
watchpack "^2.0.0"
|
||||
webpack-sources "^2.1.1"
|
||||
|
||||
webpackbar@^5.0.0-3:
|
||||
version "5.0.0-3"
|
||||
resolved "https://registry.npmjs.org/webpackbar/-/webpackbar-5.0.0-3.tgz#f4f96c8fb13001b2bb1348252db4c980ab93aaac"
|
||||
|
Loading…
x
Reference in New Issue
Block a user