Vue + Element UI 前端篇(十二):用户管理模块
Vue + Element UI 实现权限管理系统 前端篇(十二):用户管理模块
用户管理模块
添加接口
在 http/moduls/user.js 中添加用户管理相关接口。
![]()
import axios from '../axios'/* * 用户管理模块*/// 保存
export const save = (params) => {return axios({url: '/user/save',method: 'post',params})
}// 删除
export const del = (params) => {return axios({url: '/user/delete',method: 'post',params})
}
// 分页查询
export const findPage = (params) => {return axios({url: '/user/findPage',method: 'post',params})
}
![]()
模拟数据
在 mock/moduls/user.js 中添加用户管理相关mock接口。
![]()
/* * 用户管理模块*/// 保存
export function save() {return {url: 'http://localhost:8080/user/save',type: 'post',data: {"code": 200,"msg": null,"data": 1}}
}// 删除
export function del() {return {url: 'http://localhost:8080/user/delete',type: 'post',data: {"code": 200,"msg": null,"data": 1}}
}
// 分页查询
export function findPage() {return {url: 'http://localhost:8080/user/findPage',type: 'post',data: findPageData}
}
![]()
提取根路径
为了可以统一控制mock的开启与关闭,把mock的根路径提取出来。

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

用户界面
用户管理界面主要是用户信息的表格展示,并提供基础的增删改查功能。
User.vue
![]()
<template><div class="container" style="width:100%;"><!--工具栏--><div class="toolbar" style="float:left; padding:18px;"><el-form :inline="true" :model="filters" size="small"><el-form-item><el-input v-model="filters.name" placeholder="用户名"></el-input></el-form-item><el-form-item><el-button type="primary" v-on:click="findPage(null)">查询</el-button></el-form-item><el-form-item><kt-button label="新增" perms="sys:user:add" type="primary" @click="handleAdd" /></el-form-item></el-form></div><!--表格内容栏--><kt-table permsEdit="sys:user:edit" permsDelete="sys:user:delete":data="pageResult" :columns="columns" @findPage="findPage" @handleEdit="handleEdit" @handleDelete="handleDelete"></kt-table><!--新增编辑界面--><el-dialog :title="operation?'新增':'编辑'" width="40%" :visible.sync="editDialogVisible" :close-on-click-modal="false"><el-form :model="dataForm" label-width="80px" :rules="dataFormRules" ref="dataForm"><el-form-item label="ID" prop="id"><el-input v-model="dataForm.id" :disabled="true" auto-complete="off"></el-input></el-form-item><el-form-item label="用户名" prop="name"><el-input v-model="dataForm.name" auto-complete="off"></el-input></el-form-item><el-form-item label="密码" prop="password"><el-input v-model="dataForm.password" type="password" auto-complete="off"></el-input></el-form-item><el-form-item label="机构" prop="deptName"><popup-tree-input :data="deptData" :props="deptTreeProps" :prop="dataForm.deptName" :nodeKey="''+dataForm.deptId" :currentChangeHandle="deptTreeCurrentChangeHandle"></popup-tree-input></el-form-item><el-form-item label="邮箱" prop="email"><el-input v-model="dataForm.email" auto-complete="off"></el-input></el-form-item><el-form-item label="手机" prop="mobile"><el-input v-model="dataForm.mobile" auto-complete="off"></el-input></el-form-item></el-form><div slot="footer" class="dialog-footer"><el-button @click.native="editDialogVisible = false">取消</el-button><el-button type="primary" @click.native="editSubmit" :loading="editLoading">提交</el-button></div></el-dialog></div>
</template><script>
import PopupTreeInput from "@/components/PopupTreeInput"
import KtTable from "@/views/Core/KtTable"
import KtButton from "@/views/Core/KtButton"
export default {components:{PopupTreeInput,KtTable,KtButton},data() {return {filters: {name: ''},columns: [{prop:"id", label:"ID", minWidth:40, sortable:"false"},{prop:"name", label:"用户名", minWidth:120, sortable:"true"},{prop:"deptName", label:"机构", minWidth:120, sortable:"true"},{prop:"email", label:"邮箱", minWidth:120, sortable:"true"},{prop:"mobile", label:"手机", minWidth:120, sortable:"true"}],pageRequest: { pageNum: 1, pageSize: 8 },pageResult: {},operation: false, // true:新增, false:编辑editDialogVisible: false, // 新增编辑界面是否显示editLoading: false,dataFormRules: {name: [{ required: true, message: '请输入用户名', trigger: 'blur' }]},// 新增编辑界面数据dataForm: {id: 0,name: '',password: '123456',deptId: 1,deptName: '',email: 'test@qq.com',mobile: '13889700023',status: 1},deptData: [],deptTreeProps: {label: 'name',children: 'children'}}},methods: {// 获取分页数据findPage: function (data) {if(data !== null) {this.pageRequest = data.pageRequest}this.pageRequest.columnFilters = {name: {name:'name', value:this.filters.name}}this.$api.user.findPage(this.pageRequest).then((res) => {this.pageResult = res.data})},// 批量删除handleDelete: function (data) {this.$api.user.batchDelete(data.params).then(data.callback)},// 显示新增界面handleAdd: function () {this.editDialogVisible = truethis.operation = truethis.dataForm = {id: 0,name: '',password: '',deptId: 1,deptName: '',email: 'test@qq.com',mobile: '13889700023',status: 1}},// 显示编辑界面handleEdit: function (params) {this.editDialogVisible = truethis.operation = falsethis.dataForm = Object.assign({}, params.row)},// 编辑editSubmit: function () {this.$refs.dataForm.validate((valid) => {if (valid) {this.$confirm('确认提交吗?', '提示', {}).then(() => {this.editLoading = truelet params = Object.assign({}, this.dataForm)this.$api.user.save(params).then((res) => {this.editLoading = falsethis.$message({ message: '提交成功', type: 'success' })this.$refs['dataForm'].resetFields()this.editDialogVisible = falsethis.findPage(null)})})}})},// 获取部门列表findDeptTree: function () {this.$api.dept.findDeptTree().then((res) => {this.deptData = res.data})},// 菜单树选中deptTreeCurrentChangeHandle (data, node) {this.dataForm.deptId = data.idthis.dataForm.deptName = data.name}},mounted() {this.findDeptTree()}
}
</script><style scoped></style>
![]()
表格组件封装
为了可以实现表格的代码复用,封装表格组件。
src/views/Core/KtTable.vue

<template><div><!--表格栏--><el-table :data="data.content" stripe highlight-current-row @selection-change="selectionChange" :v-loading="loading" :max-height="maxHeight" :size="size" :align="align" style="width:100%;" ><el-table-column type="selection" width="40"></el-table-column><el-table-column v-for="column in columns" :prop="column.prop" :label="column.label" :width="column.width" :min-width="column.minWidth" :sortable="column.sortable" :fixed="column.fixed" :key="column.prop" :type="column.type"></el-table-column><el-table-column label="操作" width="150" fixed="right"><template slot-scope="scope"><kt-button label="编辑" :perms="permsEdit" :size="size" @click="handleEdit(scope.$index, scope.row)" /><kt-button label="删除" :perms="permsDelete" :size="size" type="danger" @click="handleDelete(scope.$index, scope.row)" /></template></el-table-column></el-table><!--分页栏--><div class="toolbar" style="padding:10px;"><kt-button label="批量删除" :perms="permsDelete" :size="size" type="danger" @click="handleBatchDelete()" :disabled="this.selections.length===0" style="float:left;"/><el-pagination layout="total, prev, pager, next, jumper" @current-change="refreshPageRequest" :current-page="pageRequest.pageNum" :page-size="pageRequest.pageSize" :total="data.totalSize" style="float:right;"></el-pagination></div></div>
</template><script>
import KtButton from "@/views/Core/KtButton"
export default {name: 'KtTable',components:{KtButton},props: {columns: Array, // 表格列配置data: Object, // 表格分页数据permsEdit: String, // 编辑权限标识permsDelete: String, // 删除权限标识size: { // 尺寸样式type: String,default: 'mini'},align: { // 文本对齐方式type: String,default: 'left'},maxHeight: { // 表格最大高度type: Number,default: 420}},data() {return {// 分页信息pageRequest: {pageNum: 1,pageSize: 8},loading: false, // 加载标识selections: [] // 列表选中列}},methods: {// 分页查询findPage: function () {this.$emit('findPage', {pageRequest:this.pageRequest})},// 选择切换selectionChange: function (selections) {this.selections = selections},// 换页刷新refreshPageRequest: function (pageNum) {this.pageRequest.pageNum = pageNumthis.findPage()},// 编辑handleEdit: function (index, row) {this.$emit('handleEdit', {index:index, row:row})},// 删除handleDelete: function (index, row) {this.delete(row.id)},// 批量删除handleBatchDelete: function () {let ids = this.selections.map(item => item.id).toString()this.delete(ids)},// 删除操作delete: function (ids) {this.$confirm('确认删除选中记录吗?', '提示', {type: 'warning'}).then(() => {let params = []let idArray = (ids+'').split(',')for(var i=0; i<idArray.length; i++) {params.push({'id':idArray[i]})}let callback = res => {this.$message({message: '删除成功', type: 'success'})this.findPage()}this.$emit('handleDelete', {params:params, callback:callback})}).catch(() => {})}},mounted() {this.refreshPageRequest(1)}
}
</script><style scoped></style>
![]()
权限按钮封装
为了可以实现对表格数据进行新增、编辑、删除操作按钮的权限控制,封装权限按钮组件。
src/views/Core/KtButton.vue
![]()
<template><el-button :size="size" :type="type" :loading="loading" :disabled="!hasPerms(perms)" @click="handleClick">{{label}}</el-button>
</template><script>
import { hasPermission } from '@/permission/index.js'
export default {name: 'KtButton',props: {label: {type: String,default: 'Button'},size: {type: String,default: 'mini'},type: {type: String,default: null},loading: {type: Boolean,default: false},disabled: {type: Boolean,default: false},perms: {type: String,default: null}},data() {return {}},methods: {handleClick: function () {this.$emit('click', {})}, hasPerms: function (perms) {return hasPermission(perms) & !this.disabled}},mounted() {}
}
</script><style scoped></style>
![]()
测试效果
测试效果如下,增删改功能,mock不能实际操作数据库,可以结合本教程的后端代码一起测试。

源码下载
后端:kitty: 基于Spring Boot、Spring Cloud、Vue.js 、Element UI实现,采用前后端分离架构的权限管理系统,JAVA快速开发平台。
前端:kitty-ui: Kitty 前端,基于 Vue + Element 实现的权限管理系统。
相关文章:
Vue + Element UI 前端篇(十二):用户管理模块
Vue Element UI 实现权限管理系统 前端篇(十二):用户管理模块 用户管理模块 添加接口 在 http/moduls/user.js 中添加用户管理相关接口。 import axios from ../axios/* * 用户管理模块*/// 保存 export const save (params) > {ret…...
C# 设计保存文件
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System...
Leetcode 1486.数组异或操作
给你两个整数,n 和 start 。 数组 nums 定义为:nums[i] start 2*i(下标从 0 开始)且 n nums.length 。 请返回 nums 中所有元素按位异或(XOR)后得到的结果。 示例 1: 输入:n 5, …...
【Java】Java核心API概述
Java核心API是Java编程语言的基础,包含了Java应用程序中常用的类和接口。本文将介绍Java核心API中的一些重要部分,包括输入输出流、异常处理、集合框架、多线程和网络编程等。 1、输入输出流 Java的输入输出流API是Java IO,它提供了处理输入…...
微信小程序检查版本更新
新建文件 version-util.js // 小程序启动时检查版本 class VersionUtil {/*** 检查更新*/checkUpdate(){const updateManager wx.getUpdateManager();updateManager.onCheckForUpdate((hasUpdate)>{if(hasUpdate){updateManager.onUpdateReady(()>{wx.showModal({title…...
Linux查看是虚拟机还是物理机
第一种方式:dmesg命令 [roottest ~]# dmesg | grep -i hypervisor [ 0.000000] Hypervisor detected: VMware [ 0.001000] TSC freq read from hypervisor : 2903.999 MHz [ 6.311621] [drm] Max dedicated hypervisor surface memory is 0 kiB第二种方式…...
【数据结构】二叉搜索树——二叉搜索树的概念和介绍、二叉搜索树的简单实现、二叉搜索树的增删查改
文章目录 二叉搜索树1. 二叉搜索树的概念和介绍2. 二叉搜索树的简单实现2.1二叉搜索树的插入2.2二叉搜索树的查找2.3二叉搜索树的遍历2.4二叉搜索树的删除2.5完整代码和测试 二叉搜索树 1. 二叉搜索树的概念和介绍 二叉搜索树又称二叉排序树,它或者是一棵空树&…...
通过linux定时任务删除es日志索引
能过linux定时任务删除es日志索引 项目用上了elk,产生的日志索引要定时,其一个方法,通过linux定时任务,调用es接口删除索引。 #!/bin/bash #删除ELK30天前的日志 #计算索引名称包含的日期,比如这里是 %Y.%m.%d (2023…...
【跟小嘉学 Rust 编程】二十二、常用 API
系列文章目录 【跟小嘉学 Rust 编程】一、Rust 编程基础 【跟小嘉学 Rust 编程】二、Rust 包管理工具使用 【跟小嘉学 Rust 编程】三、Rust 的基本程序概念 【跟小嘉学 Rust 编程】四、理解 Rust 的所有权概念 【跟小嘉学 Rust 编程】五、使用结构体关联结构化数据 【跟小嘉学…...
【ES6】Class中this指向
先上代码: 正常运行的代码: class Logger{printName(name kexuexiong){this.print(hello ${name});}print(text){console.log(text);} }const logger new Logger(); logger.printName("kexueixong xiong");输出: 单独调用函数p…...
Python 编程竟然如此幽默!揭秘程序员们的搞笑日常,快来看看吧!
食用原文效果更佳,原文链接 Python 编程竟然如此幽默!揭秘程序员们的搞笑日常,快来看看吧! 在 Python 编程的世界里,充满了智慧与创造力。 当然,也少不了轻松幽默的段子,这些段子让程序员们在…...
Linux c++开发-03-使用CMake组织工程
一、简单文件的编译 有如下的目录结构: 其中 helloworld.cpp如下: #include <iostream> using namespace std; int main() {printf("hello world my name is Ty!");return 0; }CMakeLists.txt如下: cmake_minimum_requir…...
【C++】函数重载 ④ ( 函数指针定义的三种方式 | 直接定义函数指针 | 通过 函数类型 定义 函数指针 | 通过 函数指针类型 定义 函数指针 )
文章目录 一、函数指针定义方法1、直接定义函数指针2、通过 函数类型 定义 函数指针3、通过 函数指针类型 定义 函数指针4、代码示例 - 不同方式定义函数指针 博客总结 : 重载函数 : 使用 相同 的 函数名 , 定义 不同 的 函数参数列表 ;判定标准 : 只有 函数参数 的 个数 / 类…...
异常-java
目录 一、异常的概念和体系结构 1.1 异常的概念 1.2 异常的体系结构 1.3 异常的分类 二、异常的处理 2.1 防御式编程 2.2 异常抛出 2.3 异常捕获 2.4 异常处理流程 三、自定义异常类 一、异常的概念和体系结构 1.1 异常的概念 程序员在开发过程中,想要将代码写得…...
软件测试/测试开发丨Selenium Web自动化测试 高级控件交互方法
点此获取更多相关资料 本文为霍格沃兹测试开发学社学员学习笔记分享 原文链接:https://ceshiren.com/t/topic/27045 一、使用场景 使用场景对应事件复制粘贴键盘事件拖动元素到某个位置鼠标事件鼠标悬停鼠标事件滚动到某个元素滚动事件使用触控笔点击触控笔事件&am…...
深入Go语言:进阶指南
深入Go语言:进阶指南 欢迎来到深入Go语言的进阶指南。如果你已经熟悉Go语言的基础知识,想要更深入地探索这门语言的高级特性和技巧,那么本篇博客将为你提供有关Go语言的更多深入内容。 Go语言的并发编程 Go语言以其强大的并发支持而闻名。…...
FOXBORO FBM232 P0926GW 自动化控制模块
Foxboro FBM232 P0926GW 是 Foxboro(福克斯博罗)自动化控制系统的一部分,通常用于监测和控制工业过程。以下是关于这种类型的自动化控制模块可能具有的一些常见功能: 数字输入通道: FBM232 P0926GW 控制模块通常具有多…...
【C# Programming】编程入门:方法和参数
一、方法 1、方法的定义 由一系列以执行特定的操作或计算结果语句组成。方法总是和类关联,类型将相关的方法分为一组。 方法名称 形参和实参(parameter & argument)返回值 2、命名空间 一种分类机制,用于组合功能相关的所有类型。命名空间是分级…...
【报错】 Cannot create property ‘showColumn‘ on number ‘-1‘
1、报错原因: 代码如下: 报错是因为:this.findObject(this.option.column, "thirdId")是一个number ,没有.showColumn属性 2、修改代码 将其变成object属性就行了...
C++容器string的运用和注意
介绍 首先,先说明,string在C的string头文件中定义,而在C语言中的字符串就是字符数组,在C中,string容器相当于C语言中的字符数组,string比C语言中的字符数组更为好用,如:C中cin/cout可…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...
打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用
一、方案背景 在现代生产与生活场景中,如工厂高危作业区、医院手术室、公共场景等,人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式,存在效率低、覆盖面不足、判断主观性强等问题,难以满足对人员打手机行为精…...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...
协议转换利器,profinet转ethercat网关的两大派系,各有千秋
随着工业以太网的发展,其高效、便捷、协议开放、易于冗余等诸多优点,被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口,具有实时性、开放性,使用TCP/IP和IT标准,符合基于工业以太网的…...
