目标:点击左侧员工姓名实现高亮,右侧显示选中的对应员工信息
1、树形结构
//封装一个将列表结构的数据转换为树形结构的数据
default-expand-all:定义树形结构是否展开 默认展开
expand-on-click-node:设置点击一个节点的文字下拉信息不收起, 默认收起
highlight-current:点击当前节点的时候是否高亮;默认不高亮
**注意点:**
上面三个属性值设置的时候有两种方式:
// 一、动态绑定之后设置值true或者false
<el-tree
:default-expand-all="true"
:expand-on-click-node="false"
:highlight-current="true"
/>
// 二、若属性值为true直接将属性放入标签即可,不需要额外的数据绑定赋值
<el-tree
highlight-current
default-expand-all
/>
// 三、以下写法是错误的(下图是报错的截图)
<el-tree
highlight-current="true"
default-expand-all="true"
/>
2、员工管理—初始化首个节点高亮状态
添加属性node-key="id" 前面不加冒号: a.定义一个变量queryParams: { departmentId: null } b.通过setCurrentKey配合node-key c.vue的渲染是异步的,涉及到等待机制,所以需要通过this.$nextTick进行数据设置 nextTick本质还是定时器,只不过是等待上面的步骤执行完了,没有设置时间罢了,然后调用forceUpdate手动让页面再次渲染。
// 初始化数据
async getDepartmentList() {
const res = await departs()
this.departs = translateListToTreeData(res, 0)
this.queryParams.departmentId = this.departs[0].id
this.$nextTick(() => {
this.$refs.treeRef.setCurrentKey(this.queryParams.departmentId)
})
}
3、点击员工的时候将此节点的id赋值给this.queryParams.departmentId
currentChange(node) { // node为当前选中接待的信息 — 一个对象
this.queryParams.departmentId = node.id
}
4、获取员工信息
这里员工信息的获取需要在左侧部门数据渲染之后在进行调用接口
5、点击左侧右侧对应员工信息显示
<el-tree @current-change="currentChange">
currentChange(node) {
this.queryParams.departmentId = node.id
this.getEmployeeList()
}
5、将后台返回的图片路径转换为图像(el-Avatar头像组件)
这里用到了elementui提供的插槽再配合v-if对图像的路径是否存在进行判断,有的话直接展示图像,没有的话显示人名的姓氏,这个涉及到获取第一个字符串的方法charAt(),它默认获取第一个字符串,所以不写0也可以。
6、员工分页处理
// 这个需求涉及到了三个属性:
page(当前页码)
pagesize(当前页码有多少页)
total(数据总条数)
此外,还涉及到一个改变页码的事件current-change 这个事件在触发的时候会携带当前页码
这个地方有个注意点就是:在点击左侧的部门进行切换的时候,需要将当前的页码设置为1
7、搜索员工涉及到的知识点
-
防抖处理 首先我们需要给输入框绑定input事件,但是这样会导致在输入值的时候对后端过多的请求,为提升性能,我们需要对这一情况做防抖处理。具体做法是:将业务代码放入延时器中,同时延时器向外暴露它的id => this.timer,在延时器代码执行之前我们先清除this.timer,这样就实现了防抖处理。
-
change和input两个事件的区别:
- change:仅在输入框失去焦点或用户按下回车时触发
- input:在input值改变的时候触发
-
为何不在data里面设置timer,而是用this.timer data里面的数据都是响应式的,这里的timer只需要接收延时器的id,然后每次调用接口之前只需要对这个做清除处理即可。这样做能提升性能。
-
防抖(debounce)和节流(throttle)的区别
- 防抖:就是指触发事件后 n 秒后才执行函数,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
- 节流:指连续触发事件但是在 n 秒中只执行一次函数
-
防抖和节流的应用场景
- 防抖:1、用户在不断输入值时,用防抖来节约请求资源。2、- window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次
- 节流:1、鼠标不断点击触发,mousedown(单位时间内只触发一次);2、监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断
8、员工导出Excel
- 调用接口 => 返回的是二进制流数据
- 在拦截器中判断类型 if(response.data instanceof Blob) return response.data
- 获取二进制流文件:通过调用接口获取二进制流文件
- 通过FileServer插件将文件导出 FileServer.saveAs(res, '员工测试表.xlsx')
这里需要npm i file-saver 插件并引入
如何实现初始化和点击左侧部门高亮状态效果的逐字稿:
-
在获取左侧部门数据之前,我们先定义一个对象:queryParams: { departmentId: null }.这个对象的值初始为null。他是为了保存初始化和点击左侧部门时的id
-
为了提升界面的体验,我们需要给el-tree设置对应的属性
default-expand-all:定义树形结构是否展开 默认展开 expand-on-click-node:设置点击一个节点的文字下拉信息不收起, 默认收起 highlight-current:点击当前节点的时候是否高亮;默认不高亮
-
初始化通过elementUi库提供的api setCurrentKey配合node-key给顶级部门设置高亮状态。这里涉及到了vue的异步操作,需要使用vue提供的this.$nextTick()方法进行处理。
-
点击左侧部门,右侧对应的数据显示。在点击右侧部门的时候,elementui提供的点击事件会向外暴露出当前部门的信息,包括Id,我们可以通过将这个id赋值给定义好的this.queryParams.departmentId然后再执行this.getEmployeeList()即可。
9、左树右表的实现思路
-
左树
- 列表数据=>树形数据
- 我们使用到el-tree组件,但是这个组件接收的数据是树形数据,而后端返回的是列表数据,所以我们需要通过递归的方法将列表数据转换为树形数据。
- 初始化顶级pid高亮显示
- 首先初始化记录部门的id,然后配合elementui里面的setCurrentPage和node-key方法进行实现。因为里面涉及到异步操作,所以我们需要用到vue里面提供的$nextTick方法。
- 列表数据=>树形数据
-
右表
- 通过el-tabl进行员工的信息渲染,通过el-pagination进行列表数据的相应切换。这里设计的用户图像的显示和聘用形式格式的转换。图像我用作用域插槽暴露每行数据,el-avatar组件配合实现,若获取不到员工的图像,这使用charAt()方法获取员工的姓加上相应的样式替代图片进行显示。
-
左树右表的切换实现思路
- 首先将当前的页码设置为1
- 将当前行的员工id赋值给初始化记录部门的id,通过这个id获取相应的员工数据并进行渲染
10、针对搜索模块是如何进行优化的
答:在输入框进行数据输入的时候,需要实时向后端请求数据。但是这样对后端接口有很大的压力,我们可以通过防抖的方式进行优化处理。防抖的核心是利用setTimeout延时器进行相应的业务操作。
11、员工导出excel的实现步骤
- 首先我们要封装一个下载模板接口的api,这个api与其他封装的api不同点在于它设置了一个接收数据的类型 responseType: 'blob' 意思是:使用blob接收二进制文件流。
- 安装插件file-saver,然后通过这个插件将调用接口返回来的数据进行处理可下载的xlsx文件。
- 处理报错;因为二进制流文件返回的数据里面没有message这个属性,所以我们需要通过instanceof对返回的数据进行相应的处理,判单是否为blob类型,即:if(response.data instanceof Blob) return response.data。这样就解决了报错问题。
12、Excel组件封装
-
这个组件里面有个值得学习的方法,他将事件直接写在了组件内部
-
封装接口接收返回的类型binary => 二进制流数据
-
点击导出配合FileSaver插件进行文件生成和导出
13、员工导入
- 在type类型为file的input输入框里面,她有个属性accept用来设置输入文件的类型:accept=".xlsx, .xls"
- 获取短号拼接的ref值的组件,this.$refs['excel-upload-input']
-
涉及到文件上传的数据类型都为form-data
逐字稿:
- 点击导入按钮触发文件选择按钮的click事件
- 选择文件触发input的change事件
- 通过event接收选中的文件信息,并哟个files进行保存
- 为避免不必要的bug我们需要对files的长度进行判断
- new一个FormData()对象并将获取到的文件信息append进去
- 然后将这个对象传递到后端去
- 通知父组件关闭弹窗
- 通过try获取成功或者失败的信息,无论成功与否都将input里面的值清空,这个可以放入finally里面进行处理。
14、员工详情
-
数据和校验 model整个表单的数据 rules指规则
-
路由配置注意点:两种配置方法
-
组件el-select使用的注意事项:
option里面的value是传给后端的值,label是在界面显示的值
-
组件el-date-picker中,添加value-format="yyyy-MM-dd"可以设置时间格式为 2023-06-23
15、级联组件 el-cascader
-
知道里面的三个参数:
-
options:绑定数据
-
props:自定义绑定的数据属性
-
separator="-" 自定义数据间隔的属性
-
-
使用的步骤
-
从接口获取数据
-
将列表数据转为树形数据
-
此组件使用的是 value label,而后端返回的数据是id和name,所以需要通过props重置属性为:id和name
- 将数据赋值给treeData
-
至此,el-cascader组件使用完成。
这就是员工模块的技术总结。本人能力有限,不足之处还望多多指教~