危险

为之则易,不为则难

0%

06_人资后台

✔ 完成员工界面的交互(左树右表)。

员工管理-页面结构

  1. 基本的页面结构,src/views/employee/index.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<template>
<div class="container">
<div class="app-container">
<el-card>
<div class="left">
<el-input style="margin-bottom: 10px" type="text" prefix-icon="el-icon-search" size="small" placeholder="输入员工姓名全员搜索" />
<!-- 树形组件 -->
</div>
<div class="right">
<el-row class="opeate-tools" type="flex" justify="end">
<el-button size="mini" type="primary">添加员工</el-button>
<el-button size="mini">excel导入</el-button>
<el-button size="mini">excel导出</el-button>
</el-row>
<!-- 表格组件 -->
<!-- 分页 -->
</div>
</el-card>
</div>
</div>
</template>

<script>
export default {
name: 'Employee'
}
</script>

<style lang="scss" scoped>
.app-container {
:deep(.el-card__body) {
background: #fff;
display: flex;
}

.left {
width: 280px;
padding: 20px;
border-right: 1px solid #eaeef4;
}

.right {
flex: 1;
padding: 20px;

.opeate-tools {
margin: 10px;
}

.username {
height: 30px;
width: 30px;
line-height: 30px;
text-align: center;
border-radius: 50%;
color: #fff;
background: #04c9be;
font-size: 12px;
display: inline-block;
}
}
}
</style>

员工管理-左侧树的加载

  1. 定义树组件需要的数据,src/views/employee/index.vue
1
2
3
4
5
6
7
8
9
10
11
12
export default {
name: 'Employee',
data() {
return {
depts: [], // 组织数据
defaultProps: {
label: 'name',
children: 'children'
}
}
}
}
  1. 放置树形组件。
1
<el-tree :data="depts" :props="defaultProps" default-expand-all :expand-on-click-node="false" highlight-current />
  1. 初始化时加载数据转化树形,src/views/employee/index.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import {
transListToTreeData
} from '@/utils'
import {
getDepartments
} from '@/api/departments'
export default {
name: 'Employee',
// ...
created() {
this.getDepartment()
},
methods: {
async getDepartment() {
this.depts = transListToTreeData(await getDepartments(), 0)
}
}
}

员工管理-选中首个节点

  1. 在 data 中声明一个记录 id 的参数,src/views/employee/index.vue
1
2
3
4
5
6
7
8
9
10
11
12
export default {
name: 'Employee',
// ...
data() {
return {
// ...
queryParams: {
departmentId: null
}
}
}
}
  1. 初始化时首个 id 节点,并且选中,src/views/employee/index.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
export default {
name: 'Employee',
// ...
methods: {
async getDepartment() {
this.depts = transListToTreeData(await getDepartments(), 0)
// #1
this.queryParams.departmentId = this.depts[0].id
// #2 DOM 更新是异步的
this.$nextTick(() => {
this.$refs.deptTree.setCurrentKey(this.queryParams.departmentId)
})
}
}
}
  1. 给 el-tree 组件设置 node-key 属性,否则 setCurrentKey 方法不知道设置的是哪个字段的值。
1
<el-tree ref="deptTree" node-key="id" :data="depts" :props="defaultProps" default-expand-all :expand-on-click-node="false" highlight-current />
  1. 监听树组件的节点切换事件并记录当前点击的 ID。
1
<el-tree ref="deptTree" node-key="id" :data="depts" :props="defaultProps" default-expand-all :expand-on-click-node="false" highlight-current @current-change="selectNode" />
1
2
3
4
5
6
7
8
9
10
export default {
name: 'Employee',
// ...
methods: {
// ...
selectNode(node) {
this.queryParams.departmentId = node.id
}
}
}

员工管理-员工列表结构

  1. 右侧列表页面结构,src/views/employee/index.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!-- 表格 -->
<el-table>
<el-table-column align="center" label="头像" />
<el-table-column label="姓名" />
<el-table-column label="手机号" sortable />
<el-table-column label="工号" sortable />
<el-table-column label="聘用形式" />
<el-table-column label="部门" />
<el-table-column label="入职时间" sortable />
<el-table-column label="操作" width="280px">
<template>
<el-button size="mini" type="text">查看</el-button>
<el-button size="mini" type="text">角色</el-button>
<el-button size="mini" type="text">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<el-row style="height: 60px" align="middle" type="flex" justify="center">
<el-pagination layout="total,prev, pager, next" :total="1000" />
</el-row>

员工管理-获取员工数据

第一次加载或者是切换节点之后,都要去根据点击的节点去查询员工的数据。

  1. 封装获取员工数据的 API,src/api/employee.js
1
2
3
4
5
6
7
import request from '@/utils/request'
export function getEmployeeList(params) {
return request({
url: '/sys/user',
params // 地址参数 查询参数
})
}
  1. 声明一个 list 数组接受数据,src/views/employee/index.vue
1
2
3
4
5
6
7
8
9
10
export default {
name: 'Employee',
// ...
data() {
return {
// ...
list: []
}
}
}
  1. 初始化以及切换节点时获取右侧表格数据,src/views/employee/index.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import { getEmployeeList } from '@/api/employee'
export default {
name: 'Employee',
// ...
methods: {
async getDepartment() {
this.depts = transListToTreeData(await getDepartments(), 0)
this.queryParams.departmentId = this.depts[0].id
this.$nextTick(() => {
this.$refs.deptTree.setCurrentKey(this.queryParams.departmentId)
})

// #1
this.getEmployeeList()
},
selectNode(node) {
this.queryParams.departmentId = node.id
// #2
this.getEmployeeList()
},
async getEmployeeList() {
const {
rows
} = await getEmployeeList(this.queryParams)
this.list = rows
}
}
}
  1. 绑定数据到表格,src/views/employee/index.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<el-table :data="list">
<el-table-column prop="staffPhoto" align="center" label="头像" />
<el-table-column prop="username" label="姓名" />
<el-table-column prop="mobile" label="手机号" sortable />
<el-table-column prop="workNumber" label="工号" sortable />
<el-table-column prop="formOfEmployment" label="聘用形式" />
<el-table-column prop="departmentName" label="部门" />
<el-table-column prop="timeOfEntry" label="入职时间" sortable />
<el-table-column label="操作" width="280px">
<template>
<el-button size="mini" type="text">查看</el-button>
<el-button size="mini" type="text">角色</el-button>
<el-button size="mini" type="text">删除</el-button>
</template>
</el-table-column>
</el-table>

员工管理-头像和聘用形式的处理

头像。

1
2
3
4
5
6
<el-table-column align="center" label="头像">
<template v-slot="{ row }">
<el-avatar v-if="row.staffPhoto" :src="row.staffPhoto" :size="30" />
<span v-else class="username">{{ row.username?.charAt(0) }}</span>
</template>
</el-table-column>

聘用形式。

1
2
3
4
5
6
7
<el-table-column label="聘用形式">
<template v-slot="{ row }">
<span v-if="row.formOfEmployment === 1">正式</span>
<span v-else-if="row.formOfEmployment === 2">非正式</span>
<span v-else></span>
</template>
</el-table-column>

员工管理-员工分页处理

  1. 定义分页参数,src/views/employee/index.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
export default {
name: 'Employee',
// ...
data() {
return {
// ...
queryParams: {
departmentId: null,
page: 1, // 当前页码
pagesize: 10
},
total: 0, // 记录员工的总数
}
},
methods: {
// ...
async getEmployeeList() {
const {
rows,
total
} = await getEmployeeList(this.queryParams)
this.list = rows
// #mark
this.total = total
}
}
}
  1. 绑定分页参数。
1
<el-pagination layout="total,prev, pager, next" :total="total" :current-page="queryParams.page" :page-size="queryParams.pagesize" />
  1. 切换页码事件。
1
<el-pagination layout="total,prev, pager, next" :total="total" :current-page="queryParams.page" :page-size="queryParams.pagesize" @current-change="changePage" />
1
2
3
4
5
6
7
8
9
10
11
export default {
name: 'Employee',
// ...
methods: {
// ...
changePage(newPage) {
this.queryParams.page = newPage // 赋值新页码
this.getEmployeeList() // 查询数据
}
}
}
  1. 切换部门时,查询第一页数据。
1
2
3
4
5
6
selectNode(node) {
this.queryParams.departmentId = node.id
// mark
this.queryParams.page = 1
this.getEmployeeList()
},

员工管理-员工模糊搜索

  1. 设置模糊搜索的参数字段,src/views/employee/index.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
export default {
name: 'Employee',
data() {
return {
// ...
queryParams: {
departmentId: null,
page: 1,
pagesize: 10,
keyword: '' // 模糊搜索字段
},
}
}
}
  1. 双向绑定 input 输入框,监听值改变事件,src/views/employee/index.vue
1
<el-input v-model="queryParams.keyword" style="margin-bottom: 10px" type="text" prefix-icon="el-icon-search" size="small" placeholder="输入员工姓名全员搜索" @input="changeValue" />
  1. 值改变查询数据-支持防抖查询,src/views/employee/index.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
export default {
name: 'Employee',
// ...
methods: {
// ...
changeValue(v) {
clearTimeout(this.timer)
this.timer = setTimeout(() => {
this.queryParams.page = 1
this.getEmployeeList()
}, 300)
}
}
}