详解Vue路由自动注入实践(2)

src/views ├── Bank <!-- 银行卡管理 --> │ └── Index.vue ├── DivideData <!-- 分成数据 --> │ └── Index.vue <!- 首页 ---> ├── Index.vue <!-- 404路由 --> ├── NotFound.vue ├── Withdraw │ ├── BankDetails <!-- 提现中查看银行卡信息 --> │ │ └── Index.vue │ ├── Description <!-- 提现说明 --> │ │ └── Index.vue <!-- 提现页面 --> │ └── Index.vue └── WithdrawHistory <!--提现记录 --> └── Index.vue

其实一般这么分下来,相似功能的是会在一个文件夹下面的,也实现了按功能分路由的思路,而且这种层级划分是一目了然的,很容易可以看出路由的从属关系

但有时候也会遇到一个麻烦,就是有些页面可能出现在当前层级下面,也可能出现在另外一个层级下面,按功能分的时候也有这种,就是功能可能存在于两个功能点之间,这种情况其实可以考虑下在哪个层级的权重重一点或者从用户的点击习惯考虑,哪个位置进去会多一点就放在哪个层级下面

vue-router-invoke-webpack-plugin 中独特的文件结构

也许大家会有疑问,为啥非要写成 Index.vue 并多加一层文件夹封装,直接命名 vue 文件不好吗,用过 nuxt 的同学可能也会感觉到这一点的区别,这也是我们在 nuxt 的基础上增加的一个 feature ,为了更友好的封装一个单页面

举个列子,如果你的项目没有引用ui库,很多业务组件需要自己写,除了常用的组件会放在目录最外面的 components 文件,其余的对应一个单页面的业务组件你会放在哪里呢,这就是我们预留的位置,比如一个目录结构如下

src/views ├── Audit │ ├── Index.vue │ ├── components │ │ └── AuditItem.vue │ └── images │ └── AuditIntro.png

Audit 是我们的审批页面,其中用到了一个只有当前页面所用的 AuditItem.vue 组件,也引用了一个只有当前页面所用到的图片 AuditIntro.png ,独特的文件结构就是为了这种需求而生的,当前页面的组件图片放在一个文件夹中会更清晰,但值得一提的是,你也需要在插件中设置 ignore 去忽略掉不被我们解析的目录,比如这样

plugins: [ new VueRouterInvokeWebpackPlugin({ dir: 'src/views', alias: '@/views', language: 'javascript', ignore: ['images', 'components', 'template.vue'] }) ];

那么 images components template.vue 会被忽略不解析

聊一聊路由权限控制

关于前端控制路由权限,前段时间看到过一个文章,感觉实现思路稍微复杂了点,其实有一个比较简单的思路,就是后端给定当前用户没有权限的路由,然后前端在 beforeEach 钩子中去匹配,如果匹配到没有权限则直接跳404或者没有权限的页面就行了,如果用 vue-router-invoke-webpack-plugin 写会这么写

apis.getForbiddenRoute

export default { // 请求当前没有权限的路由列表 async getForbiddenRoute() { return ['/single/user']; } };

plugins: [ new VueRouterInvokePlugin({ // 观察的目录 dir: 'demos/src', // 观察目录的别名 alias: '@/src', // 当前语言 language: 'javascript', // 生成router.js的位置 routerDir: 'demos', // 忽略文件夹 ignore: ['images', 'template.vue', 'components', 'notfound.vue'], // 404路由地址 notFound: '@/src/NotFound.vue', // 引用的模块 modules: [ { name: 'apis', package: '@/apis' } ], // 同scrollBehavior scrollBehavior: (to, from, savedPosition) => { if (savedPosition) { return savedPosition; } else { return { x: 0, y: 0 }; } }, <!-- 主要是这段代码 --> /* eslint-disable */ beforeEach: async (to, from, next) => { // 通过绑定在静态属性上的_cachedForbiddenRoute判断是否请求过接口 if (!Vue._cachedForbiddenRoute) { Vue._cachedForbiddenRoute = []; await apis.getForbiddenRoute().then(res => { Vue._cachedForbiddenRoute = res; }); } // 当当前页面的地址存在于禁止访问的列表中,则直接跳转到404页面 if (Vue._cachedForbiddenRoute.includes(to.path)) { next({ name: 'notFound' }); } else { next(); } } }), ]

但话说回来,任何实现思路,前端获取的接口数据想篡改还是能绕过去的,所以还是得后端再防一层

项目实现思路

项目实现不太复杂,但要照顾到的地方很多

基本路由

动态路由

多层嵌套路由

多层嵌套动态路由

meta替代品

文件不符合规则的友好处理

命名转换统一

node中原生fs模块十分不友好

要考虑的小细节还挺多的,特别是当路由过于复杂的情况

但node的 fs 的坑点是我没有想到的,特别是在跨平台上,所以我们舍弃了使用原生的 fs 模块,用 chokidar 和 fs-extra 替代了 fs 的部分功能

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/825fb38d13625ec3421dc5ace32b7cbf.html