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 实现的权限管理系统。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/123055.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

React中消息订阅与发布(PubSubJS)——两个组件之间通信

结合案例&#xff1a;github搜索案例 结果如下图 1.父容器代码 import React, { Component } from react import Search from ./components/Search import List from ./components/List export default class App extends Component {render() {return (<div className&…

【面试题】如何实现数组去重的?有几种方式?

前端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;前端面试题库 【国庆头像】- 国庆爱国 程序员头像&#xff01;总有一款适合你&#xff01; 1. 方法一&#xff1a;利用两层循环数组的splice方法 通过两层循环对数组…

zabbix监控平台部署

目录 前言 一、zabbix的基本概述 &#xff08;一&#xff09;、zabbix的工作流程 &#xff08;二&#xff09;、zabbix的构成 &#xff08;三&#xff09;、zabbix的监控对象 &#xff08;四&#xff09;、zabbix的常用术语 &#xff08;五&#xff09;、zabbix进程详解…

MySQL数据库的增删改查(进阶)

目录 数据库约束 约束类型 NULL约束 UNIQUE&#xff1a;唯一约束 DEFAULT&#xff1a;默认值约束 PRIMARY KEY&#xff1a;主键约束 FOREIGN KEY&#xff1a;外键约束 表的设计 一对一关系 一对多关系 多对多关系 查询 聚合查询 聚合函数 GROUP BY子句 HAVING …

深入协议栈了解TCP的三次握手、四次挥手、CLOSE-WAIT、TIME-WAIT。

TCP网络编程的代码网上很多&#xff0c;这里就不再赘述&#xff0c;简单用一个图展示一下tcp网络编程的流程&#xff1a; 1、深入connect、listen、accept系统调用&#xff0c;进一步理解TCP的三次握手 这三个函数都是系统调用&#xff0c;我们可以分为请求连接方和被…

项目(智慧教室)第四部分,页面交互功能

一。页面构思 1.标题栏 大标题&#xff1a;智慧教室管理系统 小标题&#xff1a;灯光&#xff0c;报警&#xff0c;风扇&#xff0c;温度&#xff0c;湿度&#xff0c;光照 2.样式设计 背景设置。字体设置&#xff08;字体大小&#xff0c;格式&#xff0c;颜色&#xff09; 3.…

简单使用_matlab生成数据帧

文章目录 生成数据帧参考 生成数据帧 代码如下&#xff0c;代码很简单&#xff0c;有几点要注意&#xff0c; 较高版本的MATLAB中支持0x的写法使用bitand进行位运算使用strcat函数进行字符串拼接时&#xff0c;如果需要插入空格&#xff0c;要使用双引号 cmd_ay(1) 0x33; …

【跟小嘉学 Rust 编程】二十三、Cargo 使用指南

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

【MySQL】CRUD (增删改查) 基础

CRUD&#xff08;增删改查&#xff09;基础 一. CRUD二. 新增 &#xff08;Create&#xff09;1. 单行数据 全列插入2. 多行数据 指定列插入 三. 查询&#xff08;Retrieve&#xff09;1. 全列查询2. 指定列查询3. 查询字段为表达式4. 别名5. 去重&#xff1a;DISTINCT6. 排序…

K210学习笔记——三角函数下的目标追踪

各位正在读文章的朋友们你们好&#xff0c;本人为非专业学生&#xff0c;如有不对的地方&#xff0c;期待您的指正。 目标追踪的意思是&#xff1a;识别到目标物体&#xff0c;通过舵机转动&#xff0c;朝向目标物体. 实验器材&#xff1a;二自由度舵机云台加两个SG90舵机&…

Vue2项目练手——通用后台管理项目第四节

Vue2项目练手——通用后台管理项目 数据的请求mock数据模拟实战文件目录src/api/mock.jssrc/api/mockServeData/home.jsmain.js 首页组件布局可视化图表可视化图表布局Home.vue echarts表Home.vue 数据的请求 mock数据模拟实战 mock官方文档 前端用来模拟后端接口的工具&…

uni-app语音转文字功能demo(同声传译)

目录 首先去微信开发者官网申请一下同声传译的插件 微信公众平台 在文件中开始引用&#xff1a; 首先去微信开发者官网申请一下同声传译的插件 微信公众平台 后续使用的时候可以看详情里面的信息进行使用 在文件中开始引用&#xff1a; 注意&#xff01;&#xff01;在这个…

为XDR扩展威胁检测响应提供响应解决方案

安全层面最本质的问题是检测与响应&#xff0c;而当前的检测与响应&#xff0c;还存在着一些痛点和难点亟需解决&#xff0c;响应运营层面仍存在着一些挑战。 各类安全防护设备每天会产生大量的安全告警&#xff0c;使得安全分析人员绝大部分时间和精力都“消耗”在告警信息中…

Mysql--技术文档--B+树-数据结构的认知

阿丹解读&#xff1a; 之前的文章中写道了有关mysql底层索引&#xff0c;那么在数据量特别大的情况下。mysql采用了B来管理索引。和存储的数据。 Mysql--技术文档--索引-《索引为什么查找数据快&#xff1f;》-超底层详细说明索引_一单成的博客-CSDN博客 B树解读&#xff1a…

flask中的操作数据库的插件Flask-SQLAlchemy

1、ORM 框架 Web 开发中&#xff0c;一个重要的组成部分便是数据库了。Web 程序中最常用的莫过于关系型数据库了&#xff0c;也称 SQL 数据库。另外&#xff0c;文档数据库&#xff08;如 mongodb&#xff09;、键值对数据库&#xff08;如 redis&#xff09;近几年也逐渐在 w…

sql:SQL优化知识点记录(十二)

&#xff08;1&#xff09;读锁案例讲解 加读锁和写锁 查看是否上锁&#xff1a;In_use&#xff1a;变成了1 读写锁对我们数据产生哪些影响&#xff1a; 读锁&#xff1a;是共享锁&#xff0c;其他线程可以查看&#xff1a; 加了读锁&#xff1a;session1不能修改自己&#xf…

使用Vue3和Vite升级你的Vue2+Webpack项目

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

Opencv图像暗通道调优

基于雾天退化模型的去雾算法&#xff0c;Opencv图像暗通道调优&#xff0c;&#xff08;清华版代码&#xff09;对普通相片也有较好的调优效果&#xff0c;相片更通透。 结合代码实际运行效果、算法理论模型、实际代码。我个人理解&#xff0c;实际效果是对图像的三个颜色通道…

React三属性之:refs

作用 refs是为了获取节点,使用场景主要在需要操作dom的时候,比如echarts,就需要真实的dom节点 使用 import React from "react"; class RefsTest extends React.Component{state {value:输入框的值}refPlan React.createRef()logRef ()>{console.log(this.r…

重拾html5

新增的position: sticky; 基于用户的滚动位置来定位&#xff0c;粘性定位的元素是依赖于用户的滚动&#xff0c;在 position:relative 与 position:fixed 定位之间切换。ie15以上的低版本不支持&#xff0c;Safari 需要使用 -webkit- prefix&#xff1b; vertical-align: midd…