当前位置: 首页 > news >正文

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 实现权限管理系统 前端篇&#xff08;十二&#xff09;&#xff1a;用户管理模块 用户管理模块 添加接口 在 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.数组异或操作

给你两个整数&#xff0c;n 和 start 。 数组 nums 定义为&#xff1a;nums[i] start 2*i&#xff08;下标从 0 开始&#xff09;且 n nums.length 。 请返回 nums 中所有元素按位异或&#xff08;XOR&#xff09;后得到的结果。 示例 1&#xff1a; 输入&#xff1a;n 5, …...

【Java】Java核心API概述

Java核心API是Java编程语言的基础&#xff0c;包含了Java应用程序中常用的类和接口。本文将介绍Java核心API中的一些重要部分&#xff0c;包括输入输出流、异常处理、集合框架、多线程和网络编程等。 1、输入输出流 Java的输入输出流API是Java IO&#xff0c;它提供了处理输入…...

微信小程序检查版本更新

新建文件 version-util.js // 小程序启动时检查版本 class VersionUtil {/*** 检查更新*/checkUpdate(){const updateManager wx.getUpdateManager();updateManager.onCheckForUpdate((hasUpdate)>{if(hasUpdate){updateManager.onUpdateReady(()>{wx.showModal({title…...

Linux查看是虚拟机还是物理机

第一种方式&#xff1a;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. 二叉搜索树的概念和介绍 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&…...

通过linux定时任务删除es日志索引

能过linux定时任务删除es日志索引 项目用上了elk&#xff0c;产生的日志索引要定时&#xff0c;其一个方法&#xff0c;通过linux定时任务&#xff0c;调用es接口删除索引。 #!/bin/bash #删除ELK30天前的日志 #计算索引名称包含的日期&#xff0c;比如这里是 %Y.%m.%d (2023…...

【跟小嘉学 Rust 编程】二十二、常用 API

系列文章目录 【跟小嘉学 Rust 编程】一、Rust 编程基础 【跟小嘉学 Rust 编程】二、Rust 包管理工具使用 【跟小嘉学 Rust 编程】三、Rust 的基本程序概念 【跟小嘉学 Rust 编程】四、理解 Rust 的所有权概念 【跟小嘉学 Rust 编程】五、使用结构体关联结构化数据 【跟小嘉学…...

【ES6】Class中this指向

先上代码&#xff1a; 正常运行的代码&#xff1a; class Logger{printName(name kexuexiong){this.print(hello ${name});}print(text){console.log(text);} }const logger new Logger(); logger.printName("kexueixong xiong");输出&#xff1a; 单独调用函数p…...

Python 编程竟然如此幽默!揭秘程序员们的搞笑日常,快来看看吧!

食用原文效果更佳&#xff0c;原文链接 Python 编程竟然如此幽默&#xff01;揭秘程序员们的搞笑日常&#xff0c;快来看看吧&#xff01; 在 Python 编程的世界里&#xff0c;充满了智慧与创造力。 当然&#xff0c;也少不了轻松幽默的段子&#xff0c;这些段子让程序员们在…...

Linux c++开发-03-使用CMake组织工程

一、简单文件的编译 有如下的目录结构&#xff1a; 其中 helloworld.cpp如下&#xff1a; #include <iostream> using namespace std; int main() {printf("hello world my name is Ty!");return 0; }CMakeLists.txt如下&#xff1a; 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 异常的概念 程序员在开发过程中&#xff0c;想要将代码写得…...

软件测试/测试开发丨Selenium Web自动化测试 高级控件交互方法

点此获取更多相关资料 本文为霍格沃兹测试开发学社学员学习笔记分享 原文链接&#xff1a;https://ceshiren.com/t/topic/27045 一、使用场景 使用场景对应事件复制粘贴键盘事件拖动元素到某个位置鼠标事件鼠标悬停鼠标事件滚动到某个元素滚动事件使用触控笔点击触控笔事件&am…...

深入Go语言:进阶指南

深入Go语言&#xff1a;进阶指南 欢迎来到深入Go语言的进阶指南。如果你已经熟悉Go语言的基础知识&#xff0c;想要更深入地探索这门语言的高级特性和技巧&#xff0c;那么本篇博客将为你提供有关Go语言的更多深入内容。 Go语言的并发编程 Go语言以其强大的并发支持而闻名。…...

FOXBORO FBM232 P0926GW 自动化控制模块

Foxboro FBM232 P0926GW 是 Foxboro&#xff08;福克斯博罗&#xff09;自动化控制系统的一部分&#xff0c;通常用于监测和控制工业过程。以下是关于这种类型的自动化控制模块可能具有的一些常见功能&#xff1a; 数字输入通道&#xff1a; FBM232 P0926GW 控制模块通常具有多…...

【C# Programming】编程入门:方法和参数

一、方法 1、方法的定义 由一系列以执行特定的操作或计算结果语句组成。方法总是和类关联&#xff0c;类型将相关的方法分为一组。 方法名称 形参和实参(parameter & argument)返回值 2、命名空间 一种分类机制&#xff0c;用于组合功能相关的所有类型。命名空间是分级…...

【报错】 Cannot create property ‘showColumn‘ on number ‘-1‘

1、报错原因&#xff1a; 代码如下&#xff1a; 报错是因为&#xff1a;this.findObject(this.option.column, "thirdId")是一个number &#xff0c;没有.showColumn属性 2、修改代码 将其变成object属性就行了...

C++容器string的运用和注意

介绍 首先&#xff0c;先说明&#xff0c;string在C的string头文件中定义&#xff0c;而在C语言中的字符串就是字符数组&#xff0c;在C中&#xff0c;string容器相当于C语言中的字符数组&#xff0c;string比C语言中的字符数组更为好用&#xff0c;如&#xff1a;C中cin/cout可…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

JS手写代码篇----使用Promise封装AJAX请求

15、使用Promise封装AJAX请求 promise就有reject和resolve了&#xff0c;就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型&#xff08;Primitive&#xff09; 和 对象类型&#xff08;Object&#xff09; 两大类&#xff0c;共 8 种&#xff08;ES11&#xff09;&#xff1a; 一、原始类型&#xff08;7种&#xff09; 1. undefined 定…...

tauri项目,如何在rust端读取电脑环境变量

如果想在前端通过调用来获取环境变量的值&#xff0c;可以通过标准的依赖&#xff1a; std::env::var(name).ok() 想在前端通过调用来获取&#xff0c;可以写一个command函数&#xff1a; #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...