黑色背景的网站开发工具,学校网站建设方案策划书,短网址在线生成器,做自适应网站对设计稿的要求正文一、前情回顾哈喽大家好#xff0c;在这个欢庆的日子里#xff0c;老张祝大家工作都能蒸蒸日上#xff01;今天正好也是社团成立的第一天#xff0c;我也是希望今天能是个纪念日#xff0c;沾沾这个大喜庆#xff01;放假这两天#xff0c;倒是学到了很多东西#… 正文一、前情回顾哈喽大家好在这个欢庆的日子里老张祝大家工作都能蒸蒸日上今天正好也是社团成立的第一天我也是希望今天能是个纪念日沾沾这个大喜庆放假这两天倒是学到了很多东西我这个也是承认的昨天的事务提交今天的按钮级别的权限都是群里小伙伴提供的方案和思路我就是诚惶诚恐的写到文章里了我总怕会说我是知识的偷盗者当然我这个完全是为了社区我毕竟一分钱没有得到无论访问量有多少可能充其量就是数字好看。 言归正传还记得半年前(2019.02.27)的时候我的 vue 项目之二Blog.Admin 正式开源https://github.com/anjoy8/Blog.Admin当时打算做一个简单的权限后台系统我自己想了常用的一些功能当然有人说丑有人说乱但是也有人在自己项目和公司中使用不过也是我付出心血的而且也是完美的配合了 Blog.Core 项目当时几大设想功能中迟迟有一个功能没有实现搁置了很久 —— 就是按钮级别的权限配置 当时我为啥没有做这个呢有两点考虑1、是因为超级管理员我没让大家访问就怕误操作数据对别人观看权限有影响2、另一个考虑就是想把按钮暴漏出来看看是不是真的 test 测试账号能不能删除数据。后来我就开始思考是时候把这个权限加进来了就是没有删除的权限删除按钮就不显示但是考虑了很久被一个小知识点给卡住了就是没有想到如何动态事件绑定这个不懂没关系我下文章会说到前天由群管理 大黄瓜和Kawhi 提供了解决思路和方案眼前一亮终于实现了这个功能。投稿作者大黄瓜 and Kawhi效果预览我为了防止大改目前只在 “角色管理” 页增加了这个功能正常后全部替换在线地址http://vueadmin.neters.clubGithub分支主分支 下边就开始正式讲解分成了两部分步骤重点知识说明所以看步骤的时候直接动手操作就行了不用管为什么下边的第三部分——重点知识的说明会简单说说。 二、详细设计步骤1、后端微调保存按钮相关信息不知道还有没有小伙伴记得我现在后台的权限系统中左侧的导航条已经自动化了所谓的自动化就是已经完全交给了数据库无论增加多少权限不用前端或者后端进行操作只需要配置即可达到目的当时呢我把左侧的菜单和按钮揉到了一张表里当时感觉很不合理但是现在又改起来简单得益于这个设计思路所以这次我们几乎不用改什么只需要把按钮信息给放出来即可这里有两个小点1、Permission.cs 菜单表中新建字段 Func 用来存放当前按钮所对应的方法事件2、/Permission/GetNavigationBar 接口中把 IsButtonfalse 限制去掉使之可以配合菜单进行递归//var rolePermissionMoudles (await _permissionServices.Query(d pids.Contains(d.Id) d.IsButton false)).OrderBy(c c.OrderSort);var rolePermissionMoudles (await _permissionServices.Query(d pids.Contains(d.Id))).OrderBy(c c.OrderSort);3、在 RecursionHelper.cs 中增加 IsButton 属性将数据库数据拼车 Tree 返回到前端这样我们就把按钮数据配合着菜单数据一起返回前端了你可以来查看下 到这里我们第一部分——后端数据就完成了当然如果你想更炫酷可以多增加字段比如按钮的样式或者其他属性等等等这里你肯定明白我就不细说了。从下边开始我们就开始说 Blog.Admin 项目了请打开 VSCode 来修改我们的 Vue 项目 2、修改后台权限管理添加按钮事件这个步骤很简单就是把上边我们建立的那个 Func 字段给在页面里增删改查一下就好了具体的代码自行修改即可。 3、控制“按钮”不要和“菜单”展示冲突刚刚我们上边说到了把按钮数据配合着菜单一起开放了出来那这个时候我们要需要检查一下不能和菜单的展示起冲突这里我就直接说修改的地方了 1、修改 Sidebar.vue 组件让按钮的数据不要进行展示具体的看看代码就明白了很简单2、修改 src\router\index.js 中的动态路由注入方法过滤掉按钮数据 到了这里我们的第二部分——准备工作就做完了接下来就是本文的重中之重的重头戏设计这个工具栏了那具体怎么操作这个时候我希望你可以先暂停一下先不要往下看先自己脑中考虑一下按照我的思路就是按钮数据也已经有了如何设计这个公共组件呢考虑五分钟吧...... 五分钟后假设你已经考虑过了那我就开始正式说明。 4、设计工具栏组件——Toolbar.vue 既然要做成自动化的组件就一定要抽象出来那第一步就是建立一个组件不能每个页面都写相似的一堆代码其实呢我们也要可以配置不能仅仅把按钮给提出来还应该有其他的比如input /搜索框等等都应该放到工具栏里一定要加载或者不加载不能show or hide这样别人也会在查看元素的时候看到 综上所述 我的设计是把表格里的按钮全部提到了顶部先给大家一个展示的效果图这个删除颜色是我手动加的你也可以自己加个字段配置 首先我们创建组件src\components\Toolbar.vue 具体的代码如下template el-col v-ifbuttonList.length0 :span24 classtoolbar stylepadding-bottom: 0px; el-form :inlinetrue submit.native.prevent el-form-item el-input v-modelsearchVal placeholder请输入内容/el-input /el-form-item !-- 这个就是当前页面内所有的btn列表 -- el-form-item v-foritem in buttonList !-- 这里触发点击事件 -- el-button typeprimary clickcallFunc(item){{item.name}}/el-button /el-form-item /el-form /el-col/templatescriptexport default { name: Toolbar, data() { return { searchVal: //双向绑定搜索内容 }; }, props: [buttonList], //接受父组件传值 methods: { callFunc(item) { item.search this.searchVal; this.$emit(callFunction, item); //将值传给父组件 } }};/script 相信每个人都能看的懂只是字面意思能看得懂其中的核心知识点就是 List for渲染父给子传值子给父传值我下文会重点讲到其中 buttonList 数组的格式很简单你可以自己后端封装一下我这里就偷懒了直接使用的菜单的数据结果就是上边我 localstorage.routes 中的结构毕竟我把按钮和菜单共有一套嘛。那现在我们设计好了子组件——工具栏接下来就要设计父组件了传递数据和接受子组件广播了。 5、将按钮事件绑定到组件上刚刚我们说到了 在 Toolbar.vue 中核心的内容就是把动态的事件方法给推送到一个个父组件上这里是以 Role.vue 页面举例的所有用到了 $emit(callFunction, item) 方法这个如果你开发vue的话肯定都知道这个的这个父子通讯实例中使用很多具体的我在之前的文中中也讲到了你可以看看这里不细说说白了一句话就是子组件执行父组件方法。二十║Vue基础终篇传值组件项目说明。其实到这个地方我也想到了但是问题来了你可以先看看 emit 的用法使用 emit 一般都是传递数据但是如果传递 function 的话肯定也是一个 name 的字符串那父组件接受到这个 function name 的时候很容易当成一个 data如果强行执行他们又不在一个对象里因为有闭包如何让页面执行这个 function 呢我思考了很久说明自己学的不到家。这个就是这两个月来困扰我的地方前边的思路和后边的 Table 隔离我都想到了只是这里我没有想到看来还是需要一些高级前端的朋友哟前天听到了一个 apply 方法后我豁然开朗原来可以这样那下边我就详细的说一说如何父组件执行事件在 src\views\User\Roles.vue 页面呢修改我们的工具栏使用 这种引用组件在data中定义 buttonList 就不说重点还是要理解 callFunction 这个必须要和子组件的 $emit 中的方法名一致。然后我们定义 callFunction用来动态执行一个个事件 callFunction(item) {//这个 item 就是我们的 permission.cs 数据 this.filters { name: item.search };//这里是把子组件中的 search 内容也接受过来 this[item.Func].apply(this, item);//核心就是要执行 apply 方法 }, 是不是很简单难点就在于.apply这个方法下文会说到。这个 this 就是当然父组件的内容就是我们执行可以在子组件来调用父组件的方法了 这里再说下 6、父组件获取 ButtonList 数据上边我们也说到了我们把 button 和 菜单揉在一起了所以我们很简单操作一下之前的数据就行做一下筛选// 在 mounted 钩子中调用 router let routers window.localStorage.router ? JSON.parse(window.localStorage.router) : []; this.getButtonList(routers); // 定义方法目的我为了递归 getButtonList(routers) { let _this this; routers.forEach(element { let path this.$route.path.toLowerCase(); if (element.path element.path.toLowerCase() path) { _this.buttonList element.children; return; } else if (element.children) { _this.getButtonList(element.children); } }); } OK数据准备完毕。 7、修改 Table 组件将工具栏与 Table 逻辑隔离到了这里就是最后一步了我们把之前的 tabel 右侧 “操作栏” 删掉统一放到顶部然后绑定数据就可以加载出来了 现在我们把操作栏给取消了但是我们如何获取 scope.row 呢是不是很麻烦要修改很多呢其实不是的。 8、Table 改为单选通过点击选择某行这个功能特别简单思路就是通过单击某一行来获取这个 table 的 row这个 element 官网写的很详细我就简单的说一下吧//触发事件获取到这个row selectCurrentRow(val) { this.currentRow val; }, !--列表-- el-table :datausers highlight-current-row v-loadinglistLoading current-changeselectCurrentRow stylewidth: 100%; 然后只需要简单的修改一下我们的 edit 和 delete 方法即可因为我们已经拿到了这个 row 搞定啦是不是很简单几乎没有修改什么感觉之前设计的方案还可以吧至少扩展还是很不错的到了这里我们的动态按钮权限功能就已经完全做完了一个八个步骤大家动手起来搞一搞吧。 三、重点知识解析 1、组件 ——子传父 父传子 这块内容呢其实我们都已经讲过很多遍了父传子很简单只需要定一个自定属性即可然后子组件接受比如上文中的 toolbar :buttonListbuttonList callFunctioncallFunction/toolbar name: Toolbar, data() { return { searchVal: //双向绑定搜索内容 }; }, props: [buttonList], //接受父组件传值 比较复杂的就是 子传父 了重点还是要了解一些 $emit 这个api二十║Vue基础终篇传值组件项目说明 我这篇文章写的还算是详细如果还是不懂咱们再一对一讨论吧。 2、动态事件绑定—— apply 这个apply 有点儿想 call 回调函数首先每个函数都包含两个非继承而来的方法.apply()和 .call()。这两个方法的用途都是在特定的作用域中调用函数实际等于设置函数体内this对象的值。这两个方法接收的参数可以分为两个部分 第一部分是在其中运行函数的作用域如果就在当前函数体中运行就可以直接使用this值如果在window作用域中使用可以传入window值这样可以实现扩充作用域 第二部分是参数组在apply中可以传入Array实例也可以是arguments对象在call中传递给函数的参数必须逐个列举如果没有参数这个部分可以省略。首先我们来看看网上apply()方法的定义:1. apply()方法能劫持另外一个对象的方法继承另外一个对象的属性2.Function.apply(obj,args)方法能接收两个参数3.obj这个对象将代替Function类里this对象4.args这个是数组它将作为参数传给Functionargs–arguments 举个例子如下所示function sum(num1,num2){ return num1num2;}//两个数相等就相加,不相等就相乘function mul(num1,num2){ if(num1 ! num2){ return num1*num2; }else{ return sum.apply(this,arguments); //可以为 sum.apply(this,[num1,num2])或sum.call(this,num1,num2); }}console.log(mul(5,6)); //30console.log(mul(6,6)); //12说句简单的我认为就是在其他地方去调用某一个方法很重要的一个点就是 this 这个到底指向什么自己可以好好调调。 3、动态路由过滤—— addRoutes 这个在上边的步骤里我没有说到是因为我们把 按钮 给放出来以后在动态菜单路由的时候会出现重复的问题所以我们就需要坐下过滤注意这个不是错误是警告意思就是我们把一些重复的东西添加到路由里了路由会忽略掉只不过给大家一个 warm 而已。 所以呢我做了一个过滤封装了下 route.addRoutes——在 src\router\index.js 中我们过滤下重复路由还是递归router.$addRoutes (params) { var f item { if (item[children]) { item[children] item[children].filter(f); return true; } else if (item[IsButton]) { return item[IsButton]false; } else { return false; } } var paramsFilt params.filter(f); router.addRoutes(paramsFilt)}然后咋其他的地方将 router.addRoutes 统一都换成 router.$addRoutes 。搞定 四、Github Gitee Corehttps://github.com/anjoy8/Blog.Core Vuehttps://github.com/anjoy8/Blog.Admin 一起学习一起进步 QQ群867095512