网路营销网站策划书,网站报301错误,望野王维,去水印小程序搭建回顾 今天VS 2019正式发布#xff0c;实验一波#xff0c;你安装了么#xff1f;Blog.Core 预计今天会升级到 Core 3.0 版本。 哈喽大家周三好#xff01;本来今天呢要写 Id4 了#xff0c;但是写到了一半#xff0c;突然有人问到了关于 Blog.Admin 管理后台的一些问题实验一波你安装了么Blog.Core 预计今天会升级到 Core 3.0 版本。 哈喽大家周三好本来今天呢要写 Id4 了但是写到了一半突然有人问到了关于 Blog.Admin 管理后台的一些问题想着这个前后端系列是第一个项目而且是以后学习的基础不能草草了事所以就把重心往 Blog.Core Blog.Admin 两个项目上靠拢了下明天再更新 IdentityServer4 吧因为从上周末到今天这几天修改了一些东西这里就不一一的写文章了如果你是跟着系列看的小伙伴应该知道我写的是什么意思如果是路人额不敢保证你能看懂我在说什么总结来说有以下五点 1、Blog.Core 项目增加了单元测试项目 Blog.Core.Tests 不过就几行代码做了个小测试而已 2、Blog.Core 项目配置了 AOP Sql 的功能就是大家在操作仓储的时候会生成指定的Sql语句保存到日志中方便查看这是SqlSugar的核心功能 3、Blog.Core 项目增加多线程日志功能防止出现死锁可以查看 BlogLogAOP.cs 当然你可以封装起来 具体查看方法static void OutSql2Log(string dataIntercept) 4、DDD开发之 Christ3D 项目完成了末尾开发实现了 Identity 登录注意不是 Id4 并完成部署 地址http://123.206.33.109:4773 5、Blog.Admin 项目实现数据库配置动态路由这个是今天的重点内容其他的都很简单大家看看就行。 然后也简单说说如何在 Blog.Admin 项目中快速添加页面虽然这个真的很简单。 好啦马上开始今天的 Share Time。 因为这个系列我还没有写过一些文章所以今天就把两种写法都写上既补充了之前的方案又设计新的方案。 一、传统的权限路由是如何设计的 首先先来个动图(注意这个方案已经弃用了看看个过程即可下边第二节有个动图才是以后开发的模板) 1、设计页面 这个步骤很简单也很普通我们开发项目肯定需要设计页面了这个不属于权限路由的一部分 不过要说的就是这个页面路径的设计要考虑清楚有的小伙伴习惯一股脑全部并列放页面也有详情页用 detail.vue 或者 id.vue 还有的是 _id.vue 的具体的这些规则需要好好想想设计清楚不细说。 2、路由实例配置 routerManuaConfig.js 文件 。相信这个路由大家都已经很明白了只要是写过 vue 的有一点点基础的项目初期我们每次开发页面如果需要在项目中使用就必须将路由实例添加到 Vue 实例里其实说白了就是一个对象这样 Vue 实例才能调用也就是能通过 url 访问到我们的页面。这个其实是很合理的也是很正确的官方也是这么处理的比如我的 Blog.Admin 项目中就是这么配置的 可是嗯就怕可是现在我的页面大概有十多个就已经一大串了有时候修改一个路由需要找半天这个设计貌似不是随着项目的扩大越来越不合理我见过一个项目页面有50那配置了一大大大页的路由 json嗯感觉会有解决方案的没错vue 官方也说提到了具体的下文会详细说明咱们先安装这个方案进行下去。 那既然是权限路由路由有了就该权限了。 3、配置权限菜单路由 Login.vue 、App.vue 文件虽然我已经覆盖了 GitHub 上的代码但是这个方案的写法还保留着大家如果真的就喜欢这种配置也可以看看。 上边我们是把所有的路由都注入到了 Router 实例里那如何渲染权限菜单呢没错思路很简单 1、当前用户登录 2、获取到用户标识比如 Id 3、根据用户标识获取权限菜单的 Json 数据 4、根据 Json 数据渲染到左侧菜单上。//查看 App.vue 文件中的 routes 这个数组。 其实前三步都是在 Login.vue 页面内进行的很简单的两个方法 GetNavigationBar() 自己看看即可。 4、菜单表中添加新建的页面菜单 上边的步骤中仅仅是将之前的页面渲染出来了如果我们新建了一个页面新的页面还没有显示出来 所以就需要在后台管理 - 菜单权限管理 - 菜单管理中新建一条数据 5、角色与菜单的分配 上边菜单数据配置好后 就需要对当前用户所对应的角色进行权限的再次分配了这个很好理解这个是核心前边所以的操作都是给这个做铺垫的 6、存在的小问题 其实关于权限路由上边五步走已经实现了是不是感觉很简单这里只说菜单不说API权限问题这个是上一篇的《二 || 完美实现 JWT 滑动授权刷新》已经说到了但是现在面临着两个问题 1、就是上边提到的需要将很多的路由一一的配置好注入到路由实例 2、因为这样是一次性把全部的路由都注入如果当前用户没有这个页面的权限虽然左侧的菜单看不到这个页面但是如果他强行访问这个url的话还是会出现的 当然我们设计了 api 权限他看不到内容但是再强行访问这个URL的时候还是会在当前页面停留并看到页面骨架就是没有数据但是有按钮啥的 当然我们可以让用户直接跳转到403页面嗯也是一个办法。 那有没有什么办法可以动态的生成路由实例呢欸要是有这个想法就是人才请往下看。 二、动态生成路由实例 上边我们研究了一般实现权限路由菜单的方法很简单很直观但是有两个小问题其实对我来说主要的还是手动配置路由的问题页面现在的太多每次开发一个页面不仅需要添加路由还需要在菜单表里增加该菜单然后对权限勾选该菜单从这个逻辑来看好像在vue项目中配置路由就成了冗余的一步了那如果不配置了我们该怎么办呢这就是今天要说的重头戏 —— 动态路由实例。 首先再来个动图以后就用这个方法进行快速开发了 上边的这个已经对当前路由页面做了权限匹配我们匹配好了页面剩下的就是开发 API 接口了开发成功后要注意两点 1、增加接口的授权特性 2、后台对路由进行编辑增加api接口 1、在路由实例中注入项目基础路由 这里要说的重点是 基础路由 那什么是基础路由呢就是我们在项目启动的时候首次运行的页面比如登录页或者不需要参与数据库权限配置的某些路由比如欢迎页404页比如我将基本的路由实例重新整理如下 在项目的 src 文件夹下新建一个 router 文件夹然后新建主程序文件 —— index.js 这个文件以后就是我们的新的路由方案用来替换之前的 router.js现在更名为 routerManuaConfig.js 大家可以看到现在除了这几个基础路由其他的都被删除了统一通过动态注入的方式添加。 2、根据环境配置导入组件文件 这里其实是一个小坑以前没有研究过后来搜索了下才知道的原来 vue 动态导入 vue 文件在不同的环境还不一样所以这里特别用了一节来说明下虽然内容很简单 还是在 src/router 文件夹下建立两个文件然后定义导入方法 _import_development.js
//开发环境导入组件
module.exports file require(/views file .vue).default_import_production.js
//生产环境导入组件
module.exports file () import(/views file .vue) 那如何进行导入呢就是下边的重头戏了。 3、动态生成权限路由核心 这个具体的code 在 src 的根目录下的 promissionRouter.js 文件里 A、组件导入 —— _import 这个其实很简单只需要根据当前的环境变量获取指定的导入方案传入路径地址作为参数就可以很好的实现当然地址的注入。 //获取组件的方法
const _import require(./router/_import_ process.env.NODE_ENV)// .......//导入路径下的组件
route.component _import(route.path) B、获取数据与保存钩子 —— router.beforeEach 这个是一个核心就是我们每次在路由切换的时候都需要动态处理路由实例这里还有点儿瑕疵我会在以后慢慢完善但是思路就是这样的这里的路由数据来自两个方面一个是api接口获取一个是将获取到的数据存放在本地 var storeTemp store;
router.beforeEach((to, from, next) {//动态添加路由{//不加这个判断路由会陷入死循环if (!getRouter) {if (!getObjArr(router)) {var user window.localStorage.user ? JSON.parse(window.localStorage.user) : null;if (user user.uID 0) {var loginParams {uid: user.uID};getNavigationBar(loginParams).then(data {console.log(router before each get navigation bar from api succeed!)if (data.success) {getRouter data.response.children//后台拿到路由saveObjArr(router, getRouter) //存储路由到localStoragerouterGo(to, next)//执行路由跳转方法}});}} else {//从localStorage拿到了路由getRouter getObjArr(router)//拿到路由routerGo(to, next)}} else {console.log(to)if(to.nameto.name ! login){getRouter getObjArr(router)//拿到路由global.antRouter getRouterrouterGo(to, next)//执行路由跳转方法}next()}}
}); 具体的写法都很简单就是判断和保存到路由不细说了大家pull 下代码看看即可。 C、路由过滤 —— filterAsyncRouter 这里要说下这个是关键因为我们获取到的仅仅是一个json格式的权限列表我们的路径还是一个字符串 url 但是我们的动态路由需要一个 component 也就是刚刚我们获取到的对应组件所以我们需要来一个过滤器将获取到的json数据中每一个菜单都添加进去一个 component 组件信息。 //遍历后台传来的路由字符串转换为组件对象
function filterAsyncRouter(asyncRouterMap) {//注意这里的 asyncRouterMap 是一个数组const accessedRouters asyncRouterMap.filter(route {if (route.path) {if (route.path /) {//Layout组件特殊处理route.component Layout} else { route.component _import(route.path)}}if (route.children route.children.length) {route.children filterAsyncRouter(route.children)}return true})return accessedRouters
} D、生成路由实例与运行 —— routerGo 上边所有的工程中我们把路由已经生成好了就剩下最后一步注入到实例里没错就是红色的部分是不是很简单 function routerGo(to, next) {getRouter filterAsyncRouter(getRouter) //过滤路由router.addRoutes(getRouter) //动态添加路由global.antRouter getRouter //将路由数据传递给全局变量做侧边栏菜单渲染工作next({...to, replace: true})
} 4、遗留问题——重登新用户路由不同步 这个是个很搞笑的问题怎么说搞笑呢好像上边的 addRoutes 这个方法设计之初没有设计过动态删除额好吧我就是开个玩笑对尤大大的框架还是很给力的。 现在有一个问题就是我现在是test账号然后没有 测试管理 这一组这个期间我刷新了页面然后当我切换超级管理员 blogadmin 的时候虽然有这个左侧菜单但是点击测试页面1的时候提示404证明啥证明这个路由虽然渲染出来了但是没有导入到路由实例里路由对象里还是之前的这个时候必须刷新一下才能正常访问请看 这个时候我研究出来两个方案虽然两个在本地都可以但是第二种在发布模式下不行也就是dist 上传到服务器就不行了这里做下记录暂时使用第一种方案可能你遇不到。 1、在系统登出也就是退出登录的时候刷新页面使用 window.location.reload()在 App.vue 的logout 方法里 2、使用 router.matcher 来替换在 router/index.js 下的 resetRouter方法和调用处promissionRouter.js 下的 routerGo 方法里调用 目前一切正常就暂时使用刷新页面的第一种方案第二种以后慢慢研究。 您可参考这个issues 三、支持多级菜单——递归 这个其实很简单以前我的版本只是支持两级菜单那如果想实现无限级别的多级菜单的话就肯定需要用到递归的概念了简单来说就是——递归组件。 具体的原理相信有一点基础的小伙伴都能理解就是写一个递归组件将路由菜单 JSON 给递归渲染出来即可 1、设计菜单递归组件 在 src - components - 下新建 Sidebar.vue 组件实现自身嵌套递归 templatedivtemplate v-ifitem.childrenel-submenu :indexitem.idindex v-if!item.leaftemplate slottitlei classfa :classitem.iconCls/ispan classtitle-name slottitle{{item.name}}/span/templatetemplate v-forchild in item.children!-- 这里实现自己递归嵌套 注意这个名称 --sidebarv-ifchild.childrenchild.children.length0:itemchild:keychild.path5/el-menu-item v-else :keychild.path5 :indexchild.path5i v-ifchild.childrenchild.children.length0 :classitem.iconCls/i{{child.name}}/el-menu-item/template/el-submenu/template !-- 没有子节点直接输出 --template v-elseel-menu-item :indexitem.pathi classfa :classitem.iconCls/itemplate slottitlespan classtitle-name slottitle{{item.name}}/span/template/el-menu-item/template/div
/templatescriptexport default {name: Sidebar,props: {item: {type: Object,required: true}}}
/script 2、在App.vue 中进行调用 当然你也可以放到模板组件也就是 Layout.vue 中调用把左侧菜单页头页脚放到 Lauout 布局页不过我都放到了 App.vue 了 el-menu :default-active$route.pathclassel-menu-vertical-demo openhandleopen closehandleclose selecthandleselectunique-opened router :collapseisCollapsebackground-color#2f3e52text-color#fffactive-text-color#ffd04bsidebar v-for(menu,index) in routes :keyindex :itemmenu //el-menu 记得导入组件 来看看最终的效果吧 四、结语 好啦今天的文章就先写到这里吧最近比较累心感觉努力付出和收获不是正比虽然还在学习还是想要歇一歇了。 今天的所有内容都已经提交到 Github然后在线 demo 也做了改变大家可以自行查看。 五、Github Gitee .NET CORE 源码: Github: https://github.com/anjoy8/Blog.Core Gitee : https://gitee.com/laozhangIsPhi/Blog.Core VUE 项目开源代码: https://github.com/anjoy8/Blog.Vue --- ♥♥♥ ---转载于:https://www.cnblogs.com/laozhang-is-phi/p/10643993.html