六、用户管理

  1. 创建用户列表组件
  2. 配路由表(重点:子路由)
  3. 处理侧边栏导航
  4. 布局用户列表组件
  5. 请求用户列表数据,渲染到用户列表组件
    1. 发请求,得到数据
    2. 处理数据,渲染到组件模板

表格列表渲染

我们可以直接在用户列表组件的 created 生命钩子函数中发起请求加载表格数据:

  1. export default {
  2. // ...
  3. async created () {
  4. const res = await this.$http.get('/users', {
  5. params: { // 请求参数,对象会被转换为 k=v&k=v 的格式,然后拼接到请求路径 ? 后面发起请求
  6. pagenum: 1,
  7. pagesize: 2
  8. }
  9. })
  10. const {users} = res.data.data
  11. this.tableData = users
  12. }
  13. // ...
  14. }

分页处理

首先我们把接口返回的 total 总记录数交给分页插件帮我们完成页码分页:

  1. export default {
  2. // ...
  3. async created () {
  4. const res = await this.$http.get('/users', {
  5. params: { // 请求参数,对象会被转换为 k=v&k=v 的格式,然后拼接到请求路径 ? 后面发起请求
  6. pagenum: 1,
  7. pagesize: 2
  8. }
  9. })
  10. const {users, total} = res.data.data
  11. this.tableData = users
  12. }
  13. // ...
  14. }

我们发现分页插件已经根据我们给定的每页大小以及总记录数完成了分页页码功能。

接下来我们来处理点击页码加载对应页码数据的功能。这里我们可以使用分页插件提供的 current-change 事件,在该事件处理函数中我们可以接收到分页插件传递给我们的当前页码。

  1. export default {
  2. // ...
  3. methods: {
  4. handleCurrentChange (val) { // 页码改变的时候,该函数会被调用,并得到当前页码
  5. const res = await this.$http.get('/users', {
  6. params: {
  7. pagenum: val, // 将当前页码传递给服务器接口
  8. pagesize: 2
  9. }
  10. })
  11. const {users, total} = res.data.data
  12. this.tableData = users
  13. this.total = total
  14. }
  15. }
  16. // ...
  17. }

我们已经发现 created 钩子函数中加载用户列表数据和 handleCurrentChange() 函数中的代码已经几乎一样了。所以我们可以封装一个函数用来根据页码加载对应的分页数据,然后分别在 created 钩子和 handleCurrentChange() 函数中进行调用。

  1. export default {
  2. // ...
  3. methods: {
  4. created () {
  5. // 组件初始化默认加载第1页数据
  6. this.loadUsersByPage(1)
  7. },
  8. handleCurrentChange (val) {
  9. // 页码改变的时候获取当前页码数据
  10. this.loadUsersByPage(val)
  11. },
  12. loadUsersByPage (page) { // 页码改变的时候,该函数会被调用,并得到当前页码
  13. const res = await this.$http.get('/users', {
  14. params: {
  15. pagenum: page,
  16. pagesize: 2
  17. }
  18. })
  19. const {users, total} = res.data.data
  20. this.tableData = users
  21. this.total = total
  22. }
  23. }
  24. // ...
  25. }

处理完页码改变加载对应页码数据之后,接下来我们看一下如何实现分页插件的动态切换页码大小改变功能。

我们可以看到分页插件同时为页码大小改变提供了一个自定义事件 size-change。在该事件处理函数中我们可以动态的接收到当前用户选择的每页页码大小。

接下来我们稍微改造一下 loadUsersByPage() 函数,并在 size-change 事件绑定的 handleSizeChange 函数中调用。

  1. export default {
  2. // ...
  3. methods: {
  4. created () {
  5. // 组件初始化默认加载第1页数据
  6. this.loadUsersByPage(1)
  7. },
  8. handleCurrentChange (val) {
  9. // 页码改变的时候获取当前页码数据
  10. this.loadUsersByPage(val)
  11. },
  12. handleSizeChange (val) { // val 就是当前用户选择的每页大小
  13. this.loadUsersByPage(1, val)
  14. },
  15. loadUsersByPage (page, pageSize = 2) { // 加入了一个新的动态参数 pageSize 用来指定每页大小,默认为 2
  16. const res = await this.$http.get('/users', {
  17. params: {
  18. pagenum: page,
  19. pagesize: pageSize
  20. }
  21. })
  22. const {users, total} = res.data.data
  23. this.tableData = users
  24. this.total = total
  25. }
  26. }
  27. // ...
  28. }

让我们来测试一下,我们发现切换每页大小确实已经可以实现我们想要的功能了。

:smile::smile::smile:

:smile::smile::smile:

:smile::smile::smile:

等等,我们发现页码大小改变之后,点击页码,加载的始终是 2 条数据。

这是为啥?

哦,因为我们在 loadUsersByPage() 函数中设定的 pageSize 默认大小就是 2。而无论改变之前还是改变之后,页码的改变都是在调用该函数,页码改变的时候调用该函数并没有指定当前用户选择的最新每页大小

原来是这样的。

好吧,接下来我们可以在 data 中添加一个成员 pageSize 用来存储我们当前的每页大小。

  1. export default {
  2. data () {
  3. return {
  4. searchText: '',
  5. tableData [],
  6. total: 0,
  7. pageSize: 2
  8. }
  9. },
  10. methods: {
  11. created () {
  12. // 组件初始化默认加载第1页数据
  13. this.loadUsersByPage(1)
  14. },
  15. handleCurrentChange (val) {
  16. // 页码改变的时候获取当前页码数据
  17. this.loadUsersByPage(val)
  18. },
  19. handleSizeChange (val) { // val 就是当前用户选择的每页大小
  20. this.pageSize = val // 将改变之后的每页大小实时的存储起来
  21. this.loadUsersByPage(1, val)
  22. },
  23. loadUsersByPage (page) { // 加入了一个新的动态参数 pageSize 用来指定每页大小,默认为 2
  24. const res = await this.$http.get('/users', {
  25. params: {
  26. pagenum: page,
  27. pagesize: this.pageSize // 该数据是动态的,在 data 中默认为 2,当用户点击切换每页大小的时候会修改该数据
  28. }
  29. })
  30. const {users, total} = res.data.data
  31. this.tableData = users
  32. this.total = total
  33. }
  34. }
  35. // ...
  36. }

至此我们终于完成了每页大小改变并动态加载对应的页码大小数据。

但是!

还没有结束:sunglasses::joy:

我们发现每页大小改变之后我们会让页码从第1页开始加载,但是我们的页码高亮状态并没有回归到第1页。

好吧,我们继续。

我们看到分页插件有一个 current-page 属性,我们可以使用该属性告诉分页插件让哪个页码高亮,我们可以分别尝试给定1、2、3 查看页码高亮的样式是否会发生变化。

接下来我们就利用 current-page 属性修正页码高亮问题。

首先在 data 中添加一个成员 currentPage,然后在分页插件模板中同步绑定 currentPage

  1. <template>
  2. ...
  3. <el-pagination
  4. @size-change="handleSizeChange"
  5. @current-change="handleCurrentChange"
  6. :current-page.sync="currentPage"
  7. :page-sizes="[1, 2]"
  8. layout="total, sizes, prev, pager, next, jumper"
  9. :total="totalSize">
  10. </el-pagination>
  11. ...
  12. </template>
  13. <script>
  14. export default {
  15. data () {
  16. return {
  17. // ...
  18. currentPage: 1
  19. // ...
  20. }
  21. }
  22. }
  23. </script>

我们通过调试工具发现,每页分页页码改变,我们的数据成员 currentPage 也会随之同步改变。

最后,让我们在 handleSizeChange() 函数中加载用户列表完成之后,手动将 currentPage 指定为 1。

  1. export default {
  2. // ...
  3. methods: {
  4. // ...
  5. handleSizeChange (val) { // val 就是当前用户选择的每页大小
  6. this.pageSize = val // 将改变之后的每页大小实时的存储起来
  7. this.loadUsersByPage(1, val)
  8. this.currentPage = 1 // 将当前页码设定为 1
  9. }
  10. // ...
  11. }
  12. // ...
  13. }

恭喜,终于使用分页插件完成了我们想要的分页功能。过程虽然麻烦,但是我们的前途一片光明。共勉!!!:smile::smile::smile:

列表搜索

  • 业务分析
  • 接口测试
  • 绑定点击搜索事件处理函数
  • 调用加载用户列表数据方法

修改用户状态

  • 业务分析
  • 接口测试

添加用户

  • 业务分析
  • 接口测试
  • DIalog 对话框
  • 表单布局 + 数据绑定
  • 提交表单添加用户
  • 添加用户成功,重新加载用户列表

删除用户

  • 业务分析
  • 接口测试
  • 注册点击删除事件处理函数
  • 使用 MessageBox 弹框 给出删除操作提示
  • 根据用户 id 执行删除操作
  • 删除成功,重新加载当前分页数据

编辑用户

  • 业务分析
  • 接口测试
  • 注册点击编辑时间处理函数
  • 使用 Dialog 对话框 弹出编辑窗口
  • 将要编辑的用户信息渲染到编辑窗口中
  • 处理编辑操作

角色分配

  • 业务分析
    • 0 为超管,只有超管才可以设置用户的状态
    • -1 为没有角色的用户
  • 接口测试
  • 功能实现

动态加载侧边栏操作菜单

  • 业务分析
  • 接口测试
  • 功能实现