文档更新

master
toesbieya 6 years ago
parent 5030e3db57
commit 7532c837a1
  1. 2
      docs/.vuepress/config.js
  2. BIN
      docs/.vuepress/public/abstract-table.png
  3. BIN
      docs/.vuepress/public/search-form_1.png
  4. BIN
      docs/.vuepress/public/search-form_2.png
  5. 2
      docs/backend/README.md
  6. 26
      docs/frontend/components/abstract-table.md
  7. 63
      docs/frontend/components/abstract.md
  8. 1
      docs/frontend/components/region-selector.md
  9. 50
      docs/frontend/components/search-form.md
  10. 9
      docs/frontend/layout.md
  11. 7
      docs/frontend/mock.md
  12. 14
      docs/frontend/permission.md
  13. 6
      docs/frontend/plugins.md
  14. 52
      docs/frontend/router.md

@ -35,7 +35,7 @@ module.exports = {
{
title: '组件',
children: [
'/frontend/components/abstract-table',
'/frontend/components/abstract',
'/frontend/components/region-selector',
'/frontend/components/search-form',
'/frontend/components/upload-file',

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

@ -10,4 +10,4 @@ cloud版基于SpringBoot、SpringCloud、SpringCloudAlibaba、SpringMVC、Mybati
目前两者在功能上的差别就是local版支持动态修改资源的限流设置,而cloud版由于还在研究sentinel中,
所以还未实现,暂时以gateway的 `default-filters` 作为替代。
*文档完善中。。。*
具体文档不写啦,代码写得太垃圾了。。。

@ -1,26 +0,0 @@
# Abstract Table
<img :src="$withBase('/abstract-table.png')">
给`<el-table>`设置了一些默认属性,设置了`empty`插槽。
```html
<el-table
ref="table"
current-row-key="id"
row-key="id"
highlight-current-row
{...data}
>
{children}
<Empty slot="empty"/>
</el-table>
```
### 引入:
`@/component/AbstractTable`
### 使用:
照着官方文档,当成 `<el-table>` 用就行。

@ -0,0 +1,63 @@
# 二次封装的element-ui组件
这些组件位于 `@/component/abstract` 下,均为函数式组件,无特殊声明时与原始的 `element-ui` 组件没有区别。
## Dialog
位于 `@/component/abstract/Dialog/index.vue`
可拖拽,超出滚动(使用 `el-scrollbar`),使用 `value`(支持 `v-model`) 代替 `visible`,新增了 `loading` 属性。
## Form
位于 `@/component/abstract/Form`
`el-form``el-form-item` 做了默认封装(`index.vue` 和 `item.vue`),使用 `el-row``el-col` 包裹。
用法:
```vue
<abstract-form :model="model" :rules="rules">
<abstract-form-item label="xxx" prop="xxx">
<el-input/>
</abstract-form-item>
</abstract-form>
```
`abstract-form` 的其他用法与 `el-form` 没有区别,`abstract-form-item` 参数如下:
| 名称 | 说明 | 类型 | 默认值 |
|:-----:|:--------------------------------------:|:-------:|:------:|
| full | 为 `true` 时,将占满一行 | Boolean | - |
| thin | 为 `true` 时,屏幕宽度>=1200px下占12列 | Boolean | - |
| label | 等同于 `el-form-item``label` | String | - |
| prop | 等同于 `el-form-item``prop` | String | - |
::: tip 注意
`abstract-form-item``full``true` 时,可以认为是 `el-form-item` 的子集
:::
## Pagination
位于 `@/component/abstract/Pagination/index.vue`
设置了一些默认属性,与 `el-pagination` 的区别是增加了 `model` 属性,
`model` 是一个 `{total, page, pageSize}` 对象,对应 `el-pagination``total`、`current-page`、`page-size` 属性
## Table
位于 `@/component/abstract/Table/index.vue`
`<el-table>` 设置了一些默认属性,设置了 `empty` 插槽(位于 `@/component/Empty`)。
```html
<el-table
ref="table"
current-row-key="id"
row-key="id"
highlight-current-row
{...data}
>
{children}
<Empty slot="empty"/>
</el-table>
```

@ -20,6 +20,7 @@
| 参数 | 说明 | 类型 | 默认 |
| :-----------------: | :-------------------------------------: | :--------------: | :-----: |
| type | 选择器类型,`tab / tree` | `string` | `'tab'` |
| regionDataUrl | 行政区域json的请求地址 | `string` | `${process.env.BASE_URL}static/json/region-pca.json` |
| value / v-model | 绑定值 | `string / array` | - |
| readonly | 等同于`el-select`的`disabled` | `boolean` | - |
| size | 等同于`el-select`的`size` | `string` | - |

@ -1,59 +1,45 @@
# Search Form
一个自适应的表单容器,根据父元素的内宽来确定一行渲染多少个表单控件,同时确定是否需要折叠。
一个自适应的搜索表单,模仿ant-design-pro,根据父元素的内宽来确定一行渲染多少个表单控件,同时确定是否需要折叠。
<img :src="$withBase('/search-form_1.png')">
<img :src="$withBase('/search-form_2.png')">
### 引入:
`@/component/SearchForm`,`@/component/SearchFormItem`
`@/component/SearchForm`
### 使用:
```html
<search-form>
<search-form-item label="单 号:">
<search-form v-model="searchForm" @search="search">
<el-form-item label="label1">
<el-input/>
</search-form-item>
<search-form-item label="采购订单:">
</el-form-item>
<el-form-item label="label2">
<el-input/>
</search-form-item>
<search-form-item label="创建人:">
<el-input/>
</search-form-item>
<search-form-item label="创建时间:">
<el-date-picker/>
</search-form-item>
<search-form-item label="审核人:">
<el-input/>
</search-form-item>
<search-form-item label="审核时间:">
<el-date-picker/>
</search-form-item>
<search-form-item label="状 态:">
<el-select/>
</search-form-item>
</el-form-item>
</search-form>
```
### SearchForm Attributes:
| 参数 | 说明 | 类型 | 默认 |
| :-----------------: | :----------------------------------: | :------: | :-------: |
| :---------: | :----------------------------------: | :------: | :-------: |
| model | 表单数据,支持v-model,用于重置表单 | `object` | - |
| label-width | 等同于 `el-form``label-width` | `string` | `'120px'` |
| xs | 父元素内宽<768px时每行渲染多少空间 | `number` | `1` |
| sm | >=768px | `number` | `2` |
| md | >=998px | `number` | `3` |
| lg | >=1200px | `number` | `4` |
### SearchForm Slots:
### SearchForm Events:
| 名称 | 说明 |
| :------: | :---------------------------------------------------------------------: |
| collapse | 折叠按钮,参数为 `{collapse:展开为true否则false,handle:展开折叠的方法}` |
### SearchFormItem Attributes:
| 参数 | 说明 | 类型 | 默认 |
| :---: | :---------------------------: | :------: | :-------: |
| label | 等同于`el-form-item`的`label` | `string` | - |
| :----: | :--------------------------------: |
| search | 点击查询按钮触发 |
| reset | 点击重置按钮触发,参数为表单初始值 |
::: tip 注意
`<search-form>` 算是对 `<el-form>` 的封装,其 `label-suffix` 属性为`':'`,
也就是说 `<search-form>` 下的所有 `<el-form-item>` 项的label后缀为`':'`
:::

@ -2,11 +2,11 @@
<img :src="$withBase('/布局.png')">
文件目录:`@/layout/index.vue`。
布局也是一个组件,比较重型而已,文件目录:`@/layout/index.vue`。
此布局是在vue-element-admin的基础上改造而来,并且模仿and design pro实现了三种导航模式。
实际上这个布局算是二级路由,一级路由是App.vue,这就是为什么经常会看到路由会这么写的原因:
实际上这个布局算是二级路由,一级路由是 `App.vue`,这就是为什么经常会看到路由会这么写的原因:
```json
{
"path": "/",
@ -15,8 +15,7 @@
{
"path": "index",
"name": "index",
"component": Page,
"meta": {"title": "首页"}
"component": Page
}
]
}
@ -124,6 +123,6 @@ PC端的行为是切换侧边栏的折叠状态,移动端是切换侧边栏在
只是一个静态dom,想咋改就咋改。
目前页脚全局显示,没有提供配置来隐藏。
目前页脚全局显示,没有提供配置来隐藏,不想显示的直接删除即可

@ -1,8 +1,7 @@
# mock
如果不想依赖后端的话,需要将 `@/config` 中的 `useMock` 设为true,
同时在 `@/mock/controller` 里写对应的处理路由,项目中预先写了三个
基础的路由,可以让你进行 *登陆-登出* 的基础操作,可以照着代码自行扩展。
同时在 `@/mock/controller` 里写对应的处理路由,项目中预先写了三个基础的路由,
可以让你进行 *登陆-登出* 的基础操作,可以照着代码自行扩展。
目前mock和代理不能共存,如果真想要这个功能的话,需要自己在`vue.config.js`
中的 `devServer.proxy` 设置拦截路径。
目前mock和代理不能共存,如果真想要这个功能的话,需要自己在`vue.config.js` 中的 `devServer.proxy` 设置拦截路径。

@ -1,13 +1,21 @@
# 权限
本前端项目里需要用到权限控制的地方有两个:
1. 路由页面的跳转
源码位于 `@/router/guardian/accessControl.js`,再说明一点,不需要登录的路由也不需要进行权限控制
2. 按钮
一般使用 `v-if` 或者 `render` 做,尽量不使用 `display: none`,如果不得已那么需要在按钮方法里控制
项目使用基于资源url的形式来实现权限控制,说白点就是用户的所有操作都可以用一个url来标识。
鉴权方法为 `@/util/auth.js #auth`
### 鉴权前的准备工作
登陆成功后,后台返回用户所拥有的资源,构造出用户的权限树。
之后用户在进入系统的任意一个非白名单内的路由时,会向后台获取所有的资源,构造出总权限树。
登陆成功,后台返回用户所拥有的资源,构造出用户的权限树。
之后用户在进入系统的任意一个需要登录才可访问的路由时,会向后台获取所有的资源,构造出总权限树(同时渲染菜单)
### 鉴权流程
@ -23,7 +31,7 @@
### 如何移除权限控制?
前端的权限控制的方法全在 `@/util/auth.js` 里面,哪里引入就改哪里,粗暴点直接把`# auth`方法返回true就完事了。
前端的权限控制的方法全在 `@/util/auth.js` 里面,哪里引入就改哪里,粗暴点直接`# auth` 方法返回true就完事了。
后端的权限控制由拦截器实现,同样的改造原理,easy啦。
### 为什么不是RBAC?

@ -1,11 +1,11 @@
# 插件
这里放的是即使删掉也不会影响运行的东东,基本都通过`import().then()`的方式来引用。
`@/plugin`放的是即使删掉也不会影响运行的东东,都通过`import().then()`的方式来引用。
## canvas动画
所有动画位于 `@/plugin/canvasAnimation`下,使用 `new Animation(canvas)`的方式来创建一个动画。
想停止的话调用 `Animation.stop()` 即可。
所有动画位于 `@/plugin/canvasAnimation`下,每一个文件夹都会导出一个`Animation`对象,
使用 `new Animation(canvas)`的方式来创建一个动画,想停止的话调用 `Animation.stop()` 即可。
## 图片压缩

@ -54,23 +54,25 @@ const routes = [
本项目的路由配置除了`component`以外,与`vue-router`没有区别,仅在`meta`中添加了一些用于生成路由和菜单的字段。
这里约定,配置项中只有根节点(即顶部菜单)的path以'/'开头,并且,只有根节点和叶子节点可以自定义`component`。
当使用前端定义路由时(`@/config`中`route.useBackendDataAsRoute`为`false`),`component`可以是字符串,
也可以是一个返回`Promise`的函数,比如`() => import('xxx')`,否则只能为字符串。
目前根节点的`component`固定为`'Layout'`。
当`component`为字符串时,比如组件路径是`@/view/test/indexPage.vue`,
那么值可以是`test/`、`test/index`、`test/indexPage`、`test/indexPage.vue`,
具体可以看`@/router/util.js` 中的 `generateRoutes` 方法。
此外,所有根节点(经过降级缩减)的`redirect`属性都将设为其第一个子节点的`fullPath`,目前不支持自定义。
这里约定,配置项中只有根节点的path以'/'开头(这也是`vue-router`所要求的),并且只有根节点和叶子节点可以自定义`component`
::: warning 注意
路由配置项中的`component`是字符串,比如组件路径是`@/view/test/indexPage.vue`,那么component可以是
`test/`、`test/index`、`test/indexPage`、`test/indexPage.vue`,具体可以看`@/router/util.js` 中的 `generateRoutes` 方法。
:::
目前根节点的`component`固定为`Layout`。
此外,所有根节点(经过降级缩减)的`redirect`属性都将设为其第一个子节点的`fullPath`,`redirect`有值的不作处理。
### Route.meta Attributes:
| 参数 | 说明 | 类型 | 默认 |
| :------------: | :--------------------------------------------------: | :--------: | :---: |
| title | 路由在侧边栏、面包屑、页签 | `string` | - |
| title | 路由在侧边栏、面包屑、页签的名称 | `string` | - |
| dynamicTitle | 路由在面包屑、页签中的动态名称,参数为(to,from) | `function` | - |
| hidden | 是否在菜单中隐藏 | `boolean` | - |
| alwaysShow | 是否总是把只有一个子级的菜单以嵌套模式展示 | `boolean` | - |
@ -92,7 +94,7 @@ const routes = [
## 页面缓存
先总结一下路由页面被缓存的条件:
- 启用了多页签
- 启用了多页签(`@/layout/store/tagsView.js`中的`enabled`为`true`)
- `(route.name || route.meta.usePathKey || route.meta.useFullPathKey) && !route.meta.noCache && !route.meta.iframe`
通常情况路由想做缓存都是通过 `<keep-alive>`,但是如果是像 `/edit/1`、`/edit/2` 这样的共用路由页面的详情页的话,
@ -109,20 +111,22 @@ const routes = [
]
```
先访问 `/foo`,然后将输入框的值改为100,再访问 `/bar` ,会发现输入框的值还是100。
所以在 `router.beforeEach` 中做了判断,如果跳转前后的路由的 `meta.commonModule` 相同的话,那么借助 `/redirect` 跳转一次,从而避免组件复用的问题
所以在 `router.beforeEach` 中做了判断,如果跳转前后的路由的 `meta.commonModule` 相同的话,
那么借助 `/redirect` 跳转一次,从而避免组件复用的问题
::: warning 注意
如果使用`name`作为组件缓存的标识,那么缓存的页面的`name`必须和路由的`name`一致
:::
## 路由白名单
## 路由免登陆
`@/router/guardian/security.js` 中有这么一句:
`@/router/guardian/accessControl.js` 中有这么一句:
```js
const whiteList = ['/login', '/register', '/403', '/404', '/500'].map(url => pathToRegexp(url))
const noLoginList = ['/login', '/register', '/403', '/404', '/500']
```
这个`whiteList`就是白名单,里面的值会被转为正则表达式,详细请查看[path-to-regexp文档](https://github.com/pillarjs/path-to-regexp)。
被白名单匹配的路由不需要验证,直接放行。
被`noLoginList`匹配的路由不需要登录(同样也不需要鉴权),直接放行。
一般来说,不需要登录即可访问的路由都不以`Layout`作为组件,并且这东东基本不需要修改。
## 路由守卫
@ -160,7 +164,7 @@ const whiteList = ['/login', '/register', '/403', '/404', '/500'].map(url => pat
<img :src="$withBase('/路由和菜单-骨架屏.png')">
通常情况下,路由组件都是以 `import(...)` 的形式异步引入,
通常情况下,路由组件都是以 `() => import(...)` 的形式异步引入,
如果想让路由在加载异步组件时显示,可以使用以下方式:
```js
function lazyLoadView(component) {
@ -176,9 +180,9 @@ function lazyLoadView(component) {
//将路由配置中的component项改为以下形式
component: lazyLoadView(import(...))
```
项目中具体的使用方式可以查看 `@/router/util #generateRoutes`方法。
[这是vue-router的官方文档](https://github.com/vuejs/vue-router/pull/2140/files) ,项目中具体的使用方式可以查看 `@/router/util #generateRoutes`方法。
关于 `AsyncHandler` 的更多选项,可以查看[官方文档](https://cn.vuejs.org/v2/guide/component-dynamic-async.html#%E5%A4%84%E7%90%86%E5%8A%A0%E8%BD%BD%E7%8A%B6%E6%80%81)
关于 `AsyncHandler` 的更多选项,可以查看[vue官方文档](https://cn.vuejs.org/v2/guide/component-dynamic-async.html#%E5%A4%84%E7%90%86%E5%8A%A0%E8%BD%BD%E7%8A%B6%E6%80%81)
## 过渡动画
@ -193,8 +197,8 @@ component: lazyLoadView(import(...))
但是由于项目中使用了自定义的 `<keep-router-view-alive>`,所以就变成这样的:
```html
<keep-router-view-alive :include="cachedViews">
<transition :name="transitionName" mode="out-in">
<keep-router-view-alive>
<transition>
<router-view>
</transition>
</keep-router-view-alive>
@ -202,7 +206,7 @@ component: lazyLoadView(import(...))
具体原因是 `<transition>` 中的代码硬编码了 `<keep-alive>`,导致如果按照往常写法的话,过渡动画不会生效。
项目中是根据页签的前后位置来决定路由动画的,比如从前面的页签跳转到后面的,那么动画是从左滑出,反之是从右滑出。
项目中是根据页签的前后位置来决定路由动画的,比如从前面的页签跳转到后面的,那么动画是从左滑出,反之是从右滑出,源码位于`@/layout/mixin/decideRouterTransition.js`
::: warning 注意
只有在启用了多页签的时候才会有上面的效果,否则默认是 `@/config/index.js` 中的 `route.animate.default` 动画。
@ -227,7 +231,9 @@ iframe页面的缓存与普通页面相同,都是使用 `meta.noCache` 控制
## 外链
也可以在路由中配置一个外链,只要在 path 中填写了合法的 url 路径,当你点击该路由菜单时就会新开这个页面。
也可以在路由中配置一个外链,只要在 `path` 中填写了以 `'http'` 开头的路径,当你点击该路由菜单时就会新开这个页面。
外链**只**存在与菜单中,**不会**被 `vue-router` 识别。
例如:
```json
@ -241,5 +247,5 @@ iframe页面的缓存与普通页面相同,都是使用 `meta.noCache` 控制
::: tip 注意
由于在`<el-menu>`中,菜单(`<el-menu-item>`)只要被点击就会高亮,所以如果不希望外链菜单被高亮,
那么需要在点击后通过调用`<el-menu>`的`updateActiveIndex`方法来设置高亮菜单。
那么需要在点击后通过调用`<el-menu>`的`updateActiveIndex`方法来重新设置高亮菜单。
:::

Loading…
Cancel
Save