diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 88da54a..e7eb629 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -27,6 +27,7 @@ module.exports = { collapsable: false, children: [ '/frontend/', + '/frontend/icon', '/frontend/layout', '/frontend/router', '/frontend/permission', @@ -43,6 +44,8 @@ module.exports = { '/frontend/components/tree-select', ] }, + '/frontend/directives', + '/frontend/filters', { title: '全局方法', collapsable: false, diff --git a/docs/frontend/README.md b/docs/frontend/README.md index 273b8f5..be7f195 100644 --- a/docs/frontend/README.md +++ b/docs/frontend/README.md @@ -15,6 +15,7 @@ - 布局功能 - 异步路由组件loading骨架屏 + - 响应式的顶部菜单 - 多级侧边栏 - 面包屑 - 多页签(支持详情页缓存) diff --git a/docs/frontend/deploy.md b/docs/frontend/deploy.md index 887df37..19c1879 100644 --- a/docs/frontend/deploy.md +++ b/docs/frontend/deploy.md @@ -26,7 +26,7 @@ npm run build ## 路由模式 -项目提供了动态修改路由模式的功能,只需要修改 `@/config/index.js` 中的 `routerMode` 即可。 +项目提供了动态修改路由模式的功能,只需要修改 `@/config/index.js` 中的 `route.mode` 即可。 当路由模式为 `'history'` 时,需要服务器提供支持。以 `nginx` 为例,需要在配置中补上: ```shell script diff --git a/docs/frontend/directives.md b/docs/frontend/directives.md new file mode 100644 index 0000000..a194416 --- /dev/null +++ b/docs/frontend/directives.md @@ -0,0 +1,33 @@ +# 指令 + +## el-dialog拖拽 + +已全局注册,使用方式: +```js + +``` + +## 波纹 + +从[quasar](https://quasar.dev/vue-directives/material-ripple)处搬运 +已全局注册,使用方式: +```js +
+``` +更多细节请根据quasar文档使用 + +## element-ui自带 + +### clickOutside + +未全局注册,使用方式: +```js +//引入 +import ClickOutside from 'element-ui/lib/utils/clickoutside' + +//组件中注册 +directives: {ClickOutside} + +//使用 +
+``` diff --git a/docs/frontend/filters.md b/docs/frontend/filters.md new file mode 100644 index 0000000..4c9440f --- /dev/null +++ b/docs/frontend/filters.md @@ -0,0 +1,7 @@ +# 过滤器 + +项目中将 `@/filter` 中的文件注册为全局过滤器,各自功能作用可以查看注释或代码。 + +:::tip 小技巧 +全局注册的过滤器可以在vue示例中以this.$options.filters.xxx调用 +::: diff --git a/docs/frontend/icon.md b/docs/frontend/icon.md new file mode 100644 index 0000000..cf4a9cc --- /dev/null +++ b/docs/frontend/icon.md @@ -0,0 +1,5 @@ +# 图标 + +组件已全局注册,以``来使用。 +当`icon`属性以`svg-`开头时,将渲染为`svg`,否则为`i`标签。 +svg的引入与[vue-element-admin](https://panjiachen.github.io/vue-element-admin-site/zh/guide/advanced/icon.html)相同。 diff --git a/docs/frontend/layout.md b/docs/frontend/layout.md index fb7b189..87770fd 100644 --- a/docs/frontend/layout.md +++ b/docs/frontend/layout.md @@ -19,9 +19,16 @@ ``` `Layout` 填充到 `App.vue` 里的 ``,而真正的路由页面 `@/views/index` 则填充到 `Layout` 里的 ``。 -项目中没有用到 `Layout` 的页面只有 `@/router/constant/modules/app.js` 里的 `login`、`403`、`404` 这三个。 +项目中没有用到 `Layout` 的页面只有 `@/router/define.js` 里的 `login`、`403`、`404` 这三个。 -另外可以发现 `App.vue` 使用了 ``,这是为了从 `403`、`404` 返回时能保存之前打开的标签页。 +## 面包屑 + +摆设,放在那里充充数,正在研究是不是要移到页面里去,因为感觉和顶部菜单冲突。 + +## 顶部菜单 + +响应式设计,能够使菜单部分隐藏或全部隐藏,参考了ant design。 +由路由配置项数组中的根节点组成,根据路由地址自动高亮。 ## 多页签 @@ -41,13 +48,6 @@ ## 全局页脚 -只有使用了 `Layout` 组件的路由页面才会有这个页脚。 -这里的实现比较特别,由于路由页面被 `` 包裹,需要将页脚的dom插入到 `` 的dom中,所以使用了这种方法: -```javascript -const FooterConstructor = Vue.extend(Footer) -const footerInstance = new FooterConstructor().$mount() -this.$refs.scrollbar.$refs.wrap.appendChild(footerInstance.$el) -``` -至于为什么不用函数式组件,是因为我还不知道怎么样拿到一个函数式组件的dom +想改啥去 `@/layout/component/Footer.vue` 里改,妥妥的。 diff --git a/docs/frontend/new.md b/docs/frontend/new.md index 9928a00..d0cf087 100644 --- a/docs/frontend/new.md +++ b/docs/frontend/new.md @@ -1,6 +1,6 @@ # 新增页面 -1. 把数据请求api创建出来,建议在 `@/api`下根据模块区分。 +1. 把数据请求api创建出来,在 `@/api`下根据模块区分。 2. 在 `@/views` 下创建路由页面,根据模块区分,页面务必以`Page.vue`结尾。 @@ -15,3 +15,5 @@ 6. 如果需要创建vuex模块,请在 `@/store/modules` 下创建,同样的,该文件夹下的js会被自动导出。 7. 如果页面之间存在公共组件,建议抽取出来放到 `@/component` 中 + +8. 如果页面之间存在公共逻辑,建议抽取出来放到 `@/mixin` 中 diff --git a/docs/frontend/permission.md b/docs/frontend/permission.md index eeea666..e5adbe1 100644 --- a/docs/frontend/permission.md +++ b/docs/frontend/permission.md @@ -4,13 +4,41 @@ 鉴权方法为 `@/util/auth.js #auth`。 +鉴权前的准备工作: + +登陆成功后,后台返回用户所拥有的资源,构造出用户的权限树。 +之后用户在进入系统的任意一个非白名单内的路由时,会向后台获取 +所有的资源,构造出总权限树。 + 鉴权流程: + 1. 如果用户是`admin`身份,那么直接放行。 2. 如果访问的 `url` 不在总权限树内,说明该操作无需权限,放行。 3. 如果访问的 `url` 在用户的权限树内,说明有权限,放行。 -4. 否则拦截,跳转至403页面。 +4. 否则拦截,如果是在路由的拦截器中则会跳转至403页面。 + +当然前端的权限控制只是过滤一小部分,对接口的过滤工作还是得由后端完成。 + +### 如何移除权限控制? + +前端的权限控制的方法全在 `@/util/auth.js` 里面,哪里引入就改哪里,粗暴点直接把`# auth`方法返回true就完事了。 +后端的权限控制由拦截器实现,同样的改造原理,easy啦。 + +### 为什么不是RBAC? + +首先只有两种情况前端会用RBAC: + +**1.角色固定**: + +比如接口管理平台YAPI,角色就是固定的那三四个,前端可以直接写死,这种是最最适合的。 + +**2.角色不固定,但是后端可以返回角色-资源的映射表:** + +映射表规定了页面上所有的资源(路由页面、数据接口、按钮等等)被哪些角色所拥有,这样 +只需要凭一个用户的角色就能控制资源的访问。但是嗦实话,所有开源的纯vue管理后台全部 +不是这样搞的。 -当然前端的权限控制只是过滤一小部分,真正的工作还是由后端完成。 +所以这里偷懒,直接把用户拥有的所有资源返回给前端。不过这也导致了不好用无状态的jwt来代替session。 diff --git a/docs/frontend/plugins.md b/docs/frontend/plugins.md index 5b8a0ec..3c6947c 100644 --- a/docs/frontend/plugins.md +++ b/docs/frontend/plugins.md @@ -1,5 +1,7 @@ # 插件 +这里放的是即使删掉也不会影响运行的东东,基本都通过`import().then()`的方式来引用。 + ## canvas动画 所有动画位于 `@/plugin/canvasAnimation`下,使用 `new Animation(canvas)`的方式来创建一个动画。 diff --git a/docs/frontend/router.md b/docs/frontend/router.md index b793177..f4c3f17 100644 --- a/docs/frontend/router.md +++ b/docs/frontend/router.md @@ -1,6 +1,7 @@ # 路由 -项目中默认使用了静态路由,要使用动态路由的话需要打开 `@/config` 中的 `useBackendRoute` 选项。 +项目中默认使用了前端预设的静态路由, +要使用后端返回的动态路由的话需要打开 `@/config/index.js` 中的 `route.useBackendDataAsRoute` 选项。 本项目不支持二级以上的路由,虽然路由配置可以无限级,但是实际上是二级路由的效果,因为在处理路由 数据时会将二级以上的路由缩减为其叶子节点,也就是说如果有如下路由: @@ -53,30 +54,37 @@ const routes = [ ## 路由配置项 路由配置项不光参与路由的生成,也参与侧边栏的生成。 + +这里约定,配置项中只有根节点(即顶部菜单)的path以'/'开头。 +并且,只有根节点和叶子节点可以自定义component。 +目前根节点的component固定为`Layout` + +此外,所有根节点(经过缩减)的redirect属性都将设为其第一个子节点的fullPath,目前不支持自定义。 + ::: warning 注意 项目中,路由配置项中的component是字符串,比如组件路径是`@/views/test/indexPage.vue`,那么component可以是 -`test/` 或者 `test/index`,具体可以看`@/router/util.js` 中的 `generateRoutes` 方法。 +`test/`、`test/index`、`test/indexPage`、`test/indexPage.vue`,具体可以看`@/router/util.js` 中的 `generateRoutes` 方法。 ::: ### Route.meta Attributes: -| 参数 | 说明 | 类型 | 默认 | -| :------------: | :--------------------------------------------------: | :--------: | :---------------------: | -| title | 路由在侧边栏、面包屑、页签 | `string` | - | -| dynamicTitle | 路由在面包屑、页签中的动态名称,参数为(to,from) | `function` | - | -| hidden | 是否在侧边栏中显示 | `boolean` | - | -| alwaysShow | 是否总是把只有一个子级的菜单以嵌套模式在侧边栏中展示 | `boolean` | - | -| sort | 侧边栏的排序值,值越小越靠前 | `number` | 10000 | -| icon | 图标名,的icon属性 | `string` | - | -| affix | 是否在多页签中固定显示 | `boolean` | - | -| noCache | true时缓存页面 | `boolean` | - | -| activeMenu | 侧边栏当前激活菜单的index | `string` | - | -| noAuth | true时路由不需要鉴权 | `boolean` | router/constant下为true | -| iframe | 需要打开的iframe的地址 | `string` | - | -| usePathKey | 是否使用$route.path作为组件缓存的key | `boolean` | - | -| useFullPathKey | 是否使用$route.fullPath作为组件缓存的key | `boolean` | - | -| commonModule | 共用组件的唯一标识 | `any` | - | +| 参数 | 说明 | 类型 | 默认 | +| :------------: | :--------------------------------------------------: | :--------: | :---: | +| title | 路由在侧边栏、面包屑、页签 | `string` | - | +| dynamicTitle | 路由在面包屑、页签中的动态名称,参数为(to,from) | `function` | - | +| hidden | 是否在侧边栏中显示 | `boolean` | - | +| alwaysShow | 是否总是把只有一个子级的菜单以嵌套模式在侧边栏中展示 | `boolean` | - | +| sort | 侧边栏的排序值,值越小越靠前 | `number` | 10000 | +| icon | 图标名,的icon属性 | `string` | - | +| affix | 是否在多页签中固定显示 | `boolean` | - | +| noCache | true时缓存页面 | `boolean` | - | +| activeMenu | 侧边栏当前激活菜单的index | `string` | - | +| noAuth | true时路由不需要鉴权 | `boolean` | - | +| iframe | 需要打开的iframe的地址 | `string` | - | +| usePathKey | 是否使用$route.path作为组件缓存的key | `boolean` | - | +| useFullPathKey | 是否使用$route.fullPath作为组件缓存的key | `boolean` | - | +| commonModule | 共用组件的唯一标识 | `any` | - | ::: tip 注意 路由meta上的noAuth、noCache会被子路由继承,优先使用子路由的值 @@ -150,6 +158,7 @@ function lazyLoadView(component) { //将路由配置中的component项改为以下形式 component: lazyLoadView(import(...)) ``` +项目中具体的使用方式可以查看 `@/router/util #generateRoutes`方法。 关于 `AsyncHandler` 的更多选项,可以查看[官方文档](https://cn.vuejs.org/v2/guide/components-dynamic-async.html#%E5%A4%84%E7%90%86%E5%8A%A0%E8%BD%BD%E7%8A%B6%E6%80%81) @@ -178,7 +187,7 @@ component: lazyLoadView(import(...)) 项目中是根据页签的前后位置来决定路由动画的,比如从前面的页签跳转到后面的,那么动画是从左滑出,反之是从右滑出。 ::: warning 注意 -只有在启用了多页签的时候才会有上面的效果,否则默认是 `el-fade-in-linear` 动画。 +只有在启用了多页签的时候才会有上面的效果,否则默认是 `@/config/index.js` 中的 `route.animate.default` 动画。 ::: ## iframe @@ -196,6 +205,8 @@ component: lazyLoadView(import(...)) 当向上面的路由跳转时,会隐藏路由页面,展示 `