(九)axios前后端跨域数据交互--基于SpringBoot+MySQL+Vue+ElementUI+Mybatis前后端分离面向小白管理系统搭建

任务八 应用mybatis-plus框架https://blog.csdn.net/wdyan297/article/details/128736234

任务九 axios前后端跨域数据交互

在任务六中我们讲过,前后端跨域数据交互,有两种方式可以解决跨域请求,任务六我们使用了CorsConfig类配置跨域。本次任务,我们使用一个基于 Promise 的 HTTP 库,可以用在浏览器和 node.js 中的axios,实现前后端跨域数据交互。通过本次任务,大家能够:
(1)掌握axios的使用方法,包括全局设置;
(2)Element中<el-dialog>对话框使用,并实现数据增加;
(3)指定记录删除,以及批量数据删除;
(4)Element中<el-dialog>对话框使用,并实现指定记录修改。
目前我们的前端页面还没有变,仍然沿用最初的home页面,下一个任务中我们将进行VUE路由设计,主要对侧边栏进行维护,届时将对页面的逻辑进行调整。

一、基础axios配置

1.Vue安装axios

axios首先需要安装,如果VUE项目正在运行,请使用CTRL+C,然后点击Y终止运行,然后的终端输入:

npm i axios -s

在这里插入图片描述
安装成功后,大家可以看到axios的版本
在这里插入图片描述

2.引入axios封装到request中

引入axios封装到request中。新建一个utils文件夹,新建request.js。
在这里插入图片描述

3.配置文件request.js

配置文件request.js代码如下。

import axios from 'axios'

const request = axios.create({
	baseURL: '/api',  // 注意!! 这里是全局统一加上了 '/api' 前缀,也就是说所有接口都会加上'/api'前缀在,页面里面写接口的时候就不要加 '/api'了,否则会出现2个'/api',类似 '/api/api/user'这样的报错,切记!!!
    timeout: 5000
})

// request 拦截器
// 可以自请求发送前对请求做一些处理
// 比如统一加token,对请求参数统一加密
request.interceptors.request.use(config => {
    config.headers['Content-Type'] = 'application/json;charset=utf-8';
  
 // config.headers['token'] = user.token;  // 设置请求头
    return config
}, error => {
    return Promise.reject(error)
});

// response 拦截器
// 可以在接口响应后统一处理结果
request.interceptors.response.use(
    response => {
        let res = response.data;
        // 如果是返回的文件
        if (response.config.responseType === 'blob') {
            return res
        }
        // 兼容服务端返回的字符串数据
        if (typeof res === 'string') {
            res = res ? JSON.parse(res) : res
        }
        return res;
    },
    error => {
        console.log('err' + error) // for debug
        return Promise.reject(error)
    }
)


export default request

说明: 关于baseURL我们稍后经过对比之后在进行更改。

4. 在main.js中引入request对象

在这里插入图片描述
两行代码为:

import request from '@/utils/request'//添加

Vue.prototype.request=request // 添加

5.使用request,修改load方法

在前端页面使用request,修改load方法。

load() {
        //请求分页查询数据
          //fetch("http://localhost:8084/user/page?pageNum="+this.pageNum+"&pageSize="+this.pageSize+"").then(res=>res.json()).then(res=>{
          //使用axios封装的request        
           this.request.get("http://localhost:8084/user/page",{
            params:{
              pageNum: this.pageNum,
              pageSize: this.pageSize,
              username: this.username,
              nickname:this.nickname,
              address:this.address
            }
          }).then(res=>{
          console.log(res)
          this.tableData=res.data
          this.total=res.total
          })
        }

这里有几个地方需要说明:
(1)如果出现这种没有数据的情况。
在这里插入图片描述
打开“开发者工具”我们会发现,现在数据放到records以及total中,这里是一个对象,所以我们的表格数据和总条目数据需要修改取值方式。
在这里插入图片描述
后端接口是这样的:
后端代码及解析详见任务八。
在这里插入图片描述
我们在任务六中的接口是这样的:
在这里插入图片描述
所以

          console.log(res);
          this.tableData=res.records;
          this.total=res.total;

(2)使用 params整合传值
这样让前端传值比较整齐。

    params:{
              pageNum: this.pageNum,
              pageSize: this.pageSize,
              username: this.username,
              nickname:this.nickname,
              address:this.address
            }

6.运行测试

在这里插入图片描述

二、“搜索”实现模糊查询

(1)搜索按钮添加一个@click="load"点击事件,调用load方法。
(2)添加一个重置按钮,并为这个按钮添加一个@click="reset"点击事件,调用reset方法。

代码为:

        <el-button style="margin-left:5px" type="primary" @click="load">搜索</el-button>
        <el-button style="margin-left:5px" type="warning" @click="reset">重置</el-button>

reset方法的代码为:

      reset(){
        this.username="";
        this.nickname="";
        this.address="";
        this.load();
      }

运行项目,实现模糊查询。
在这里插入图片描述

三、增加数据

增加数据需要打开用户信息编辑对话框,然后输入对象值,执行添加操作,实现数据记录增加。

1. </el-main>中添加elementUI组件Dialog 对话框中的“嵌套表单的 Dialog”

</el-main>中添加一个对话框。对话框使用elementUI组件Dialog 对话框中的“嵌套表单的 Dialog”。
在这里插入图片描述
对话框这段代码放在 </el-main>中的位置没有关系,一般情况,为了增加可读性,新添加的代码我们放到最后修改相关属性,代码如下:

<el-dialog title="用户信息" :visible.sync="dialogFormVisible" width="30%">
          <el-form label-width="80px" size="small">
            <el-form-item label="用户名">
              <el-input v-model="form.username" autocomplete="off"></el-input>
            </el-form-item>          
            <el-form-item label="昵称">
              <el-input v-model="form.nickname" autocomplete="off"></el-input>
            </el-form-item>
            <el-form-item label="邮箱">
              <el-input v-model="form.email" autocomplete="off"></el-input>
            </el-form-item>
            <el-form-item label="电话">
              <el-input v-model="form.phone" autocomplete="off"></el-input>
            </el-form-item>  
            <el-form-item label="地址">
              <el-input v-model="form.address" 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" >确 定</el-button>
          </div>
        </el-dialog>  

2.data添加dialogFormVisible和form

data添加dialogFormVisible和form,并将dialogFormVisible初始化为不可见。

 data(){
      return {
        tableData:[],
        total:0,
        pageNum:1,
        pageSize:2,
        username:"",
        nickname:"",
        address:"",
        dialogFormVisible:false,
        form:{}
      }
  },

3.“新增”按钮添加调用hanleAdd()方法

“新增”按钮添加调用hanleAdd()方法。

<el-button type="primary" @click="hanleAdd">新增<i class="el-icon-circle-plus"></i></el-button>

4.添加hanleAdd方法

主要目的是打开“添加用户”对话框,代码如下。

      hanleAdd(){
        this.dialogFormVisible = true;
        this.form={};//如果之前有填过值,可以置空
      }

5.“确定”按钮填调用insert()方法

<el-button type="primary" @click="insert">确 定</el-button>

6.添加insert方法

实现用户信息添加,代码如下。

insert(){
        this.request.post("http://localhost:8084/user",this.form).then(res=>{
          if(res){
            this.$message.success("保存成功");
            this.dialogFormVisible=false;
            this.load();
          }else{
            this.$message.error("保存失败");
          }
        })
      },

7.运行项目

点击“新增”按钮,打开“用户信息”对话框。
在这里插入图片描述
添加用户信息,点击“确定”按钮,显示“保存成功”。
在这里插入图片描述
可以看到最后的数据已经添加。
在这里插入图片描述
数据表中的数据已经完成
在这里插入图片描述
这里有一个思考: 为什么密码那列为空!!!
这是因为,一般情况,系统会根据客户需求初始化一个通用密码,然后对密码进行MD5加密;
详细讲解为:
密码的安全问题:密码简单,明文密码
密码:1234 -------》 数据库:1234
这种方式一般安全性太低。
故要对密码进行加密,一般采用MD5加密,具体方法为:
MD5加密:1234+字符串(盐) 加密后生成32位的密码存到数据库中
登录的时候,对于密码则要进行解密,当原文(原密码)与盐一致,密文一致,才允许下一步操作。
MD5加密一般都需要在前端进行第一次加密,这样为了防止传递的是明文密码,然后再在后端进行二次加密。

以下方法仅供参考。
MD5加密,需要在用户表中再加一个salt字段,存放盐值。
注册时:
后端加密的方法

    String salt = UUID.randomUUID().toString();
    String password = user.getUserPassword();//取到前端传递的密码初始值
    user.setUserPassword(getMD5Pwd(password, salt)).setUserSalt(salt);//对初始密码加盐,并存放盐值,然后继续后续操作即可

加密的方法getMD5Pwd 代码为:

/**
 * 封装一个方法 对密码进行加密
 */
private String getMD5Pwd(String password, String salt) {
    String md5Pwd = password + salt;
    return DigestUtils.md5DigestAsHex(md5Pwd.getBytes());
}

登录时:

........
User selectUser = getUser("user_email", userEmail);
    if (selectUser == null) {
        return Result.error(405, "该邮箱不存在");
    }
    String userSalt = selectUser.getUserSalt();
    String userPassword = selectUser.getUserPassword();
    if (userPassword.equals(getMD5Pwd(user.getUserPassword(), userSalt))) {//解密,并与盐值做比较
........

为了项目连续性,这里就暂时不修改sys_user数据表结构,与本项目相关的MD5注册与登录,见专门撰写的博客。

四、编辑用户信息

因为前期增加用户信息已经基本搭好框架,我们在此基础上进行稍微完善就可以了,编辑用户信息比较简单。

1.给“编辑”按钮添加handleEdit()方法将当前行作为参数进行传递

<el-button type="success" size="small" icon="el-icon-edit" @click="handleEdit(scope.row)">编辑</el-button>

2.添加handleEdit()方法

添加handleEdit()方法,代码如下:

      handleEdit(row){
        console.log(row);
        this.form=row;//把当前行的数据赋值给form
        this.dialogFormVisible=true;   
      }

3.运行项目

运行项目,点击“编辑”可以打开“用户信息”对话框,实现数据更新,修改信息,因为后台调用的是saveOrUpdate(user)所以,mybatis会自动判断,然后实现更新。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
数据表中的记录:
在这里插入图片描述

五、删除用户

1.给“删除”按钮添加handleDelete()方法,将当前行的id作为参数进行传递。

<el-button type="danger" size="small"  icon="el-icon-delete" @click="handleDelete(scope.row.id)">删除</el-button>

2. 添加handleDelete()方法

添加handleDelete()方法,代码如下:

handleDelete(id){
    this.request.delete("http://localhost:8084/user/"+id+"").then(res=>{
    	if(res){
            this.$message.success("删除成功");
            this.load();
    	}else{
    		this.$message.error("删除失败");
    	} 
    })
},

3.运行项目

选中一条记录,点击"删除"。
在这里插入图片描述
提示删除成功。
在这里插入图片描述

数据表中已删除相关记录。
在这里插入图片描述

4. 删除按钮升级提示功能

此时会发现没有提示,直接删除数据,既不合理,对数据的安全性也没有保障。一般对“删除”按钮添加提示功能。
使用elementUI组件中的Popconfirm 气泡确认框,升级“删除”按钮如下。需要将原来在button中的handleDelete(scope.row.id)方法放到确认框中。

<el-popconfirm style="margin-left:5px"
                confirm-button-text='确定'
                cancel-button-text='再想想'
                icon="el-icon-info"
                icon-color="red"
                title="您确定删除吗?"
                @confirm="handleDelete(scope.row.id)"
              >
              <el-button type="danger" size="small" slot="reference" icon="el-icon-delete" >删除</el-button>

六、数据批量删除

1. 升级数据表格为有复选框列的表格

(1)首先为表格添加可以多选的复选按钮,使用elementUI的table组件中的多选。
在这里插入图片描述
(2)添加了复选框列。

<el-table-column type="selection" width="55"></el-table-column>

(3)为表格添加@selection-change="handleSelectionChange"事件。

<el-table :data="tableData" @selection-change="handleSelectionChange">
          <el-table-column type="selection" width="55"></el-table-column>
          <el-table-column prop="id" label="ID " width="80">
          </el-table-column>
          <el-table-column prop="username" label="姓名 " width="80">
          </el-table-column>
          <el-table-column prop="email" label="邮箱" width="120">
          </el-table-column>
           <el-table-column prop="phone" label="电话">
          </el-table-column>
           <el-table-column prop="nickname" label="昵称">
          </el-table-column>
          <el-table-column prop="address" label="地址">
          </el-table-column>         
          <el-table-column fixed="right" label="操作" width="240">                         
            <template slot-scope="scope">
              <el-button type="success" size="small" icon="el-icon-edit" @click="handleEdit(scope.row)">编辑</el-button>
              <el-popconfirm style="margin-left:5px"
                confirm-button-text='确定'
                cancel-button-text='再想想'
                icon="el-icon-info"
                icon-color="red"
                title="您确定删除吗?"
                @confirm="handleDelete(scope.row.id)"
              >
              <el-button type="danger" size="small" slot="reference" icon="el-icon-delete" >删除</el-button>
              </el-popconfirm>
            </template>
          </el-table-column>         
        </el-table>

(4)运行
运行结果是这样的:
在这里插入图片描述

2.编写handleSelectionChange()方法

编写handleSelectionChange()方法,代码如下:

handleSelectionChange(val){
        console.log(val);
        this.multipleSelection =val;
      },

3.后端添加一个批量删除方法

在后端UserController类添加一个批量删除接口deleteBatch:

    //使用mybtis-plus实现批量删除
    @PostMapping("/del/batch/")
    public boolean deleteBatch(@RequestBody List<Integer> ids){
        return userService.removeByIds(ids);
    }

4. “批量删除”按钮添加delBatch单击事件

<el-button type="danger" @click="delBatch">批量删除<i class="el-icon-remove"></i></el-button>

5.编写delBatch方法

编写delBatch方法。
注意: 传递IDS批量数据时,使用post请求。

delBatch(){ 
         let ids=this.multipleSelection.map(v=>v.id);//map这个方法可以实现将multipleSelection中的对象扁平化处理。
         console.log(ids);
         this.request.post("http://localhost:8084/user/del/batch/",ids).then(res=>{
         if(res){
            this.$message.success("批量删除成功");
            this.load();
          }else{
            this.$message.error("批量删除失败");
          } 
        })
      },

6.运行项目

同时选中多条记录,实现批量删除。
在这里插入图片描述
特别说明: 可以参考前面删除按钮,添加一个警告弹窗。

任务总结

本次任务,主要完成并掌握以下内容:
(1)掌握前端axios前后端跨域数据连接的方法;
(2)熟练引用Element的各类组件

彩蛋 request.js的baseURL完善

在整个增删改查的过程中,我们发现一直要与后端的这个服务地址交互。每次写很麻烦,而且容易做错,这时候request.js的baseURL设置就有用了。
我们修改axios.create,代码如下:

const request = axios.create({
	baseURL: 'http://localhost:8084',  
    timeout: 5000
})

页面中做如下修改:
在这里插入图片描述
以后都可以不用写服务器地址啦!!!

再一个彩蛋

今天是农历兔年春节,祝大家一切顺意!!!

猜你喜欢

转载自blog.csdn.net/wdyan297/article/details/128742035