SpringBoot集成Vue3实现的系统(一)

学习目标: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>
预览基本的效果:

SpringBoot集成Vue3实现的系统(一)_第1张图片

二、搭建基础的后台进行请求处理

基于maven构建一个springboot2+mp的后台应用:
pom.xml文件的基础依赖坐标:

<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.0modelVersion>
    <groupId>com.xuguoguogroupId>
    <artifactId>springboot2-vue3-mpartifactId>
    <version>0.0.1-SNAPSHOTversion>
    <name>springboot2-vue3-mpname>
    <description>springboot2-vue3-mpdescription>
    <properties>
        <java.version>1.8java.version>
        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
        <spring-boot.version>2.7.6spring-boot.version>
    properties>
    <dependencies>


        <dependency>
            <groupId>com.baomidougroupId>
            <artifactId>mybatis-plus-boot-starterartifactId>
            <version>3.5.3version>
        dependency>

        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>druid-spring-boot-starterartifactId>
            <version>1.2.9version>
        dependency>

        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>5.1.6version>
        dependency>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-devtoolsartifactId>
            <scope>runtimescope>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-configuration-processorartifactId>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
    dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-dependenciesartifactId>
                <version>${spring-boot.version}version>
                <type>pomtype>
                <scope>importscope>
            dependency>
        dependencies>
    dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.pluginsgroupId>
                <artifactId>maven-compiler-pluginartifactId>
                <version>3.8.1version>
                <configuration>
                    <source>1.8source>
                    <target>1.8target>
                    <encoding>UTF-8encoding>
                configuration>
            plugin>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
                <version>${spring-boot.version}version>
                <configuration>
                    <mainClass>com.xuguoguo.Springboot2Vue3MpApplicationmainClass>
                    <skip>trueskip>
                configuration>
                <executions>
                    <execution>
                        <id>repackageid>
                        <goals>
                            <goal>repackagegoal>
                        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插件生成对应的三层代码:

SpringBoot集成Vue3实现的系统(一)_第2张图片SpringBoot集成Vue3实现的系统(一)_第3张图片

SpringBoot集成Vue3实现的系统(一)_第4张图片

基础的配置文件和类对象
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

SpringBoot集成Vue3实现的系统(一)_第5张图片

打开浏览器访问:

SpringBoot集成Vue3实现的系统(一)_第6张图片

分页以及条件查询的处理:
页面的修改:
参照官方的文档去添加分页条

https://element-plus.gitee.io/zh-CN/component/pagination.html
SpringBoot集成Vue3实现的系统(一)_第7张图片

在UserHome.vue文件中添加
分页代码:

SpringBoot集成Vue3实现的系统(一)_第8张图片

搜索框代码:

SpringBoot集成Vue3实现的系统(一)_第9张图片SpringBoot集成Vue3实现的系统(一)_第10张图片

SpringBoot集成Vue3实现的系统(一)_第11张图片

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">&nbsp;&nbsp;&nbsp;</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的自动填充的策略来实现


  1. 可参考mp的官网:https://baomidou.com/pages/4c6bcf/
数据表的修改:

SpringBoot集成Vue3实现的系统(一)_第12张图片

用户实体对象的修改:

SpringBoot集成Vue3实现的系统(一)_第13张图片

需要注意的是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的配置:

SpringBoot集成Vue3实现的系统(一)_第14张图片

前端vue中的时间渲染处理
有多种方式,这里我用两种插件来简化实现
1、安装插件 【moment.js或者day.js进行时间格式化】
npm install moment

或者

npm install dayjs
在时间列上绑定一个时间格式化函数【:formatter=“函数名”】

SpringBoot集成Vue3实现的系统(一)_第15张图片

在需要使用格式化的vue中引入插件

在这里插入图片描述

最后在methods中定义函数即可:

SpringBoot集成Vue3实现的系统(一)_第16张图片

 formatDate(row, column) {
      let datas = row[column.property];
      if (datas == null) {
        return "";
      } else {
        return moment(datas).format("yyyy-MM-DD HH:mm:ss");
      }
    }

SpringBoot集成Vue3实现的系统(一)_第17张图片

修改用户信息的实现
在修改的html代码中通过template进行引导页面【#default="scope"进行传递行数据】

SpringBoot集成Vue3实现的系统(一)_第18张图片

在methods中定义函数回显当前行的数据:

SpringBoot集成Vue3实现的系统(一)_第19张图片

handleEdit(row) {
      console.log(row);
      this.form = JSON.parse(JSON.stringify(row));
      this.dialogVisible = true;
}
更新提交处理:

SpringBoot集成Vue3实现的系统(一)_第20张图片

因为是共用的事件,所以需要通过判断是否有id值来判断是新增还是修改

SpringBoot集成Vue3实现的系统(一)_第21张图片

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);
}

SpringBoot集成Vue3实现的系统(一)_第22张图片

删除用户信息

SpringBoot集成Vue3实现的系统(一)_第23张图片

在methods中自定义删除的事件

SpringBoot集成Vue3实现的系统(一)_第24张图片

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);
}

本节完毕,章节后续更新!如果需要源码的朋友们可关注微信公众号"锅锅编程生活"或者扫描二维码关注回复关键字/后台留言获取即可!
SpringBoot集成Vue3实现的系统(一)_第25张图片

你可能感兴趣的:(Java,spring,boot,后端,java)