SpringBoot+Vue-admin-template 实现增删改查

前言

本文的案例是基于Vue-admin-template项目改造的简化版Vue后台管理模板案例

主要是想帮助那些和我一样从后端入门并且想要快速上手Vue后台管理系统的开发

本文在SpringBoot、Element UI、Vue框架之上实现的小案例,并非从零开始

各位如果遇到难题,可以向百度和谷歌虚心求教,我也是一路折腾过来才写下此文

技术栈

  1. SpringBoot2.3
  2. Vue-admin-template4.3
  3. axios
  4. mysql5.7
  5. mybatis

案例演示

demo-result

案例实践

1.下载项目,按照操作把项目跑起来

# 去github克隆项目(我的版本是4.0版本vue-admin-template)
git clone https://github.com/PanJiaChen/vue-admin-template
# 进入目录
cd vue-admin-template
# 安装依赖(前提需要自行安装配置好node.js)
npm install --registry=https://registry.npm.taobao.org
# 运行
npm run dev

2.在侧边栏新增导航路由页面

  1. 新建文件。在src/views/ 新建一个文件夹 student,在此目录下新建文件 index.vue

  2. 添加路由。打开 src/router/index.js,此文件为该项目的后台路由配置文件。在constantRoutes这个数组中,添加路由的格式如下:

     {
        path: '/student', // 页面访问的url一级路径
        component: Layout,// 这是全局统一的一个布局文件,暂时不需要修改
        children: [
          {
            path: 'index',// 页面访问的url二级路径
            name: 'Student',
            component: () => import('@/views/student/index'), // 导入刚才新建vue文件的路径
            meta: { title: '学生', icon: 'form' } // title 是侧边栏的名字,icon是图标 
          }
        ]
      },
    

这一步我们完成路由配置,之后框架会自动地根据路由配置文件,生成边侧导航条目,剩下的工作就是写好那个index.vue组件的内容,这里包含两部分内容:简单编写组件和发送网络请求

3.简单编写组件,后面再美化组件

编程就是由简单慢慢到复杂,我们先在页面上完成一个简单的页面,只制作页面上输出123的页面组件

<template>
    <!-- div是作为根元素,必须要有这个元素 -->
  <div>
    123
  </div>
</template>
<script>
export default {
  data() {
    return {
      // 这里定义数据格式
    }
  },
  mounted() {
 	// 这里是vue钩子函数,不理解的话就是js的入口
  },
  methods: {
  	// 这是定义方法的区域
  }
}
</script>
<style scoped>
	// 这是写CSS内容的区域
</style>

如果上述步骤都没错的话,你可以得到下面的页面效果

demo-123-page

4.网络请求基础配置

4.1 跨域访问资源

本文中开发的页面是运行部署在前端服务器上,端口是http://localhost:9528,后台的数据是在后端服务器上,端口是http://localhost:8080, 两者之间端口不一致,需要跨域名访问资源,用到的是代理模式,这里就涉及到跨域访问资源和同源策略这两个概念,本文不做深入讲解,暂且只需要知道

在项目上线后,对于CORS跨域资源访问的问题,可以用类似的方案(Nginx反向代理)在前端解决。

4.2 代理模式

生活中的代理模式例子:小明要买一台高性能的华硕电脑,去街上的实体店看到只有样板的华硕电脑,于是付钱给经销商,经销商拿着钱去找华硕厂家拿到高性能的华硕电脑,然后回到实体店把电脑交付给小明,同时还赚取了中间差价,这就是一个典型的代理模式案例

4.3 开发中的代理模式

vue-admin-template是基于vue-cli开发出来的,部署在前端的服务器,

  1. 浏览器访问这些页面组件就相当于小明看到华硕电脑样板

  2. 前端服务器代理转发请求到后端服务器相当于经销商把钱付给厂家

  3. 后端服务器返回数据给前端服务器前端服务器,服务器再返回数据给浏览器

    就相当于厂家交付电脑给经销商,经销商拿到后再交付电脑给小明

proxy

登录接口的实现我在上一篇文章中已经很详细地讲解过,所以这篇文章中不会有过多的关于登录接口的实现的细节

只是在上篇的基础上进行对接口代理进行的改动,不懂的可以先去看看SpringBoot实现Vue-admin-template登录

配置代理

因为存在跨域资源请求的问题,前后端交互的网络请求在底层由node.js代理,有兴趣的可以看下官方文档

打开根目录下的vue.config.js文件,在devServer中添加proxy区域的代码

devServer: {
    port: port,
    open: false,
    overlay: {
      warnings: false,
      errors: true
    },
	// 代理所有以‘/admin’开头的网络请求
	proxy: {
      '/admin': {
        target: `http://localhost:8080/`, //后台服务地址(Springboot内置tomcat默认的地址)
        changeOrigin: true,
        pathRewrite: {
        // 路径重写,可以理解为路径重新赋值 
        // '^/admin': '/' 
        // pathRewrite: {'^/admin': '/'} 重写之后url为 http://localhost:8080/xxxx
        // pathRewrite: {'^/admin': '/admin'} 
        // 重写之后url为http://localhost:8080/admin/xxxx
        }
      }
    }
}

配置地址

生产环境与开发环境通常有不同的服务地址。编辑 .env.development 以及 .env.production 这两个文件,修改其中的 VUE_APP_BASE_API 配置项即可

本文只涉及开发,就以开发环境为例:

VUE_APP_BASE_API = '/admin'

配置拦截器

打开src/utils/request.js,它封装了一个axios请求对象,它就是jquery中的ajax那样理解着用,应该很快就能上手,在这个项目的数据交互的请求都是基于axios来处理的。

我们可以在发送请求之前规定一些后端数据返回的格式,方便我们自己调试和定位网络请求是否正确响应和输出。比如根据服务端的状态码判断请求是否正常,若不正常给出相应的提示。

service.interceptors.response.use(
  response => {
    const res = response.data

    // if the custom code is not 20000, it is judged as an error.
    // 个性化定制响应的状态码不为20000,它会认为这是一个错误的响应
    if (res.code !== 20000) { // 这里可以根据业务修改为res.code !== 200 我演示就懒得改
      Message({
        message: res.message || 'Error',
        type: 'error',
        duration: 5 * 1000
      })

      // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
      // 50008: 非法的token 50012: 其他客户端登录了; 50014: Token 过期了;
      if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
        // to re-login
        MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
          confirmButtonText: 'Re-Login',
          cancelButtonText: 'Cancel',
          type: 'warning'
        }).then(() => {
        // 重新设置token
          store.dispatch('user/resetToken').then(() => {
            location.reload()
          })
        })
      }
       // 返回一个Promise对象,ES6中的方便处理异步请求的对象,可以查阅MDN文档理解
      return Promise.reject(new Error(res.message || 'Error'))
    } else {
      return res
    }
  },
)

配置全局请求

src/main.js加入下面的代码配置,这样我们就可以在组件的脚本使用全局发起请求

Vue.prototype.http = request

1.全局发起请求

this.http({
// 此处写不同业务对应的url,框架会自动与baseURL拼接
  url: "getInfo?id=6", 
  data: {},
  method: "GET"
}).then(
  res => {
    // 请求成功后的处理
    console.log("res :", res);
  },
  err => {
    // 请求失败后的处理
    console.log("err :", err);
  }
);

2.单一封装好请求

按照比较好的前端开发模式,应该是把网络请求统一抽离到单一文件,然后在每个具体的页面进行对服务端数据的处理。 比如下面的这种形式,首先创建文件src/api/student.js,把在student组件中需要用到的网络请求都写入此文件。

// src/api/student.js
import request from '@/utils/request'

export function getStudentList(params) {
  return request({
    url: 'getTableData',
    method: 'get',
    params
  })
}

3.登录接口的实现适配

src\api\user.js中修改了login的接口代码

export function login(data) {
  return request({
    url: '/user/login',
    method: 'post',
    data
  })
}

4.前后登录接口数据流细节对比

新的登录接口

login-axios-new

上篇文章旧的登录接口前端做了小改动和SpringBoot中的LoginController做了小改动

login-axios-old

5.后端SpringBoot搭建接口返回数据

5.1 pom.xml引入依赖
 		<!--web开发依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--mybatis依赖-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.1</version>
        </dependency>
        <!--mysql依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!--lombok依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
5.2 SpringBoot配置数据库和端口
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test?characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: root
server:
  port: 8080 // 端口号
  servlet:
    context-path: /admin // 项目根路径
5.3 实体类
@Data//使用这个注解就默认帮我们生成getter和setter以及toString等
@NoArgsConstructor //lombok生成无参数构造函数
public class Student {
    private Integer id;
    private String name;
    private Integer age;
    private String className;
    private String gender;
    private String marjor;
    private String department;
}
5.4 mapper接口
@Mapper
public interface StudentMapper {
    @Select("select * from student where id=#{id}")
    Student findStudentById(Integer id);

    @Insert("insert into student(name,age)values(#{name},#{age})")
    void insertStudent(Student student);

    @Update("update student set name=#{name} where id=#{id}")
    void updateStudent(Student student);

    @Delete("delete from student where id=#{id}")
    void deleteStudentById(Integer id);

    @Select("select * from student")
    List<Student> findAll();
}
5.5 controller类

这里省略了dao层和service层,主要是写demo贪方便,实际开发中还是要遵循3层结构开发

@RestController
public class StudentController {
    @Autowired
    private StudentMapper studentMapper;

    @CrossOrigin // 跨域访问
    @GetMapping(value = "/getTableData")
    public Map finAllStudent(){
        List<Student> studentList = studentMapper.findAll();
        HashMap<String, Object> responseData = new HashMap<>();
        responseData.put("code",20000);
        responseData.put("data",studentList);
        return responseData;
    }
}

6.使用Element UI美化组件

现在我们可以在student.vue中用Element UI所提供的组件来美化我们student页面组件

  1. Table组件写一个表格数据展示区域,

  2. 用Element UI的栅格布局和Form组件在表格上方编写一个搜索区域,用来做日常的增删改查功能

  3. 用Element UI的 Pagination 组件在表格上方编写一个搜索区域,用来做日常的增删改查功能

进入Element UI Table表格 ,Pagination分页,Layout 布局, Form 表单组件的说明文档,复制粘贴对应的代码。

vue-admin-template对于Element UI已经进行了全局引入,所以这些组件拿来即用。

这里暂且以获取后端的返回的数据作为案例,只要能写通这个区域,其他的基本上能一通百通,也就自然会增删改

<template>  
<!-- 数据表格区域 -->
    <div class="data-content">
      <el-table
        :data="tableData"
        style="width: 100%"
        border
      >
        <el-table-column
          type="selection"
          width="55"
        />
        <el-table-column
          type="index"
          label="序号"
          width="80px"
        />
        <el-table-column
          prop="name"
          label="姓名"
          width="180"
        />
        <el-table-column
          prop="age"
          label="年龄"
        />
         <el-table-column
          prop="gender"
          label="性别"
        />
         <el-table-column
          prop="className"
          label="班级"
        />
         <el-table-column
          prop="marjor"
          label="专业"
        />
        <el-table-column
          prop="department"
          label="系别"
        />
      </el-table>
    </div>
</template>

在组件装载时请求数据

<script>
import { getStudentList } from '@/api/student.js' // 导入封装过的网络请求专门用于student相关api
export default {
  data() {
    return {
      // 表格数据
      tableData: []
    }
  },
  mounted() { // mounted钩子函数(生命周期函数)相当window.onload函数,随页面一加载执行
  // 单一网络请求在student.js经过封装统一处理,这里需要导入这个文件
    getStudentList({}).then(res => {
      console.log('tableData :', res)
      this.tableData = res.data
    }, err => {
      console.log('err :', err)
    })
  },
  methods: {
  	// 暂时没用到定义方法,可以不写
  }
}
</script>

数据正常的页面实际效果

table-result

数据正常的页面动态效果

demo-result-end

后序

文章虽然不多图,但大体的流程都详细讲解了,碍于文章篇幅太长,
如果把增删改查放在一篇文章里面记录,就会很容易产生阅读疲劳
所以暂时只把查询作为案例讲解,后面会把剩下的增删改补上

文章配套源码已传至百度网盘,拿来即用(github好像也有,可以自行查看以往的文章)

链接: https://pan.baidu.com/s/1u9DY3zzRn4-r9Ih_OAZeJg 提取码: c4k3

posted @ 2020-06-17 22:46  Codeluojay  阅读(6158)  评论(7编辑  收藏  举报