用户管理模块

添加接口

在 http/moduls/user.js 中添加用户管理相关接口。

  1. import axios from '../axios'
  2.  
  3. /*
  4. * 用户管理模块
  5. */
  6.  
  7. // 保存
  8. export const save = (params) => {
  9. return axios({
  10. url: '/user/save',
  11. method: 'post',
  12. params
  13. })
  14. }// 删除
  15. export const del = (params) => {
  16. return axios({
  17. url: '/user/delete',
  18. method: 'post',
  19. params
  20. })
  21. }
  22. // 分页查询
  23. export const findPage = (params) => {
  24. return axios({
  25. url: '/user/findPage',
  26. method: 'post',
  27. params
  28. })
  29. }

模拟数据

在 mock/moduls/user.js 中添加用户管理相关mock接口。

  1. /*
  2. * 用户管理模块
  3. */
  4.  
  5. // 保存
  6. export function save() {
  7. return {
  8. url: 'http://localhost:8080/user/save',
  9. type: 'post',
  10. data: {
  11. "code": 200,
  12. "msg": null,
  13. "data": 1
  14. }
  15. }
  16. }// 删除
  17. export function del() {
  18. return {
  19. url: 'http://localhost:8080/user/delete',
  20. type: 'post',
  21. data: {
  22. "code": 200,
  23. "msg": null,
  24. "data": 1
  25. }
  26. }
  27. }
  28. // 分页查询
  29. export function findPage() {
  30. return {
  31. url: 'http://localhost:8080/user/findPage',
  32. type: 'post',
  33. data: findPageData
  34. }
  35. }

提取根路径

为了可以统一控制mock的开启与关闭,把mock的根路径提取出来。

而具体的Mock接口,把根路径移除,因为在生成Mock的时候会自动把根路径加上去。

用户界面

用户管理界面主要是用户信息的表格展示,并提供基础的增删改查功能。

User.vue

  1. <template>
  2. <div class="container" style="width:100%;">
  3. <!--工具栏-->
  4. <div class="toolbar" style="float:left; padding:18px;">
  5. <el-form :inline="true" :model="filters" size="small">
  6. <el-form-item>
  7. <el-input v-model="filters.name" placeholder="用户名"></el-input>
  8. </el-form-item>
  9. <el-form-item>
  10. <el-button type="primary" v-on:click="findPage(null)">查询</el-button>
  11. </el-form-item>
  12. <el-form-item>
  13. <kt-button label="新增" perms="sys:user:add" type="primary" @click="handleAdd" />
  14. </el-form-item>
  15. </el-form>
  16. </div>
  17. <!--表格内容栏-->
  18. <kt-table permsEdit="sys:user:edit" permsDelete="sys:user:delete"
  19. :data="pageResult" :columns="columns"
  20. @findPage="findPage" @handleEdit="handleEdit" @handleDelete="handleDelete">
  21. </kt-table>
  22. <!--新增编辑界面-->
  23. <el-dialog :title="operation?'新增':'编辑'" width="40%" :visible.sync="editDialogVisible" :close-on-click-modal="false">
  24. <el-form :model="dataForm" label-width="80px" :rules="dataFormRules" ref="dataForm">
  25. <el-form-item label="ID" prop="id">
  26. <el-input v-model="dataForm.id" :disabled="true" auto-complete="off"></el-input>
  27. </el-form-item>
  28. <el-form-item label="用户名" prop="name">
  29. <el-input v-model="dataForm.name" auto-complete="off"></el-input>
  30. </el-form-item>
  31. <el-form-item label="密码" prop="password">
  32. <el-input v-model="dataForm.password" type="password" auto-complete="off"></el-input>
  33. </el-form-item>
  34. <el-form-item label="机构" prop="deptName">
  35. <popup-tree-input
  36. :data="deptData"
  37. :props="deptTreeProps"
  38. :prop="dataForm.deptName"
  39. :nodeKey="''+dataForm.deptId"
  40. :currentChangeHandle="deptTreeCurrentChangeHandle">
  41. </popup-tree-input>
  42. </el-form-item>
  43. <el-form-item label="邮箱" prop="email">
  44. <el-input v-model="dataForm.email" auto-complete="off"></el-input>
  45. </el-form-item>
  46. <el-form-item label="手机" prop="mobile">
  47. <el-input v-model="dataForm.mobile" auto-complete="off"></el-input>
  48. </el-form-item>
  49. </el-form>
  50. <div slot="footer" class="dialog-footer">
  51. <el-button @click.native="editDialogVisible = false">取消</el-button>
  52. <el-button type="primary" @click.native="editSubmit" :loading="editLoading">提交</el-button>
  53. </div>
  54. </el-dialog>
  55. </div>
  56. </template>
  57.  
  58. <script>
  59. import PopupTreeInput from "@/components/PopupTreeInput"
  60. import KtTable from "@/views/Core/KtTable"
  61. import KtButton from "@/views/Core/KtButton"
  62. export default {
  63. components:{
  64. PopupTreeInput,
  65. KtTable,
  66. KtButton
  67. },
  68. data() {
  69. return {
  70. filters: {
  71. name: ''
  72. },
  73. columns: [
  74. {prop:"id", label:"ID", minWidth:40, sortable:"false"},
  75. {prop:"name", label:"用户名", minWidth:120, sortable:"true"},
  76. {prop:"deptName", label:"机构", minWidth:120, sortable:"true"},
  77. {prop:"email", label:"邮箱", minWidth:120, sortable:"true"},
  78. {prop:"mobile", label:"手机", minWidth:120, sortable:"true"}
  79. ],
  80. pageRequest: { pageNum: 1, pageSize: 8 },
  81. pageResult: {},
  82.  
  83. operation: false, // true:新增, false:编辑
  84. editDialogVisible: false, // 新增编辑界面是否显示
  85. editLoading: false,
  86. dataFormRules: {
  87. name: [
  88. { required: true, message: '请输入用户名', trigger: 'blur' }
  89. ]
  90. },
  91. // 新增编辑界面数据
  92. dataForm: {
  93. id: 0,
  94. name: '',
  95. password: '123456',
  96. deptId: 1,
  97. deptName: '',
  98. email: 'test@qq.com',
  99. mobile: '13889700023',
  100. status: 1
  101. },
  102. deptData: [],
  103. deptTreeProps: {
  104. label: 'name',
  105. children: 'children'
  106. }
  107. }
  108. },
  109. methods: {
  110. // 获取分页数据
  111. findPage: function (data) {
  112. if(data !== null) {
  113. this.pageRequest = data.pageRequest
  114. }
  115. this.pageRequest.columnFilters = {name: {name:'name', value:this.filters.name}}
  116. this.$api.user.findPage(this.pageRequest).then((res) => {
  117. this.pageResult = res.data
  118. })
  119. },
  120. // 批量删除
  121. handleDelete: function (data) {
  122. this.$api.user.batchDelete(data.params).then(data.callback)
  123. },
  124. // 显示新增界面
  125. handleAdd: function () {
  126. this.editDialogVisible = true
  127. this.operation = true
  128. this.dataForm = {
  129. id: 0,
  130. name: '',
  131. password: '',
  132. deptId: 1,
  133. deptName: '',
  134. email: 'test@qq.com',
  135. mobile: '13889700023',
  136. status: 1
  137. }
  138. },
  139. // 显示编辑界面
  140. handleEdit: function (params) {
  141. this.editDialogVisible = true
  142. this.operation = false
  143. this.dataForm = Object.assign({}, params.row)
  144. },
  145. // 编辑
  146. editSubmit: function () {
  147. this.$refs.dataForm.validate((valid) => {
  148. if (valid) {
  149. this.$confirm('确认提交吗?', '提示', {}).then(() => {
  150. this.editLoading = true
  151. let params = Object.assign({}, this.dataForm)
  152. this.$api.user.save(params).then((res) => {
  153. this.editLoading = false
  154. this.$message({ message: '提交成功', type: 'success' })
  155. this.$refs['dataForm'].resetFields()
  156. this.editDialogVisible = false
  157. this.findPage(null)
  158. })
  159. })
  160. }
  161. })
  162. },
  163. // 获取部门列表
  164. findDeptTree: function () {
  165. this.$api.dept.findDeptTree().then((res) => {
  166. this.deptData = res.data
  167. })
  168. },
  169. // 菜单树选中
  170. deptTreeCurrentChangeHandle (data, node) {
  171. this.dataForm.deptId = data.id
  172. this.dataForm.deptName = data.name
  173. }
  174. },
  175. mounted() {
  176. this.findDeptTree()
  177. }
  178. }
  179. </script>
  180.  
  181. <style scoped>
  182.  
  183. </style>

表格组件封装

为了可以实现表格的代码复用,封装表格组件。

src/views/Core/KtTable.vue

  1. <template>
  2. <div>
  3. <!--表格栏-->
  4. <el-table :data="data.content" stripe highlight-current-row @selection-change="selectionChange"
  5. :v-loading="loading" :max-height="maxHeight" :size="size" :align="align" style="width:100%;" >
  6. <el-table-column type="selection" width="40"></el-table-column>
  7. <el-table-column v-for="column in columns"
  8. :prop="column.prop" :label="column.label" :width="column.width" :min-width="column.minWidth"
  9. :sortable="column.sortable" :fixed="column.fixed" :key="column.prop" :type="column.type">
  10. </el-table-column>
  11. <el-table-column label="操作" width="150" fixed="right">
  12. <template slot-scope="scope">
  13. <kt-button label="编辑" :perms="permsEdit" :size="size" @click="handleEdit(scope.$index, scope.row)" />
  14. <kt-button label="删除" :perms="permsDelete" :size="size" type="danger" @click="handleDelete(scope.$index, scope.row)" />
  15. </template>
  16. </el-table-column>
  17. </el-table>
  18. <!--分页栏-->
  19. <div class="toolbar" style="padding:10px;">
  20. <kt-button label="批量删除" :perms="permsDelete" :size="size" type="danger" @click="handleBatchDelete()"
  21. :disabled="this.selections.length===0" style="float:left;"/>
  22. <el-pagination layout="total, prev, pager, next, jumper" @current-change="refreshPageRequest"
  23. :current-page="pageRequest.pageNum" :page-size="pageRequest.pageSize" :total="data.totalSize" style="float:right;">
  24. </el-pagination>
  25. </div>
  26. </div>
  27. </template>
  28.  
  29. <script>
  30. import KtButton from "@/views/Core/KtButton"
  31. export default {
  32. name: 'KtTable',
  33. components:{
  34. KtButton
  35. },
  36. props: {
  37. columns: Array, // 表格列配置
  38. data: Object, // 表格分页数据
  39. permsEdit: String, // 编辑权限标识
  40. permsDelete: String, // 删除权限标识
  41. size: { // 尺寸样式
  42. type: String,
  43. default: 'mini'
  44. },
  45. align: { // 文本对齐方式
  46. type: String,
  47. default: 'left'
  48. },
  49. maxHeight: { // 表格最大高度
  50. type: Number,
  51. default: 420
  52. }
  53. },
  54. data() {
  55. return {
  56. // 分页信息
  57. pageRequest: {
  58. pageNum: 1,
  59. pageSize: 8
  60. },
  61. loading: false, // 加载标识
  62. selections: [] // 列表选中列
  63. }
  64. },
  65. methods: {
  66. // 分页查询
  67. findPage: function () {
  68. this.$emit('findPage', {pageRequest:this.pageRequest})
  69. },
  70. // 选择切换
  71. selectionChange: function (selections) {
  72. this.selections = selections
  73. },
  74. // 换页刷新
  75. refreshPageRequest: function (pageNum) {
  76. this.pageRequest.pageNum = pageNum
  77. this.findPage()
  78. },
  79. // 编辑
  80. handleEdit: function (index, row) {
  81. this.$emit('handleEdit', {index:index, row:row})
  82. },
  83. // 删除
  84. handleDelete: function (index, row) {
  85. this.delete(row.id)
  86. },
  87. // 批量删除
  88. handleBatchDelete: function () {
  89. let ids = this.selections.map(item => item.id).toString()
  90. this.delete(ids)
  91. },
  92. // 删除操作
  93. delete: function (ids) {
  94. this.$confirm('确认删除选中记录吗?', '提示', {
  95. type: 'warning'
  96. }).then(() => {
  97. let params = []
  98. let idArray = (ids+'').split(',')
  99. for(var i=0; i<idArray.length; i++) {
  100. params.push({'id':idArray[i]})
  101. }
  102. let callback = res => {
  103. this.$message({message: '删除成功', type: 'success'})
  104. this.findPage()
  105. }
  106. this.$emit('handleDelete', {params:params, callback:callback})
  107. }).catch(() => {
  108. })
  109. }
  110. },
  111. mounted() {
  112. this.refreshPageRequest(1)
  113. }
  114. }
  115. </script>
  116.  
  117. <style scoped>
  118.  
  119. </style>

权限按钮封装

为了可以实现对表格数据进行新增、编辑、删除操作按钮的权限控制,封装权限按钮组件。

src/views/Core/KtButton.vue

  1. <template>
  2. <el-button :size="size" :type="type"
  3. :loading="loading" :disabled="!hasPerms(perms)" @click="handleClick">
  4. {{label}}
  5. </el-button>
  6. </template>
  7.  
  8. <script>
  9. import { hasPermission } from '@/permission/index.js'
  10. export default {
  11. name: 'KtButton',
  12. props: {
  13. label: {
  14. type: String,
  15. default: 'Button'
  16. },
  17. size: {
  18. type: String,
  19. default: 'mini'
  20. },
  21. type: {
  22. type: String,
  23. default: null
  24. },
  25. loading: {
  26. type: Boolean,
  27. default: false
  28. },
  29. disabled: {
  30. type: Boolean,
  31. default: false
  32. },
  33. perms: {
  34. type: String,
  35. default: null
  36. }
  37. },
  38. data() {
  39. return {
  40. }
  41. },
  42. methods: {
  43. handleClick: function () {
  44. this.$emit('click', {})
  45. },
  46. hasPerms: function (perms) {
  47. return hasPermission(perms) & !this.disabled
  48. }
  49. },
  50. mounted() {
  51. }
  52. }
  53. </script>
  54.  
  55. <style scoped>
  56.  
  57. </style>

测试效果

测试效果如下,增删改功能,mock不能实际操作数据库,可以结合本教程的后端代码一起测试。

源码下载

后端:https://gitee.com/liuge1988/kitty

前端:https://gitee.com/liuge1988/kitty-ui.git


作者:朝雨忆轻尘
出处:https://www.cnblogs.com/xifengxiaoma/
版权所有,欢迎转载,转载请注明原文作者及出处。

Vue + Element UI 实现权限管理系统 前端篇(十二):用户管理模块的更多相关文章

  1. Vue + Element UI 实现权限管理系统 前端篇(二):Vue + Element 案例

    导入项目 打开 Visual Studio Code,File --> add Folder to Workspace,导入我们的项目. 安装 Element 安装依赖 Element 是国内饿 ...

  2. Vue + Element UI 实现权限管理系统 前端篇(十三):页面权限控制

    权限控制方案 既然是后台权限管理系统,当然少不了权限控制啦,至于权限控制,前端方面当然就是对页面资源的访问和操作控制啦. 前端资源权限主要又分为两个部分,即导航菜单的查看权限和页面增删改操作按钮的操作 ...

  3. Vue + Element UI 实现权限管理系统 前端篇(十一):第三方图标库

    使用第三方图标库 用过Elment的同鞋都知道,Element UI提供的字体图符少之又少,实在是不够用啊,幸好现在有不少丰富的第三方图标库可用,引入也不会很麻烦. Font Awesome Font ...

  4. Vue + Element UI 实现权限管理系统 前端篇(十):动态加载菜单

    动态加载菜单 之前我们的导航树都是写死在页面里的,而实际应用中是需要从后台服务器获取菜单数据之后动态生成的. 我们在这里就用上一篇准备好的数据格式Mock出模拟数据,然后动态生成我们的导航菜单. 接口 ...

  5. Vue + Element UI 实现权限管理系统 前端篇(四):优化登录流程

    完善登录流程 1. 丰富登录界面 1.1 从 Element 指南中选择组件模板丰富登录界面,放置一个登录界面表单,包含账号密码输入框和登录重置按钮. <template> <el- ...

  6. Vue + Element UI 实现权限管理系统 前端篇(十四):菜单功能实现

    菜单功能实现 菜单接口封装 菜单管理是一个对菜单树结构的增删改查操作. 提供一个菜单查询接口,查询整颗菜单树形结构. http/modules/menu.js 添加 findMenuTree 接口. ...

  7. Vue + Element UI 实现权限管理系统 前端篇(七):功能组件封装

    组件封装 为了避免组件代码的臃肿,这里对主要的功能部件进行封装,保证代码的模块化和简洁度. 组件结构 组件封装重构后,试图组件结构如下图所示 代码一览 Home组件被简化,包含导航.头部和主内容三个组 ...

  8. Vue + Element UI 实现权限管理系统 前端篇(五):国际化实现

    国际化支持 1.安装依赖 执行以下命令,安装 i18n 依赖. yarn add vue-i18n $ yarn add vue-i18n yarn add v1.9.4 warning packag ...

  9. Vue + Element UI 实现权限管理系统 前端篇(九):接口格式定义

    接口请求格式定义 前台显示需要后台数据,我们这里先把前后端交互接口定义好,没有后台的时候,也方便用mock模拟. 接口定义遵循几个规范: 1. 接口按功能模块划分. 系统登录:登录相关接口 用户管理: ...

随机推荐

  1. kalman滤波(二)---扩展kalman滤波[EKF]的推导

    一.状态估计的解释 我们知道每个方程都受噪声的影响,这里把位姿x和路标y看成服从某种概率分布的随机变量.因此我们关心的问题就变成了:当我们已知某些运动数据u和观测数据z时,如何确定状态量x,y的分布? ...

  2. 我的java学习之旅--一些基础

    (因为我粗略学过C,C++,Python,了解过他们的一些语法,所以为了使得java的入门更为顺畅,便会忽略一些和C语法相类似的地方,着重点明一些java自己的特色之处.也减轻一下自己写文字的负担.) ...

  3. 20. pt-show-grants

    pt-show-grants -h 192.168.100.101 -P 3306 -u admin -p admin 也可以delete,revoke,flush privileges , 用的不多 ...

  4. 可以用到的XSS跨站语句

    我们常用的测试XSS跨站的语句一般是alert比如: <script>alert(“sex”)</script> <script>alert(/sex/)</ ...

  5. SIFT算法

     备注:源代码还未理解,所以未附上——下周任务 一.SIFT算法 1.算法简介 尺度不变特征转换即SIFT (Scale-invariant feature transform)是一种计算机视觉的算法 ...

  6. POJ 1328 Radar Installation 贪心 A

    POJ 1328 Radar Installation https://vjudge.net/problem/POJ-1328 题目: Assume the coasting is an infini ...

  7. 【转】nc 使用说明

    netcat是网络工具中的瑞士军刀,它能通过TCP和UDP在网络中读写数据.通过与其他工具结合和重定向,你可以在脚本中以多种方式使用它.使用netcat命令所能完成的事情令人惊讶. netcat所做的 ...

  8. async/await的特殊的地方

    一:async如果是用于方法声明里,那么要求这个方法的返回值必须是Task.Task<TResult>.void这三种,而且await出现的地方要求其所在的方法必须是async修饰的方法: ...

  9. mysql data type <----> java data type (数值)

    https://dev.mysql.com/doc/refman/5.7/en/storage-requirements.html +----------------------------+---- ...

  10. 【repost】H5的新特性及部分API详解

    h5新特性总览 移除的元素 纯表现的元素: basefont.big.center.font等 对可用性产生负面影响的元素: frame.frameset.noframes 新增的API 语义: 能够 ...