SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现

系列文章:
SpringBoot + Vue前后端分离项目实战 || 一:Vue前端设计
SpringBoot + Vue前后端分离项目实战 || 二:Spring Boot后端与数据库连接
SpringBoot + Vue前后端分离项目实战 || 三:Spring Boot后端与Vue前端连接
SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现
SpringBoot + Vue前后端分离项目实战 || 五:用户管理功能后续

文章目录

    • 前端实现
    • 编写user.vue(整个`user.vue`代码已经放在文章最后)
      • 第一部分——搜索框
      • 第二部分——data表格
      • 第三部分——分页插件
    • 配置后端接口
    • 后端编写代码
    • user.vue

前端实现

之前自定义的user.vue页面为空白,现来实现其功能
SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第1张图片

先去element官网浏览需要的组件
官网链接: https://element.eleme.cn/2.13/#/zh-CN/component/dialog
版本:2.13.2
在这里插入图片描述

需要用到的组件:

  1. 卡片
    SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第2张图片
  2. 表格
    SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第3张图片
  3. 分页——完整功能
    SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第4张图片
  4. 输入框
    SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第5张图片
  5. 按钮
    SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第6张图片
  6. 打开表单的对话框
    SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第7张图片

编写user.vue(整个user.vue代码已经放在文章最后)

整体的页面分为3个部分,搜索——显示——分页插件
SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第8张图片

第一部分——搜索框

前端组件代码如下:
SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第9张图片

红色:绑定数据
黄色:绑定函数
白色:element自带的icon图标
SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第10张图片

  • 红色:
    SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第11张图片

  • 橙色:
    SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第12张图片
    SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第13张图片

  • 白色
    SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第14张图片

第二部分——data表格

SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第15张图片

  • 红色:绑定的数据列表变量
    SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第16张图片

  • 橙色,显示表格数据的序号,涉及到searchModel.pageNosearchModel.pageSize两个变量
    SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第17张图片

  • 白色:与后端的实体变量名保持一致
    SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第18张图片

第三部分——分页插件

SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第19张图片

  • 红色:更改插件的显示页数会再次查询数据库显示数据
    SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第20张图片
  • 橙色:分页插件的一些变量
    SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第21张图片
    至此,三个部分的前端介绍完毕

写上前端的钩子函数(页面加载自动取查询数据库然后显示)
SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第22张图片

配置后端接口

src\api新建一个userManage.js写上代码
SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第23张图片

import request from '@/utils/request'


export default{
  getUserList(searchModel){
    return request({
      url:'/user/list',
      method:'get',
      params:{    // 传给后端的参数
        pageNo: searchModel.pageNo,
        pageSize: searchModel.pageSize,
        username: searchModel.username,
        phone: searchModel.phone,
      }

    });
  },

}

然后去user.vue注册该文件
SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第24张图片

// 前后端对接的配置
import userApi from '@/api/userManage'

后端编写代码

UserController里面写对接前端的代码
SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第25张图片

// 增删改查,增:post请求,查:get请求,修改:put请求,删除:delete请求
@GetMapping("/list")
public Result<Map<String,Object>> getUserList(@RequestParam(value = "username",required = false) String username,
                                              @RequestParam(value = "phone",required = false) String phone,
                                              @RequestParam(value = "pageNo") Long pageNo,
                                              @RequestParam(value = "pageSize") Long pageSize
                                              ){

    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();

    // 第一个参数是对username进行判空条件,第三个username是传过来进行比较的值
    wrapper.eq(StringUtils.hasLength(username),User::getUsername,username);
    wrapper.eq(StringUtils.hasLength(phone),User::getPhone,phone);

    // 苞米豆 里的Page包,不是Spring的,传入当前页数和每页大小
    Page<User> page = new Page<>(pageNo, pageSize);

    // 分页查找,用 .page()方法
    userService.page(page,wrapper);

    Map<String,Object> data = new HashMap<>();
    data.put("total",page.getTotal());
    data.put("rows",page.getRecords());

    return Result.success(data);
}

注意下图中红色部分与前端的userManage.js中红色部分需保持一致
SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第26张图片SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第27张图片


此处后端返回的数据名也需和前端保持一致
SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第28张图片
SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第29张图片

借助postman验证
SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第30张图片
此处返回一个json对象,里面有codemessagedata字段,而且data中有totalrows字段

前端user.vue中代码 this.total = response.data.total;就是获取该data中的total数据

新增Mybatis-Plus的分页配置代码:在config\下新增MpConfig文件
SpringBoot + Vue前后端分离项目实战 || 四:用户管理功能实现_第31张图片

package com.ums.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;


// 官网地址 https://baomidou.com/pages/2976a3/#spring
@Configuration
public class MpConfig {
    //配置 mybatis plus的分页插件,死代码
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

user.vue

<template>
  <div>
    
    <el-card id="search">

      <el-row>
        <el-col :span="20">
          <el-input v-model="searchModel.username" placeholder="用户名" clearable>el-input>
          <el-input v-model="searchModel.phone" placeholder="电话" clearable>el-input>
          <el-button @click="getUserList" type="primary" round icon="el-icon-search">查询el-button>
        el-col>

        <el-col :span="4" align="right">
          <el-button @click="openEditUI" type="primary" icon="el-icon-plus" circle>el-button>
        el-col>
      el-row>

    el-card>

    
    <el-card>
      <el-table :data="userList" stripe style="width: 100%">
        <el-table-column  label="#" width="80">
          <template slot-scope="scope">
            
            {{(searchModel.pageNo-1) * searchModel.pageSize + scope.$index + 1}}
          template>
        el-table-column>
        <el-table-column prop="id" label="用户ID" width="180">
        el-table-column>
        <el-table-column prop="username" label="用户名" width="180">
        el-table-column>
        <el-table-column prop="phone" label="电话" width="180">
        el-table-column>
        <el-table-column prop="email" label="电子邮件">
        el-table-column>
        <el-table-column label="操作" width="180">
        el-table-column>
      el-table>
    el-card>

    
    <el-pagination 
    @size-change="handleSizeChange" 
    @current-change="handleCurrentChange"
      :current-page="searchModel.pageNo" 
      :page-sizes="[5, 10, 20, 30, 40]" 
      :page-size="searchModel.pageSize"
      layout="total, sizes, prev, pager, next, jumper" 
      :total="total">
    el-pagination>


    
    
    <el-dialog @close="clearForm" :title="title" :visible.sync="dialogFormVisible">
      <el-form :model="userForm">
        <el-form-item label="用户名" :label-width="formLabelWidth">
          <el-input v-model="userForm.username" autocomplete="off">el-input>
        el-form-item>

        <el-form-item label="登录密码" :label-width="formLabelWidth">
          <el-input type="password" v-model="userForm.password" autocomplete="off">el-input>
        el-form-item>

        <el-form-item label="联系电话" :label-width="formLabelWidth">
          <el-input v-model="userForm.phone" autocomplete="off">el-input>
        el-form-item>

        <el-form-item label="用户状态" :label-width="formLabelWidth">
          <el-switch v-model="userForm.status" 
            :active-value="1"
            :inactive-value="0"
            active-color="#13ce66" 
            inactive-color="#ff4949">
          el-switch>
        el-form-item>

        <el-form-item label="电子邮件" :label-width="formLabelWidth">
          <el-input v-model="userForm.email" autocomplete="off">el-input>
        el-form-item>
        
      el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消el-button>
        <el-button type="primary" @click="dialogFormVisible = false">确 定el-button>
      div>
    el-dialog>


  div>
template>


<script>
  // 前后端对接的配置
  import userApi from '@/api/userManage'

  // 页面变量
  export default {
    data () {
      return {
        formLabelWidth: '130px',
        userForm: {},
        dialogFormVisible: false,
        title: "",
        total: 0,
        searchModel: {    // 当前页面参数,会调用方法传给后端
          pageNo: 1,
          pageSize: 5
        },
        userList: [],
      }
    },

    methods: {
      clearForm(){
        // 清空表单
        this.userForm={}
      },

      openEditUI(){
        this.title = '新增用户';
        this.dialogFormVisible = true;
      },

      // 此处对应pageSize和pageNo改变时更改前端的显示
      handleSizeChange(pageSize){
        // 更新数据,完毕后重新调用函数
        this.searchModel.pageSize = pageSize;
        this.getUserList(); 
      },

      handleCurrentChange(pageNo){
        // 更新数据,完毕后重新调用函数
        this.searchModel.pageNo = pageNo;
        this.getUserList(); 
      },
      getUserList(){
        // userApi.getUserList 开始调用后端,并传递参数searchModel
        // then表示后端查询后返回的数据
        userApi.getUserList(this.searchModel).then(response=>{
          this.userList = response.data.rows;   // 后端返回的 json中的字段
          this.total = response.data.total;
        });
      }
    },

    // 钩子函数定义处
    created(){
      // 定义了一个钩子函数,即加载页面后就自动执行getUserList函数,显示数据
      this.getUserList();
    },

  }
script>


<style>
  #search .el-input {
    width: 200px;
    margin-right: 10px;
  }
  .el-dialog .el-input{
    width: 85%;
  }
style>

你可能感兴趣的:(vue.js,spring,boot,前端)