学习目标:SpringBoot2+Vue3+MP图文摘录(一)
提示:SpringBoot2与Vue3的小练习图文摘录
高能提示:
- 三篇文章带你更熟悉掌握前后端分离的基本实现
一、vue的基本环境搭建
新建项目vue3-springboot
- 1、安装axios、element-plus等必须的依赖即可
- 2、其他的插件应用
修改App.vue
<template>
<div>
<router-view/>
</div>
</template>
<script>
export default{
name:"App"
}
</script>
<style>
</style>
src/main.js基本的引入
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
// 引入icon的js文件
import elementIcon from './plugins/icon'
import '@/assets/css/global.css'
createApp(App).use(store).use(router).use(ElementPlus,{locale:zhCn}).use(elementIcon).mount('#app')
全局的css样式【新建css文件夹并新建global.css文件】
*{
margin: 0px;
padding: 0px;
box-sizing: border-box;
}
引入element-plus中的图标(在src下新建plugins文件夹并新建icon.js文件):
// 如果您正在使用CDN引入,请删除下面一行。
import * as components from '@element-plus/icons-vue'
export default{
install:(app)=>{
for (const key in components) {
const componentConfig=components[key];
app.component(componentConfig.name,componentConfig);
}
}
}
在utils目录下存放封装的请求js文件:
import axios from "axios";
//声明一个后端的父路径
const server="http://localhost:8888/";
/*
async 异步处理
await 等待处理完成
*/
async function getData(url,param){
var ret="";
await axios.get(server+url,{params:param}).then(function(res){
ret=res.data;
});
return ret;
}
/*
post带有请求体传输数据【json格式的数据】
async 异步处理
await 等待处理完成
*/
async function postData(url,param){
var ret="";
//设置axios的参数
var options={
url:server+url,
method:"post",
data:param
}
await axios(options).then(function(res){
ret=res.data;
});
return ret;
}
/*
post带有表单传输数据【url?name=value&name2=value2格式】
async 异步处理
await 等待处理完成
*/
async function postDataForm(url,param){
var ret="";
//设置axios的参数
var options={
url:server+url,
method:"post",
data:param,
headers:{'Content-Type':'application/x-www-form-urlencoded'}
}
await axios(options).then(function(res){
ret=res.data;
});
return ret;
}
/*
post带有文件域传输数据【file格式】
async 异步处理
await 等待处理完成
*/
async function uploadFile(url,param){
var ret="";
//设置axios的参数
var options={
url:server+url,
method:"post",
data:param,
headers:{
'Content-Type':'multipart/form-data'
}
}
await axios(options).then(function(res){
ret=res.data;
});
return ret;
}
//如果需要在其他引入当前js的vue中使用需要导出
// export 导出变量、函数
export {getData,postData,postDataForm,uploadFile}
在router目录下的index.js中进行引入首页:
import { createRouter, createWebHashHistory } from 'vue-router'
import Layout from '../layout/Layout.vue'
const routes = [
{
path: '/',
name: 'layout',
component: Layout
},
{
path: '/about',
name: 'about',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
}
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
export default router
在src下新建layout文件夹并新建Layout.vue文件:
<template>
<div>
<!-- 头部 -->
<Header></Header>
<div style="display:flex;">
<!-- 侧边导航啦 -->
<Aside></Aside>
<!-- 内容区域 -->
<router-view style="flex:1;"></router-view>
</div>
</div>
</template>
<script>
import Header from '@/components/Header.vue'
import Aside from '@/components/Aside.vue'
export default {
name:"Layout",
components:{
Header,
Aside
}
}
</script>
<style>
</style>
在components文件夹下新建Header.vue和Aside.vue文件:
<template>
<div
style="height:50px;line-height:50px;
border-bottom:solid 1px darkcyan;display: flex;">
<div style="width: 200px;padding-left:30px;font-weight:bold;color:deepskyblue;">
XX后台管理系统
</div>
<div style="flex:1;"></div>
<div style="width:100px;padding-right:30px;padding-top:20px;">
<el-dropdown>
<span class="el-dropdown-link">
管理员
<el-icon class="el-icon--right">
<arrow-down />
</el-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>个人信息</el-dropdown-item>
<el-dropdown-item>修改密码</el-dropdown-item>
<el-dropdown-item>注销登录</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
</template>
<script>
export default {
name:"Header"
}
</script>
<style>
</style>
<template>
<div>
<el-col :span="12">
<el-menu style="width:220px;min-height:100vh;"
default-active="2"
router
class="el-menu-vertical-demo"
@open="handleOpen"
@close="handleClose"
>
<el-sub-menu index="1">
<template #title>
<el-icon><location /></el-icon>
<span>用户管理</span>
</template>
<el-menu-item index="/home">用户列表</el-menu-item>
<el-menu-item index="1-2">禁用用户</el-menu-item>
</el-sub-menu>
<el-sub-menu index="2">
<template #title>
<el-icon><location /></el-icon>
<span>书籍管理</span>
</template>
<el-menu-item index="/book">书籍列表</el-menu-item>
<el-menu-item index="2-2">下架书籍</el-menu-item>
</el-sub-menu>
<el-menu-item index="3">
<el-icon><document /></el-icon>
<span>公告管理</span>
</el-menu-item>
<el-menu-item index="4">
<el-icon><document /></el-icon>
<span>订单管理</span>
</el-menu-item>
<el-menu-item index="5">
<el-icon><setting /></el-icon>
<span>个人信息</span>
</el-menu-item>
</el-menu>
</el-col>
</div>
</template>
<script>
export default {
name:"Aside"
}
</script>
<style>
</style>
修改router目录下的index.js文件内容【路由处理】:
在view目录下新建UserHome.vue文件:
<template>
<div>
<h1>用户列表页面</h1>
<!-- 表格数据渲染用户列表信息 -->
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="id" label="用户ID" width="180" />
<el-table-column prop="username" label="用户名" width="180" />
<el-table-column prop="nickname" label="昵称" />
<el-table-column prop="sex" label="性别" />
<el-table-column prop="address" label="地址" />
<el-table-column fixed="right" label="操 作" width="300">
<el-button type="success" size="small">
查看
</el-button>
<el-button type="danger" size="small">
删除
</el-button>
<el-button type="primary" size="small">
编辑
</el-button>
</el-table-column>
</el-table>
</div>
</template>
<script>
import {getData} from "../utils/remote";
export default {
name:"UserHome",
data(){
return{
tableData:[]
}
},
created(){
this.load();
},
methods:{
load(){
getData("users/loadAll").then(res=>{
console.log(res);
this.tableData=res.data;
});
}
}
}
</script>
<style>
</style>
预览基本的效果:
二、搭建基础的后台进行请求处理
基于maven构建一个springboot2+mp的后台应用:
pom.xml文件的基础依赖坐标:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xuguoguo</groupId>
<artifactId>springboot2-vue3-mp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot2-vue3-mp</name>
<description>springboot2-vue3-mp</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.7.6</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.9</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<mainClass>com.xuguoguo.Springboot2Vue3MpApplication</mainClass>
<skip>true</skip>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
创建用户信息表:
CREATE TABLE `t_users` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户的主键编号',
`username` varchar(255) DEFAULT NULL COMMENT '用户名',
`password` varchar(255) DEFAULT NULL COMMENT '密码',
`nickname` varchar(255) DEFAULT NULL COMMENT '昵称',
`sex` varchar(255) DEFAULT NULL COMMENT '性别',
`address` varchar(255) DEFAULT NULL COMMENT '地址',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
通过MybatisX插件生成对应的三层代码:
基础的配置文件和类对象
1、配置文件application.yml
server:
port: 8888
tomcat:
uri-encoding: UTF-8
threads:
max: 200
数据源配置
spring:
# 数据源配置
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/2103cloud
username: root
password: 123
type: com.alibaba.druid.pool.DruidDataSource
main:
banner-mode: off # 关闭springboot启动图标
# 开启日志
mybatis-plus:
global-config:
db-config:
id-type: auto #默认值
logic-delete-field: deleted # 逻辑删除的字段
logic-not-delete-value: 0 # 逻辑删除的字面值:未删除为0
logic-delete-value: 1 # 逻辑删除的字面值:未删除为1
banner: off # 关闭mybatisPlus的启动图标
# table-prefix: tb_ #统一配置数据标的前缀
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true
cache-enabled: false # 默认的全局的缓存为true
# config-location: classpath:mybatis-config.xml
type-aliases-package: com.xuguoguo.entity
mapper-locations: classpath*:mappers/*.xml
# 查看sql语句的日志
# 日志记录
logging:
level:
com.xuguoguo: debug
org.springframework: info
通用的返回的结果类对象:
package com.xuguoguo.commons;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* 统一返回对象
*/
@Data
@NoArgsConstructor
public class Result<T> implements Serializable {
/**
* 通信数据
*/
private T data;
/**
* 通信状态
*/
private boolean flag = true;
/**
* 通信描述
*/
private String msg = "操作成功";
/**
* 通过静态方法获取实例
*/
public static <T> Result<T> of(T data) {
return new Result<>(data);
}
public static <T> Result<T> of(T data, boolean flag) {
return new Result<>(data, flag);
}
public static <T> Result<T> of(T data, boolean flag, String msg) {
return new Result<>(data, flag, msg);
}
private Result(T data) {
this.data = data;
}
private Result(T data, boolean flag) {
this.data = data;
this.flag = flag;
}
private Result(T data, boolean flag, String msg) {
this.data = data;
this.flag = flag;
this.msg = msg;
}
}
跨域的配置类:
package com.xuguoguo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
@Package: com.xuguoguo.config
@ClassName: CorsConfig
@Author: XuGuoGuo
@CreateTime: 2023/12/5-16:09
@Description:
*/
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
//设置允许跨域的路径
registry.addMapping("/**")
//设置允许跨域请求的域名
.allowedOriginPatterns("*")
//是否允许cookie
.allowCredentials(true)
//设置允许请求的方式
.allowedMethods("*")
// .allowedMethods("GET","POST","DELETE","PUT");
//设置允许的header请求头的属性
.allowedHeaders("*")
//设置允许跨域的时间
.maxAge(3600);
}
}
MybatisPlus的分页插件配置类:
package com.xuguoguo.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
@Package: com.xuguoguo.config
@ClassName: MybatisPlusConfig
@Author: XuGuoGuo
@CreateTime: 2023/12/13-8:36
@Description:
*/
@Configuration
public class MybatisPlusConfig {
/**
* 添加分页插件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));//如果配置多个插件,切记分页最后添加
//interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); 如果有多数据源可以不配具体类型 否则都建议配上具体的DbType
return interceptor;
}
}
用户控制器编写:
package com.xuguoguo.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xuguoguo.commons.Result;
import com.xuguoguo.entity.Users;
import com.xuguoguo.service.UsersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
@Package: com.xuguoguo.controller
@ClassName: UsersController
@Author: XuGuoGuo
@CreateTime: 2023/12/12-16:40
@Description:
*/
@RestController
@RequestMapping("/users")
public class UsersController {
//注入service
@Autowired
private UsersService usersService;
@RequestMapping("/loadAll")
public Result loadAll(){
List<Users> list = usersService.list();
return Result.of(list);
}
}
分别启动服务器:
npm run serve
打开浏览器访问:
分页以及条件查询的处理:
页面的修改:
参照官方的文档去添加分页条
https://element-plus.gitee.io/zh-CN/component/pagination.html
在UserHome.vue文件中添加
分页代码:
搜索框代码:
UserHome.vue修改后的完整代码如下:
<template>
<div style="padding:10px;">
<h1>用户列表页面</h1>
<!-- 功能区域 -->
<div style="margin:10px 0px;">
<el-button type="primary">新增用户</el-button>
<el-button type="danger">删除用户</el-button>
<el-button type="danger">批量删除</el-button>
<el-button type="success">修改用户</el-button>
<el-button type="info">导入用户</el-button>
<el-button type="warning">导出用户</el-button>
<el-button type="info">帮助中心</el-button>
</div>
<!-- 搜索区域 -->
<div style="margin:10px 0px;">
<el-input
v-model="search"
clearable
placeholder="请输入您要搜索的条件"
style="width:25%;"
:prefix-icon="Search"
/>
<el-button type="primary" @click="load">搜 索</el-button>
</div>
<!-- 表格数据渲染用户列表信息 -->
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="id" label="用户ID" width="180" />
<el-table-column prop="username" label="用户名" width="180" />
<el-table-column prop="nickname" label="昵称" />
<el-table-column prop="sex" label="性别" />
<el-table-column prop="address" label="地址" />
<el-table-column fixed="right" label="操 作" width="300">
<el-button type="success" size="small">
查看
</el-button>
<el-button type="danger" size="small">
删除
</el-button>
<el-button type="primary" size="small">
编辑
</el-button>
</el-table-column>
</el-table>
<!-- 分页列表 -->
<div>
<el-pagination
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:page-sizes="[2, 5, 10, 20]"
:small="small"
:disabled="disabled"
:background="background"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</div>
</template>
<script>
import {getData} from "../utils/remote";
export default {
name:"UserHome",
data(){
return{
tableData:[],
currentPage:1,
pageSize:2,
total:0,
search:""
}
},
created(){
this.load();
},
methods:{
load(){
getData("users/loadAllByPage",{
pageNum:this.currentPage,
pageSize:this.pageSize,
search:this.search
}).then(res=>{
console.log(res);
this.tableData=res.data.records;
this.total=res.data.total;
});
},
handleSizeChange(pageSize){
this.pageSize=pageSize;
this.load();
},
handleCurrentChange(pageNum){
this.currentPage=pageNum;
this.load();
}
}
}
</script>
<style>
</style>
后台控制器的修改:
@RequestMapping("/loadAllByPage")
public Result loadAllByPage(@RequestParam("pageNum")Integer pageNum,
@RequestParam("pageSize")Integer pageSize,
String search){
//通过分页的插件【拦截器】
Page<Users> pages = new Page<>(pageNum, pageSize);
//构造条件构造器
QueryWrapper<Users> usersQueryWrapper = new QueryWrapper<>();
if (search!=null&& !"".equals(search)) {
usersQueryWrapper.like("username",search);
}
Page<Users> page = usersService.page(pages, usersQueryWrapper);
return Result.of(page);
}
添加用户信息的的实现:
页面中处理:
<!-- 添加用户的对话框 -->
<div>
<el-dialog
v-model="dialogVisible"
title="用户信息"
width="30%"
>
<!-- 表单数据 -->
<el-form
:model="form"
label-width="120px"
:rules="rules"
ref="form"
>
<el-form-item label="用户名:" prop="username">
<el-input v-model="form.username" style="width: 80%;" clearable />
</el-form-item>
<el-form-item label="密码:" prop="password">
<el-input v-model="form.password" style="width: 80%;" clearable />
</el-form-item>
<el-form-item label="昵称:" prop="nickname">
<el-input v-model="form.nickname" style="width: 80%;" clearable/>
</el-form-item>
<el-form-item label="性 别:" prop="sex">
<el-radio v-model="form.sex" label="男" size="large" >男</el-radio>
<el-radio v-model="form.sex" label="女" size="large" >女</el-radio>
<el-radio v-model="form.sex" label="未知" size="large" >未知</el-radio>
</el-form-item>
<el-form-item label="地 址:" prop="address">
<el-input type="textarea" v-model="form.address" style="width: 80%;" clearable/>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">关闭</el-button>
<el-button type="primary" @click="save">确认</el-button>
</span>
</template>
</el-dialog>
表单提交的事件:
save(){
//表单提交处理
//表单校验处理
this.$refs["form"].validate((valid)=>{
//校验通过发起请求保存用户信息
// console.log(valid);
if(valid){
postData("users/save",this.form).then(res=>{
console.log(res.data);
if(res.data){
this.load();
this.dialogVisible=false;
this.$message({
message: '成功添加用户信息!',
type: 'success',
});
}else{
ElMessage.error('添加用户信息失败!');
}
});
}
});
}
后端控制器中的编写:
@RequestMapping("/save")
public Result save(@RequestBody Users users){
//调用service实现新增用户
boolean save = usersService.save(users);
return Result.of(save);
}
完整的UserHome.vue代码如下:
<template>
<div style="padding:10px;">
<h1>用户列表页面</h1>
<!-- 功能区域 -->
<div style="margin:10px 0px;">
<el-button type="primary" @click="add"><el-icon><DocumentAdd /></el-icon>新增用户</el-button>
<el-button type="danger"><el-icon><DocumentDelete /></el-icon>删除用户</el-button>
<el-button type="danger"><el-icon><Delete /></el-icon>批量删除</el-button>
<el-button type="success"><el-icon><Edit /></el-icon>修改用户</el-button>
<el-button type="info">导入用户</el-button>
<el-button type="warning">导出用户</el-button>
<el-button type="info">帮助中心</el-button>
</div>
<!-- 搜索区域 -->
<div style="margin:10px 0px;">
<el-input
v-model="search"
clearable
placeholder="请输入您要搜索的条件"
style="width:25%;"
:prefix-icon="Search"
/>
<el-button type="primary" @click="load">搜 索</el-button>
</div>
<!-- 表格数据渲染用户列表信息 -->
<el-table :data="tableData" style="width: 100%" border>
<el-table-column prop="id" label="用户ID" width="180" />
<el-table-column prop="username" label="用户名" width="180" />
<el-table-column prop="nickname" label="昵称" />
<el-table-column prop="sex" label="性别" />
<el-table-column prop="address" label="地址" />
<el-table-column fixed="right" label="操 作" width="300">
<el-button type="success" size="small">
查看
</el-button>
<el-button type="danger" size="small">
删除
</el-button>
<el-button type="primary" size="small">
编辑
</el-button>
</el-table-column>
</el-table>
<!-- 分页列表 -->
<div style="margin:10px 0px;">
<el-pagination
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:page-sizes="[2, 5, 10, 20]"
:small="small"
:disabled="disabled"
:background="background"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
<!-- 添加用户的对话框 -->
<div>
<el-dialog
v-model="dialogVisible"
title="用户信息"
width="30%"
>
<!-- 表单数据 -->
<el-form
:model="form"
label-width="120px"
:rules="rules"
ref="form"
>
<el-form-item label="用户名:" prop="username">
<el-input v-model="form.username" style="width: 80%;" clearable />
</el-form-item>
<el-form-item label="密码:" prop="password">
<el-input v-model="form.password" style="width: 80%;" clearable />
</el-form-item>
<el-form-item label="昵称:" prop="nickname">
<el-input v-model="form.nickname" style="width: 80%;" clearable/>
</el-form-item>
<el-form-item label="性 别:" prop="sex">
<el-radio v-model="form.sex" label="男" size="large" >男</el-radio>
<el-radio v-model="form.sex" label="女" size="large" >女</el-radio>
<el-radio v-model="form.sex" label="未知" size="large" >未知</el-radio>
</el-form-item>
<el-form-item label="地 址:" prop="address">
<el-input type="textarea" v-model="form.address" style="width: 80%;" clearable/>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">关闭</el-button>
<el-button type="primary" @click="save">确认</el-button>
</span>
</template>
</el-dialog>
</div>
</div>
</template>
<script>
import {getData,postData} from "../utils/remote";
export default {
name:"UserHome",
data(){
return{
tableData:[],
currentPage:1,
pageSize:2,
total:0,
search:"",
dialogVisible:false,
form:{},
rules:{
username:[
{required:true,message:"请输入用户名!",trigger:"blur"}
],
password:[
{required:true,message:"请输入密码!",trigger:"blur"}
],
nickname:[
{required:true,message:"请输入昵称!",trigger:"blur"}
],
address:[
{required:true,message:"请输入地址!",trigger:"blur"}
]
}
}
},
created(){
this.load();
},
methods:{
load(){
getData("users/loadAllByPage",{
pageNum:this.currentPage,
pageSize:this.pageSize,
search:this.search
}).then(res=>{
console.log(res);
this.tableData=res.data.records;
this.total=res.data.total;
});
},
handleSizeChange(pageSize){
this.pageSize=pageSize;
this.load();
},
handleCurrentChange(pageNum){
this.currentPage=pageNum;
this.load();
},
add(){
//显示对话框
this.dialogVisible=true;
this.form={};
},
save(){
//表单提交处理
//表单校验处理
this.$refs["form"].validate((valid)=>{
//校验通过发起请求保存用户信息
// console.log(valid);
if(valid){
postData("users/save",this.form).then(res=>{
console.log(res.data);
if(res.data){
this.load();
this.dialogVisible=false;
this.$message({
message: '成功添加用户信息!',
type: 'success',
});
}else{
ElMessage.error('添加用户信息失败!');
}
});
}
});
}
}
}
</script>
<style>
</style>
添加用户信息的扩展【mp的自动填充】
在实际操作数据表的过程中,很多列都是可以自己填充的。比如说创建时间、修改时间、创建用户等,所以这个时候我们考虑使用mp的自动填充的策略来实现
可参考mp的官网:https://baomidou.com/pages/4c6bcf/
数据表的修改:
用户实体对象的修改:
需要注意的是mysql服务器的版本的区别,如果是mysql5,使用Date表示时间,如果是mysql8可以使用LocalDateTime来处理时间对象
编写自动填充的配置类:
代码如下:
参考官网即可https://baomidou.com/pages/4c6bcf/ (也需要注意数据库的版本哦!!!)
package com.xuguoguo.utils;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.Date;
/**
@Package: com.xuguoguo.utils
@ClassName: MyMetaObjectHandler
@Author: XuGuoGuo
@CreateTime: 2023/12/14-8:53
@Description:
*/
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
log.info("开始自动填充【insert】 ....");
// this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐使用)
// // 或者
// this.strictInsertFill(metaObject, "createTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
// 或者
this.strictInsertFill(metaObject, "createTime", Date.class, new Date()); // 也可以使用(3.3.0 该方法有bug)
// this.strictInsertFill(metaObject, "updateTime", Date.class, new Date()); // 也可以使用(3.3.0 该方法有bug)
// this.fillStrategy(metaObject, "createUser", BaseContext.getCurrentId()); // 也可以使用(3.3.0 该方法有bug)
this.strictInsertFill(metaObject, "createUser", Integer.class, 666); // 也可以使用(3.3.0 该方法有bug)
// metaObject.setValue("createTime",LocalDateTime.now());
// metaObject.setValue("updateTime",LocalDateTime.now());
// metaObject.setValue("createUser",666);
}
@Override
public void updateFill(MetaObject metaObject) {
log.info("开始自动填充【update】 ....");
// this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐)
// // 或者
// this.strictUpdateFill(metaObject, "updateTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
// 或者
this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date()); // 也可以使用(3.3.0 该方法有bug)
this.strictUpdateFill(metaObject, "updateUser", Integer.class,888); // 也可以使用(3.3.0 该方法有bug)
// metaObject.setValue("updateTime",LocalDateTime.now());
// metaObject.setValue("updateUser",888);
}
}
用户信息的话可以使用LocalThread来设置和获取:
package com.xuguoguo.utils;
/**
@Package: com.xuguoguo.utils
@ClassName: BaseContext
@Author: XuGuoGuo
@CreateTime: 2023/12/14-8:56
@Description:
*/
//使用ThreadLocal封装工具类
public class BaseContext {
public static ThreadLocal<Integer> threadLocal=new ThreadLocal<Integer>();
/**
* 设置值
*/
public static void setCurrentId(Integer id) {
threadLocal.set(id);
}
/**
* 获取值
*/
public static Integer getCurrentId() {
return threadLocal.get();
}
}
检查application.yml的配置:
前端vue中的时间渲染处理
有多种方式,这里我用两种插件来简化实现
1、安装插件 【moment.js或者day.js进行时间格式化】
npm install moment
或者
npm install dayjs
在时间列上绑定一个时间格式化函数【:formatter=“函数名”】
在需要使用格式化的vue中引入插件
最后在methods中定义函数即可:
formatDate(row, column) {
let datas = row[column.property];
if (datas == null) {
return "";
} else {
return moment(datas).format("yyyy-MM-DD HH:mm:ss");
}
}
修改用户信息的实现
在修改的html代码中通过template进行引导页面【#default="scope"进行传递行数据】
在methods中定义函数回显当前行的数据:
handleEdit(row) {
console.log(row);
this.form = JSON.parse(JSON.stringify(row));
this.dialogVisible = true;
}
更新提交处理:
因为是共用的事件,所以需要通过判断是否有id值来判断是新增还是修改
save() {
//表单提交处理
//表单校验处理
this.$refs["form"].validate((valid) => {
//校验通过发起请求保存用户信息
// console.log(valid);
if (valid) {
//如何区分是添加/更新
//更新【携带了id】
if (this.form.id) {
postData("users/edit",this.form).then(res=>{
if (res.data) {
this.load();
this.dialogVisible = false;
this.$message({
message: "成功更新用户信息!",
type: "success",
});
} else {
ElMessage.error("更新用户信息失败!");
}
});
} else {
//新增【没有id】
postData("users/save", this.form).then((res) => {
console.log(res.data);
if (res.data) {
this.load();
this.dialogVisible = false;
this.$message({
message: "成功添加用户信息!",
type: "success",
});
} else {
ElMessage.error("添加用户信息失败!");
}
});
}
}
});
}
后端的控制器处理:
@RequestMapping("/save")
public Result save(@RequestBody Users users){
//调用service实现新增用户
boolean save = usersService.save(users);
return Result.of(save);
}
@RequestMapping("/edit")
public Result edit(@RequestBody Users users){
boolean b = usersService.updateById(users);
return Result.of(b);
}
删除用户信息
在methods中自定义删除的事件
deleteUser(id){
console.log(id);
postData("users/"+id).then(res=>{
if (res.data) {
this.load();
this.$message({
message: "成功删除用户信息!",
type: "success",
});
} else {
ElMessage.error("删除用户信息失败!");
}
});
}
}
后端控制器的编写:
@RequestMapping("/{id}")
public Result deleted(@PathVariable("id")Integer id){
boolean b = usersService.removeById(id);
return Result.of(b);
}
本节完毕,章节后续更新!如果需要源码的朋友们可关注微信公众号"锅锅编程生活"或者扫描二维码关注回复关键字/后台留言获取即可!