与你相识
![](https://i-blog.csdnimg.cn/blog_migrate/48e5c8c40905450c1f6023fcc293bad9.jpeg)
博主介绍:
– 本人是普通大学生一枚,每天钻研计算机技能,CSDN主要分享一些技术内容,因我常常去寻找资料,不经常能找到合适的,精品的,全面的内容,导致我花费了大量的时间,所以会将摸索的内容全面细致记录下来。另外,我更多关于管理,生活的思考会在简书中发布,如果你想了解我对生活有哪些反思,探索,以及对管理或为人处世经验的总结,我也欢迎你来找我。
– 目前的学习专注于Go语言,辅学算法,前端领域。也会分享一些校内课程的学习,例如数据结构,计算机组成原理等等,如果你喜欢我的风格,请关注我,我们一起成长。
Introduction
因为自己在校做一个项目的时候用的是团队自己搭建的项目,基于el-admin,不过后端不是spring boot,而是gin框架(Go语言),虽然后端框架不同,不过思想也大差不差,记得刚接触这个框架的时候,官方有一些使用手册,但是不够详尽,然后去网上找了一圈也没什么教程,这让我很苦恼,经过了一个月左右时间的磨练,也有了自己的一些理解,希望能整理出来,抛砖引玉。
也许不能把el-admin的整个脉络清晰的叙述出来,但是做到能够基本的使用,入门,应该还是可以的,有问题的话可以评论,我们一起讨论。
eladmin 官方快速上手地址 :
https://el-admin.vip/guide/#%E5%9C%A8%E7%BA%BF%E4%BD%93%E9%AA%8C
预览地址 :https://el-admin.xin/system/timing
账号:admin 密码:123456
我们团队基于el-admin开发的go-sword-admin开源地址(github):
前端:
https://github.com/sanyueruanjian/go-sword-admin-web
后端:
https://github.com/sanyueruanjian/go-sword-admin
下面是el-admin的预览画面,它迭代到如今,已经有了几万行代码,整个体系已经比较的庞大了。
不过因为能力的原因,我可能无法把el-admin里的内容都覆盖到
我们这次做的项目大概是这个样子,接下来我的讲述将基于下面这个项目——面向实战学习。
Table of Contents
项目框架
第一步需要先看一下项目的文件架构,让自己面对一个全新的架构不至于那么慌乱。
前端
- 【public】:里面存的是el-admin的图片和默认主页,对我们做项目没什么价值。
- 【src】:里面存储了项目源码
- 【api】:存储各个模块的api函数,el-admin使用RESTful风格来管理接口,接口就是前端通过给后端发送请求,后端接收到请求之后,进行自己的逻辑处理,最终把数据可以返回给前端,这样前端就收到了数据。
- 【assets】:原el-admin的静态资源文件夹,存放了一些图片和图标,不过我们的项目并没有用到。
- 【components】:一些公共组件,比如搜索框,增删改按钮等
- 【layout】:这个文件里存储了el-admin的侧边栏和主体框架的布局,一般不对这里进行更改。
- 【mixins】:mixins 混入,这里要先提及一下Vue中的mixin(混入),简单介绍来说,相当于Java中的extends ,继承。
简单的小例子:
一个Vue组件(组件1)去混入另外一个Vue组件(组件2),相当于这个组件(组件1)继承了被混入组件(组件2)的属性。其中的data域中的不同名属性直接都保留,同名属性取这个组件(组件1)的值,methods域规则同data域,钩子函数则二者的都会被执行,但被混入组件(组件2)的钩子函数会先执行,具体的可以查看Vue.js中mixin的官方介绍.
- 【router】:存放了路由相关的信息,一般也不怎么修改,包括动态路由,静态路由的信息。
- 【store】:存放了框架中的一些状态信息,算是框架的一些配置信息,比如token的获取,token的过期时间,是否显示某些东西,我们这次做项目没有用到里面的内容,关于权限和token这一块都已经封装好了,我也就没看里面的源码。
- 【utils】:工具包,里面存放了一些框架的工具方法,比如获取token,设置token,标题,请求,验证等。
我找到了另一篇博客介绍了一些这里常用的工具方法(博客地址在最下面):
getToken():获取token
setToken(token, rememberMe):设置token信息
parseTime(time, cFormat):将时间解析为字符串,传闯入data和格式,返回相应格式的数据
formatTime(time, option) :格式化时间,和parseTime是不同的,这个方法可以将时间具体格式成 ‘刚刚’、‘一天前’、‘一小时前’…等等等
getQueryObject(url):可以获取url路径上的参数列表,封装成一个JS对象返回给你。例如https://mp.csdn.net/console/article?spm=111&id=222 ,返回的object{spm:111 ,id:222}
byteLength(str):返回字符串的字节长度
cleanArray(actual):这个还是比较常用的,可以帮助我们将数值中的空值给清除掉
param(json):这个就更常用了显现是调用了上边的cleanArray,清除jason中的空值,
param2Obj(url):与getQueryObject的区别在于,这个是返回的一个字符串对象(JSON对象)
html2Text(val):就像函数名所写的那样,将一个节点转化为 html代码。
objectMerge(target, source):合并两个对象,相同字段保留source中的值。
toggleClass(element, className):切换一个类名,类存在则删去,不存在则添上。
debounce(func, wait, immediate):防抖函数,防抖:触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。
deepClone(source):deep深度拷贝,这只是deep copy的一个简单版本,有很多边盒缺陷如果你想使用一个完美的深拷贝,可以使用lodash的.cloneDeep
uniqueArr:根据传入的数组,生成一个无重复值的数组(内部通过Set集合实现)
createUniqueString():生成一个唯一码,类似uuid
hasClass(ele, cls):检查节点是否具有该类。
addClass(ele, cls):给节点添加该类
removeClass(ele, cls):删除该类
regEmail(email):对邮箱进行加密,例:123456789@163.com =>123****@qq.com
regMobile(mobile):对手机号进行加密,例:15500001234 => 155****1234
downloadFile(obj, name, suffix):下载文件,原理帮助我们生成一个不显示的a连接,然后触发点击事件,然后删除a连接。
- 【view】:里面做我们的页面渲染
整个前端内容很多,但是如果想在el-admin基础上进行开发的话,其实只需要重点关注api
,components
,utils
,views
这几个就可以了。
后端 (Gin框架)
- 【app】:下面存着我们的后端项目文件
- 【admin或smartcampus】:这两个都是我们项目的文件,下面往往都会有四个文件夹,
apis
,ctrl层,用来接收请求,接收前端传来的数据。models
,Dao层,用来操作数据库。router
,存放本模块各种路由信息。service
,service层,用来做一个承上启下的过程,apis
获取前端传来的参数之后,自己会进行校验,然后调用service层的函数,把接收的参数当做参数传递,此时service
层的文件就可以根据自己的逻辑对这些传来的数据进行处理,如果有需要调用数据库的事情,比如增删查改操作,就在service
层调用models的函数来获取数据。 - 【common】:里面写了各个模块的一些公共的方法,比如获取用户的上下文,错误处理,数据库迁移的设置,服务启动,路由设置等,基本上还是原框架所用到的一些方法,内容也不多。
- 【logs】:存放了各个层级的error
- 【pkg】:里面存的是第三方库的引用,比如
casbin
,jwt
,file
的封装方法。 - 【settings】:这个里面保存了
settings.dev.yml
,settings.prod.yml
文件,也就是程序各种各样的配置,比如端口,ip,一些全局的配置等。 - 【utils】:写了各个模块的工具方法,不过我们的项目也用的不多。
- 剩下的都是git,或者go的包管理,主程序文件了。
源码分析
我感觉el-admin最难以理解的,还是前端,所以笔墨可能会偏前端一些。 我想把我关于这块的知识阐述出来,但是我一直没找到一个比较好的方式,所以就常规性的,第一模块是文件架构,第二模块源码分析。
但是怎么分析才能让大家有所获益呢?后来我想了想,前端就带大家捋一个页面是如何形成的,然后重点再说说各个我觉得比较重要的内容。
后端就带大家纵览全局,看看整体流程,以及如何写一个接口。
前端
一个页面是如何形成的?
新建文件夹
首先,这个框架一个中规中矩的页面,大概就是这个样子,el-admin是基于element组件的,所以我们在开发el-admin的时候,需要先去了解一下element组件。
需要建立这样一个页面,我们首先需要去【views】中新建一个自己模块的文件夹,假如说就叫model1
吧,然后可以在这个文件夹下再新建一个文件夹,比如test1
吧,然后可以创建一个index.vue
文件。
类似于下面这样,此时我们已经相当于建立了自己的页面文件,但是如何在网页的菜单中点击某个菜单访问index.vue
需要我们进行一些设置。
这些名字都无所谓,包括index,都可以改成其它的,只需要配置好就可以了。
新建菜单
我们需要在页面左侧的菜单栏的最下面,出现一个测试管理
的下拉菜单,然后里面有一个测试
二级菜单,当点击这个测试
菜单,就会跳到我们刚才新建的model1/test1/index.vue
页面。
我们进入菜单管理,然后点击新建按钮。
- 菜单类型:有
目录
,菜单
,按钮
三种类型,所谓的目录,就是左边你所看到的系统管理
,学生管理
,类别管理
,考评管理
这些一级标题,这也是我们在写一个新的模块的时候,所最先去做的事情。 - 菜单图标:作为展示的图标
- 外联菜单:我们设置
非外联菜单
就可以了,外联菜单
是指你需要跳转到外部的链接,比如说百度,比如说搜狐等,关于这部分的设置,在el-admin的前端手册中有说明,此处不在赘述。 - 菜单可见:
菜单可见
是指是否在侧边菜单栏中显示。 - 菜单排序:后端可以通过这个排序数字来对菜单进行一个排序,在有些时候有用,比如你创建了一个
model1
,model2
,model3
三个模块,你就是想让他们按照某个顺序展示出来,就可以通过这个排序的数字来控制。 - 路由地址:就是浏览器访问这个菜单的地址,我这里写的是test,那么访问这个顶级类别下的二级类别就应该是
http://127.0.0.1:8000/test/xxx
。
通过下面的方式,我就创建了一个测试管理模块。
可以看到我们已经创建成功了。 此时常理来讲,你在侧边栏是看不到这个菜单的——即使你新建了,不过不要着急,我们还是一股脑的再建一个二级菜单,一块让它显示出来。
我们刚才建立了一个菜单类型为目录的菜单,现在我们要创建一个菜单类型为菜单的菜单,也就是我们的二级标题,顺带插一嘴,按钮
类型的作用不在页面显示上,而是为了控制权限,等我到casbin权限那一块再细细讨论。
我就只解释几个字段:
- 路由地址:就是访问这个菜单的URL地址,我写的是
test1
,它的上级类目是我们刚刚创建的测试管理
,它的路由地址是test
,而我们的测试一
二级标题的路由地址是test1
,那么也就是说访问测试一
的url地址应该是http://127.0.0.1:8000/test/test1/xxx
。 - 组件路径:是当我们点击
测试一
这个二级标题,访问http://127.0.0.1:8000/test/test1/
的时候,会渲染哪个页面?这个时候就把我们刚才创建的model1/test1/inddex
用上了,你可以根据自己的名字来创建。 - 组件名称和菜单缓存是相互的关系,如果不用菜单缓存,组件名称可以不填,其它的字段,我也不是很清楚了,暂时没用上。
这样就可以看到我们已经创建好了测试一
。
给角色分配菜单
el-admin的菜单是按照角色来分配的,你可以控制某个角色能看到某些菜单,相应的不让看到某些菜单的话,对应的接口,这个角色也无法访问,这个api的权限控制使用到了casbin,暂且不表。
当我们点击角色管理,因为我登陆的是admin账号,属于超级管理员的角色,所以我就设置超级管理员这个角色的菜单分配了,这个地方有个坑,就是很多人会去点击那个选择框,会发现右边的菜单分配并不会变化,那是因为勾选选择框是代表对这个用户进行操作,并不是菜单分配,只需要点击一下这个用户的空白地方,右边就会显示这个用户的菜单维护情况了,我们看到我们刚才新建的测试管理模块并没有被勾选上。
我们把它勾选上,然后点击保存,保存会等待一下,其实这个时候后台在为这个用户添加该测试模块
的一些权限配置。
保存成功之后刷新页面就能看到我们创建的测试管理
了。
跳转到开发页面
此时我们点击我们创建的测试一
,会发现和我们测试的猜想是一模一样的,我们访问了/test/test1
地址,然后访问了我们创建的index.vue文件,这里面是我复制的另一个页面的数据。
如果你要开发一个模块的话,现在就可以点击那个vue文件进行开发了,接下来我会带着你解析一下这个vue文件的构成。
vue文件构成,如何在el-admin前端的基础上写出我们想要的样子?
el-admin的各个页面基本上都是下面的这种结构,大差不差,不过有的时候它可能无法满足我们的要求,我们可能会需要自己去做一些个性化的改善。
刚才我们看到的页面就是下面的代码。
- 【template】:整个页面的内容写在这个标签下
- 【app-container】:这个里面包含了所有的主体内容。
- 【head-container】: 这个div里面建立了
input搜索框
,日期搜索框
,搜索
按钮与重置
按钮,以及第二排的新增
,修改
,删除
,导出
按钮,和右边的三个按钮。 - 【el-dialog】:当点击
添加
或编辑
按钮的时候会弹出这个对话框,是element的组件。 - 【el-table】:展示的主题控件,是element的组件
- 【defaultForm】:里面定义了表单的初始值,以及控件数据源的绑定,也涉及到框架内部对字段的维护,比如点击弹出框的
取消
按钮,消除所有的内容,就需要把弹出框的变量都写在defaultFrom
中。 - 【export default】:这一块定义了核心的内容
- 【name】:这个对标的是我们创建
菜单
的时候,有个组件名称
字段,用于菜单缓存
,不过我们也没用到,所以写不写都行。 - 【components】:这是我们的页面中所用到的组件,我这里引用了六个组件,前五个是比较常用的,
udOperation
是表格中最右边的编辑
和删除
按钮,DateRangePicker
是日期搜索框需要用到的,rrOperation
是搜索框右边的搜索
和重置
按钮,pagination
是分页组件,crudOperation
是搜索框下面的四个按钮,IconSelect
是我们需要去选择图标的时候用到的组件。 - 【cruds】:这个里面定义了一些进入这个页面的时候,对框架进行一些初始化的内容,比如
title
,中间table
所访问的url地址,api的引入地址,或者一些其它的设置等,总之当你进入到这个页面的时候,会有一大堆的东西可以提前设置一下,有些是必须要设置的,有些可以先不设置。 这个crud常常指代的就是el-admin这个框架的运转。 - 【mixins】:设置混入模式,不过因为我个人对前端并不是很专精,所以这个我不是很清楚,不过我大概知道混入模式的各个模块可以共用属性,至于为什么要用这几个就不太清楚了,参考其它的页面用的是这几个,就照着用了。
- 【data】:设置一些变量,以及rules验证
- 【methods】:这个就不多说了,关于本页面的js操作就在这里写了。
- 【name】:这个对标的是我们创建
template页面渲染
搜索和crud按钮
接下来我们就专门讨论一下页面渲染这一块,看看各个部分是怎么组成出来的,以及,如何写出我们想要的样子。
我们先看下面的蓝色部分,首先第二句有一个v-if
来控制这个div的显示与隐藏,可以看得出来是crud的searchToggle
属性来控制的,不过我暂时还没有弄明白它具体有什么用,待日后再填吧。
紧接着是一个el-input
,这里面的各个属性大家可以自己去查一查,class也是框架自带的,需要重点关注的有三个属性:
- 【v-model】:你可以写
query.xxx
的名字,这个地方的作用是当你写的是query.blurry
时,当你点击搜索按钮,搜索框的内容发入后端的参数名就是blurry
,同样的,当你写query.name
的时候,在输入框中输入内容,然后点击搜索,就会发现参数变成了name
,至于点击搜索去访问什么url地址,去哪里设置接口的地址,我后面再讲。
- 【placeholder】:这个就是当控件没有内容的时候的提示,你要根据你的业务进行填写。
- 【keyup.enter.native】:这个是当你在这个控件输入内容之后,你按了一下
enter
键,进行的操作。crud.toQuery
就是搜索
的方法,也就是当你在搜索框内输入内容,你可以点击搜索按钮来执行搜索,也可以按enter
键来执行搜索。
接下来的是【date-range-picker】组件,这个组件就是我们的时间搜索框
,它绑定的query.createTime
和搜索的有些不同,这个字段相对固定,因为当你点击搜索的时候,会去获取createTime
这个字段的值,然后进行一定的处理,再发出去。 这也是为什么当你选择时间再搜索会发现多了两个参数,一个是startTime
,一个是endTime
,这都是框架里写好的,不过你要是想改,也可以去改,后面介绍到crud.js
的时候,我会和你讨论的。
总之它会接收query.createTime
这个参数,然后它是一个数组,里面存了开始日期和结束日期,也就是格式为[start,end]这样的格式,crud会对它进行处理,最终再把他们给两个参数传给后端。
在接下来,你会看到<rrOperation />
这一行信息,如果你追踪到这个组件的话,会发现它就是搜索
和重置
按钮。
紧接着又看到了<crudOperation :permission="permission" />
这一行,这是第二排那四个按钮,以及第二排最右边还有三个不显眼的按钮,permission定义了这些按钮的权限,这个等讲到js代码的时候再说。
这样第一部分我们就讲完了。
点击新增和编辑的弹出框
第二部分是下面的代码,它是一个对话框中套了一个表单控件。
首先说说<el-dialog>
的属性:
- 第一行为
false
是为了控制不能点击对话框外空白的地方关闭对话框。 - 第二行表示当你点击对话框的右上角叉号的时候,会去调用
crud.cancelCU
函数,而这个函数会将对话框关掉。 - 第三行可以看出crud是如何控制对话框的开启和关闭的,是靠crud中status下的cu属性,通过控制它的属性来控制对话框的开启和关闭,至于右边的
showInsertDialog
属性,那是我自己加的,是我想在crud的基础上,再限制一些条件才能开启。 - 第四行设置了对话框的标题,它是通过
crud.status.title
来获取的,而这个属性,在下面script中会有赋值。 - 剩下的属性自己查吧。
接下来就说说el-form
组件
el-form
中ref
和model
属性必须是form
(框架内进行维护的就是这个名字,除非你有其它的用处),也就是说只有为form
这个名字,它才会被crud
检测到,上面那些crud.xxx
的属性才能作用到这个对话框上。
接下来的item,你就可以自己去百度查如何写了,或者参考el-admin的其它新增页面,看看是怎么写的,自己做一些修改,这个不是我们的重点,就不赘述了。
唯一一点需要强调的是各个item项下的控件的v-model
属性绑定的都是form.xxx
,需要写成这样的形式,而item的prop
属性一般和xxx
相同(参考上图的积分下限即可,prop=lower_limit,v-model=form.lower_limit),然后这些xxx
都需要在下面的defaultForm
属性中定义下。
当你点击确定,发送表单的时候,prop
属性就是你发给后端的参数,比如积分下限,我们输入了-1,点击确定,发送给后端就是lower_limit:-1
,v-model.number
可以控制发送的数值为数字,如果你发送的无法转为数字,vue会发送原本的字符。
主要需要考虑一个这些输入框和crud的协调问题,既然我们需要crud的帮助,就要遵守crud对我们制定的规则。
表格
这常常是我们对这个页面最关心的部分。
接下来我们来看看这段代码
还是先看看属性,有三个关于crud的:
- 【v-loading】:这个是控制表格加载的,为true就加载,为false就停止加载,crud有一个
loading
属性来控制,比如添加后要重新加载一下,编辑要重新加载一下等等。 - 【data】:这个是表格的数据,等于
crud.data
,而crud.data
属性会获取后端传来的数据,这个我们后面再说。 - 【selection-change】:这个是当你打勾表格的数据的时候,crud会有一个
selections
属性来存储对应行的数据,是一个列表。
属性讲完之后,就会表格各个列的名字了,其中会发现有三个地方比较瞩目: - 【考评id和积分类别id】:v-if=false就是不显示出来,既然不显示出来,又为什么要在这里呢?是因为在
编辑
某一条数据的时候,我们往往需要携带这一条数据的id给后端,那么我们就可以通过这个隐藏的列来拿到id。 - 【创建日期】:这一列我们用parseTime来将后端传过来的时间戳转为日期。
- 【操作】:也就是最右边的两个按钮,它是调用了
<udOperation>
组件,这个组件下也有permission,可以控制权限,也就是哪个角色会显示哪个按钮。
另外一个最重要的就是各个列的prop
属性不是乱写的,需要根据后端传来的参数来填写,table会自动的填充对应的数据。
比如你想让某一列得到超级管理员
这个值,那就把它的prop设置为creator
。
分页组件
这个用它默认的就可以了,只要数据返回的符合规范,就没有问题。
script
import
第一部分当然是import,这些都是我们要用到的内容,第一行是我们的api的位置。
可以看到我在api文件夹中创建了我们的模块,里面存放了本模块的api
可以让你看看,大概是这个样子,你需要注意这里的add,del,edit三个函数,因为他们的名字不能更改,讲到下面的URL的时候再说这个事情。
defaultForm
这里就把form中的各个参数写下来就可以了,可以给一些默认值,null就代表空。
export
之前讲过的就不讲了,重点讲一下前面的cruds(),这个是crud内部的方法,用来作初始化。
title
属性会控制弹出框的标题,如果你写“考评类别”,crud会存title为“考评类别”,当你点击新增
按钮的时候,它会在title的前面加上“新增”,所以最终呈现的就是“新增考评类别”,当点击编辑就变成了“编辑考评类别”,但其实新增和编辑都是用的同一个对话框。
url
属性非常的重要,这一个地址影响了很多,它就是我们访问的api地址。
当我们刚进入到这个页面的时候,它就会访问http://localhost:8013/api/appraisal-classification/list
这个地址,是一个get请求,返回的数据必须如下图所示,否则框架会找不到对应的数据。
也就是最外层是code,data和message属性,这个message属性就是我们做各种操作的提示信息,data下有current,orders,pages,size和total属性,这五个是有关分页和排序的数据,再加上一个records才是我们查出来数据库的内容。
这些属性少了都会有问题。
当你点击搜索
的时候,也会走这个地址,如果搜索的输入框
有内容的话,会在原来的参数基础上加上输入框的内容,如果日期搜索
有内容的话,也是这样。
所以如果想完成搜索功能,后端需要接收一个input
框的内容,然后可以做模糊查询之类的,还需要接收startTime
和endTime
。
crudMethod
存的是我们引入的api中的内容,相当于是让crud这个框架知道这个页面用的是什么api,另外你自己想用某个api的数据,也可以通过引入的名字来调用。
它的下面是optShow
属性,会发现里面有五个属性为true,这个是控制第二排四个按钮,和重置
按钮的显示,比如有的时候我们不需要导出功能,就需要让download
属性为false,这个时候你就会发现页面上没有导出
按钮了,其它也是同理。
这个时候我们就要聊聊api中的add
,del
,edit
函数了。
这三个函数的名字是固定的,甚至连参数的格式也是固定的。
当点击页面上的添加按钮
并提交后,会调用这里的add
函数,参数是form表单的数据。
当点击页面上的删除按钮
,或勾选了很多进行删除,都会调用del
函数,给后端发送一个list(不是json),只是一个list,类似[1,2,3]
,里面存的是选中行的id。
当点击页面上的修改按钮
并提交后,会调用edit
函数,参数是form表单的数据外加编辑的那一行table的数据。
这样的话,整个页面我就算是讲完了,剩下的我感觉自己摸索就可以了。
component
components文件夹下有很多的内容,比如面包屑,导航栏,图标,日期搜索框等。
而对我们最重要的,就是Crud这个文件夹内的内容了,所以今天就只讲讲这一块。
crud
这个文件夹下,我就说crud.js
和CRUD.operation.vue
两个内容,把这两个内容了解一些,其它的内容也可以理解一些了,另外就是其它的内容我研究的也不多,希望各位能多出一些其它的内容来教教我,感激不尽。
CRUD.operation.vue
这就是它的能力范围,我为什么要说这个呢? 因为有的时候,我们不见得就想用它的按钮,比如我们想加个批量修改的按钮,就需要自己在CRUD.operation的基础上进行一个封装才可以。
点开之后是这样一堆的东西,上面写的是四个按钮,可以看到为什么我们在页面中optShow
属性中,通过对download属性设置false,可以让导出按钮消失,就是这个v-if设置的,同样的你想让其它button消失,也可以进行设置。
然后你会发现下面有较为复杂的js代码,其实你没必要看懂的,也不太需要。
如果你想在导出
的右边再加一个按钮,只需要复制一下导出
这个按钮,然后改一下名字,然后把click事件改一下,完成自己想要的功能就可以了。
crud.js
添加按钮的执行过程
我们可以通过CRUD
组件来打开crud.js
的大门,页面往往有四个按钮,我带你分析一下新增按钮
,可以发现click绑定的是crud的toAdd
函数。
我们找到这个函数,会发现它的作用是启动添加
。
首先是调用了resetForm()
函数,清空一下表单,接下来是关于crud钩子的判断,然后比较重要的是设置了一下add
的状态,为CRUD.STATUS.PREPARED
,这个状态代表现在是启动添加
,。
你找一下这个状态,会发现它的值为1
你还记得弹出框有个通过crud.status.cu > 0
来控制对话框的显示和关闭吗?而我们通过找到cu,发现它是通过判断按钮的值来返回的,此时cu的值就是1,那么对话框就会弹出来。
也就是当你点击新增按钮的时候,调用了toAdd
方法,这个方法设置了crud.add=1,而cu属性会获取这个1,对话框通过cu属性>0来显示。
接下来我们再看看toAdd
函数第一行调用的resetForm
函数,可以看到第一行它就去找form
节点,如果你的对话框的ref不是form
的话,就找不到了。
此时用户应该在填写表单,如果它点击了取消,会调用cancelCU
函数,如果点击确定会调用submitCU
函数。
这个cancelCU里进行了一大堆,其实就是维护状态,把他们的status都变成0,也就是CRUD.STATUS.NORMAL
,然后再resetForm
,把表单清除一下。
按钮的操作中主要靠这个状态来做操作。
submitCU重要的是下面,它会通过校验是哪个按钮是PREPARED
状态,也就是正在写表单
的状态,那就说明哪个该提交了,那么它就会走crud.doAdd()
。
我们点进去发现它是执行添加函数,可以看到函数内第三行是给add赋值了一个PROCESSING
状态
按钮其实就是三个状态:NORMAL
、PREPARED
、PROCESSING
,第一个代表无操作,第二个代表这个按钮被点击了,用户正在写对话框中的数据,属于占用状态,第三个就代表用户已经写好了对话框,点击提交,是提交阶段。
紧接着你就发现它调用了Method.add
,也就是我们页面中引入的api文件中的add函数,然后把form表单中的数据存进去。
因为已经开始调用api了,也就说明已经提交上去了,如果提交成功,就把add的状态重新变为NORMAL
,也就是0
,那么对话框就会消失,如果提交报错,就会走catch
,把add的状态重新设置为PREPARED
,也就是1
,对话框不会消失,此时你可以查看错误重新提交。
添加过程就结束了。
各种常用的函数
接下来就是在crud文件的闲逛了。
这个title返回的数据就是页面中crud.status.title
获取到的,如果判断是新增按钮,就加新增两个字,如果判断是编辑按钮,就加编辑两个字。
内部还有一个可以获取query参数的函数,通过传名字就可以获得对应的值。
看一下刷新函数吧,点击重置
按钮,或者新增,删除,修改,搜索也都会引起刷新。
之前说后端参数的时候,为什么说返回的格式必须要那样返回,是因为后端在获取参数的时候都是写好的。看我红框的这一条,crud.data就是我们的页面中table的数据,当没有页数的时候,它获取的是res.data
,当有页数的时候它获取的是res.data.records
,也就是说,当你没有分页的时候,你返回的格式应该是res.data,data下是你的数据列表,当你有分页的时候,就要再加一个records来存你的数据列表。
下面这个是获取查询的参数,input框的就不说了,主要看createTime
那里,它会获取这个项为createTime
,也就是页面上的query.creatTime
是不能改的,获取到了之后,对这个time进行了一些转换,然后通过crud.query
的参数来存一下,这个就是发给后端的参数名,可见,也是写死的,不过可以通过修改这里来改变名字。
在这个文件的最下面,会发现有一个CRUD钩子,这个是很好用的。
它就是crud的生命周期,比如你想在crud的Refresh(刷新)函数调用之前,也就是每次重新加载数据之前,想做一些事情,就可以在这里写。
又比如你想在点击编辑按钮之前做一些事情,也可以找到对应的钩子去写语句就可以了。
最后想说说casbin
casbin可以实现对某个角色进行api级的控制,可以让某个角色去访问某些api,或者去禁止某些api。
你下载el-admin,会发现它有一个casbin_rule数据表,里面存的是一些策略,v0下的1代表是sys_role表id=1的角色,v1是api地址,v2是GET,也就是当用户角色id=1的时候,就运行它访问/api/activity请求,类型为GET。
比如说你想限制某些角色的能力,就可以在这里进行控制。
那么我们一个一个的加,肯定不现实,前端有方式去做。
添加菜单的时候,会发现它有一个请求方式
和请求路由
,这个对标的是我们刚进入这个页面的那个table
的查询接口。
当你写上/api/activity GET的时候,当你为某个角色分配这个菜单,它就会在casbin_rule这个表格里添加对应的数据。
那么同样的,每个菜单下还有很多的按钮,每一个按钮都有对应的地址,就可以点击按钮新建了,也有这个请求方式和请求路由,按钮新建之后并不会在页面上显示,它只是一个为casbin权限控制作说明而已。
这样当你对角色1分配这个菜单之后,这个菜单对应的接口对应这个角色会添加到casbin里,然后这个角色调用这些已经被允许的接口才会被通过,否则显示权限不足。
需要注意的是,它同样需要后端的配合,如果后端没有搭建casbin的话,依然没有作用。
后端
这一篇内容写了很久,起初是想前后端都写,但是后来想想,后端好像没什么可写的,既然都接触到这个程度了,不至于连接口是什么都不清楚。
我感觉前端摸清楚了之后,后端并不怎么复杂。 就是一个不断的调接口的过程,知识是相对比较固定的,如果你是Java语言,大可以把el-admin的后端下载下来,然后在其基础上进行删改,添加。
如果你是其它语言,可以先找一个框架,然后找一个框架好用的脚手架,在这个脚手架的基础上写接口来返回数据就可以了。
基本上获取的时候,都是这个参数,Current,Size,Orders前端会自动返回给你,Content是搜索框的内容,StartTime和EndTime是时间搜索框的内容。
如果有哪些地方我没讲明白的,或者忽略了,忘记讲了,欢迎找我讨论,或者下面评论,我会回复或进行更新。
感谢 & 参考资料
博客:
在写文件架构的时候,部分内容参考了下面这个博客。
el-admin框架简单解析-快速入门(前端部分)
欢迎评论区讨论,或指出问题。 如果觉得写的不错,欢迎点赞,转发,收藏。