Vue使用axios二次封装、解决跨域问题

1、什么是 axios

在实际开发过程中,浏览器通常需要和服务器端进行数据交互。而 Vue.js 并未提供与服务器端通信的接口。从 Vue.js 2.0 版本之后,官方推荐使用 axios 来实现 Ajax 请求。axios 是一个基于 promise 的 HTTP 客户端。

关于 promise 的详细介绍,请点击浏览文章: 《ECMAScript6语法:Promise》

axios 的主要特点如下:

  • 从浏览器中创建 XMLHttpRequest。
  • 从 node.js 发出 HTTP 请求。
  • 支持 Promise API。
  • 拦截请求和响应。
  • 转换请求和响应数据。
  • 取消请求。
  • 自动转换JSON数据。
  • 客户端支持防止CSRF/XSRF。

官方文档: 《Axios中文文档》

2、安装 axios

如果在项目中使用 axios,则可以使用 npm 方式进行安装。在命令提示符窗口中输入如下命令:

java 复制代码
npm install axios --save

或者使用 yarn 安装,命令如下:

java 复制代码
yarn add axios --save

3、axios 的语法

在实际项目开发中,前端页面中所需的数据通常要从服务器端获取,这就需要实现本地与服务器端的通信,Vue 使用 axios 实现 Ajax 请求。

语法格式和参数说明:

javascript 复制代码
axios({
    url: '',             //请求的路径
    method: 'GET',       //请求的方式,默认为GET
    params: {},          //GET请求方式:传递的参数
    data: {},            //POST请求方式:传递的参数
    headers: {},         //自定义请求头
    timeout: 1000,       //请求超时时间(毫秒)
    responseType: 'JSON' //响应的数据类型,默认为JSON
}).then(
    // then() 函数:处理请求成功的回调函数
    function (response) {
        console.log("返回的数据", response.data);
    }
).catch(function (error) {
    // catch() 函数:处理请求失败的回调函数
    console.log("发生异常:" + error.message);
});

axios 详细使用方法,请点击浏览文章: 《Vue使用axios实现Ajax请求》

4、解决跨域问题

如果 Vue 前端应用请求后端 API 服务器,出现跨域问题(CORS),如下图:

**解决方法:**在 Vue 项目中,打开 vue.config.js 配置文件,在配置文件中使用代理解决跨域问题。

javascript 复制代码
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  devServer:{
    proxy: 'http://localhost:8085',  //使用代理,解决跨域问题
  }
})

详细的解决方法,请点击浏览文章: 《Vue使用代理方式解决跨域问题》

5、axios 的二次封装

在项目中,axios 进行二次封装可以更加方便的使用 Ajax 请求,提高代码复用性和维护性。同时可以封装统一的请求与响应拦截处理。

项目结构图:

5.1 封装 axios 公共处理类

在项目 src 目录下,创建 utils 目录,并在该目录下创建 request.js 类:

javascript 复制代码
// 1、引入axios
import axios from 'axios'

// 2、创建axios对象
const request = axios.create({
    //baseURL: 'http://localhost:8081', //注意:因为已经在 vue.config.js 文件中配置了代理服务(解决跨域问题),所有这里需要注释掉
    timeout: 0, //0表示永不超时
    withCredentials: true // 表示请求可以携带cookie   
});

// 3、添加请求拦截器
request.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    return config;
}, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
});

// 4、添加响应拦截器
request.interceptors.response.use(function (response) {
    // 2xx 范围内的状态码都会触发该函数。
    // 对响应数据做点什么
    if (response.status == 200) {
        return response.data;
    }
    else {
        alert("操作失败:" + response.data.message);
        return null;
    }
}, function (error) {
    // 超出 2xx 范围的状态码都会触发该函数。
    // 对响应错误做点什么
    return Promise.reject(error);
});

// 5、导出axios实例
export default request

5.2 创建 API 服务类

在实际项目中,为各个模块创建各自的 API 服务类,用于对接后端服务提供的 API 接口。

在项目 src 目录下,创建 API 目录,并在该目录下创建 UserApi.js 类:

javascript 复制代码
import request from '@/utils/request.js';

//获取用户信息
export function getUserInfo(userId) {
    return request({
        method: 'GET',
        url: `/user/getUserInfo/${userId}`
    });
}

//新增用户信息
export function saveUserInfo(userInfo) {
    return request({
        url: '/user/saveUserInfo',
        method: 'POST',
        data: userInfo
    });
}

//修改用户信息
export function updateUserInfo(userInfo) {
    return request({
        url: '/user/updateUserInfo',
        method: 'POST',
        data: userInfo
    });
}

//删除用户信息
export function deleteUserInfo(userId) {
    return request({
        url: `/user/deleteUserInfo/${userId}`,
        method: 'POST'
    });
}

5.3 创建组件并调用API接口

在项目 src 目录下,创建 views/user 目录,并在该目录下创建 UserInfo.vue 组件:

html 复制代码
<template>
    <fieldset>
        <legend>用户信息</legend>
        <p>用户名称:<input type="text" v-model="userInfo.userName" /></p>
        <p>用户年龄:<input type="text" v-model="userInfo.age" /></p>
        <p>用户性别:<input id="male" type="radio" value="男" v-model="userInfo.sex" />
            <label for="male">男</label>
            <input id="female" type="radio" value="女" v-model="userInfo.sex" />
            <label for="female">女</label>
        </p>
        <p>博客信息:<input type="text" v-model="userInfo.blogName" /></p>
        <p>博客地址:<input type="text" v-model="userInfo.blogUrl" /></p>
        <button @click="getUser(1)">查询用户</button>
        <button @click="saveUser">新增用户</button>
        <button @click="updateUser">修改用户</button>
        <button @click="deleteUser">删除用户</button>
    </fieldset>
</template>

<script setup>
//导入所需的API方法
import { getUserInfo, saveUserInfo, updateUserInfo, deleteUserInfo } from '@/api/UserApi.js';
import { ref } from 'vue';

//注意:这里使用 ref(),不要使用 reactive(),否则重新赋值后,响应式状态就缺失了
let userInfo = ref({
    userId: 0
});

//获取用户信息
function getUser(userId) {
    getUserInfo(userId).then(
        function (result) {
            userInfo.value = result;
        }
    );
}

//新增用户信息
function saveUser() {
    saveUserInfo(userInfo.value).then(
        function (response) {
            if (response) {
                alert("操作成功");
            } else {
                alert("操作失败");
            }
        }
    );
}

//修改用户信息
function updateUser() {
    updateUserInfo(userInfo.value).then(
        function (response) {
            if (response) {
                alert("操作成功");
            } else {
                alert("操作失败");
            }
        }
    );
}

//删除用户信息
function deleteUser() {
    deleteUserInfo(userInfo.value.userId).then(
        function (response) {
            if (response) {
                alert("操作成功");
            } else {
                alert("操作失败");
            }
        }
    );
}

</script>

<!-- CSS样式 -->
<style scoped>
input[type="text"] {
    width: 300px;
    padding: 3px;
    font-size: 16px;
}

button {
    margin-right: 10px;
}
</style>

6、综合实例

通过上述 axios 的二次封装,下面通过一个综合实例,来测试应用效果。

**【实例】**使用 axios 的二次封装,通过使用 Ajax 请求,实现用户信息的查询、新增、修改、删除功能。实例执行的结果如下图:

使用 Java、SpringBoot 创建一个后端项目,编写 UserController.java 用户信息控制器,实现 API 接口。

java 复制代码
package com.pjb.pm.controller;

import com.pjb.pm.entity.UserInfo;
import org.springframework.web.bind.annotation.*;

/**
 * 用户信息控制器
 * @author pan_junbiao
 **/
@RestController
@RequestMapping("/user")
//@CrossOrigin //解决跨域问题
public class UserController
{
    /**
     * 获取用户信息
     */
    @RequestMapping(value = "/getUserInfo/{id}", method = RequestMethod.GET)
    public UserInfo getUserInfo(@PathVariable("id") Long userId)
    {
        //模拟用户查询功能
        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(userId);
        userInfo.setUserName("pan_junbiao的博客");
        userInfo.setSex("男");
        userInfo.setAge(36);
        userInfo.setBlogName("您好,欢迎访问 pan_junbiao的博客");
        userInfo.setBlogUrl("https://blog.csdn.net/pan_junbiao");
        return userInfo;
    }

    /**
     * 新增用户信息
     */
    @RequestMapping(value = "/saveUserInfo", method = RequestMethod.POST)
    public boolean saveUserInfo(@RequestBody UserInfo userInfo)
    {
        if (userInfo == null || userInfo.getUserName() == null || userInfo.getUserName().length() == 0)
        {
            return false;
        }
        //忽略相关代码...
        return true;
    }

    /**
     * 修改用户信息
     */
    @RequestMapping(value = "/updateUserInfo", method = RequestMethod.POST)
    public boolean updateUserInfo(@RequestBody UserInfo userInfo)
    {
        if (userInfo.getUserId() <= 0)
        {
            return false;
        }
        //忽略相关代码...
        return true;
    }

    /**
     * 删除用户信息
     */
    @RequestMapping(value = "/deleteUserInfo/{id}", method = RequestMethod.POST)
    public boolean deleteUserInfo(@PathVariable("id") Long userId)
    {
        if (userId == 0)
        {
            return false;
        }
        //忽略相关代码...
        return true;
    }
}

执行结果:

(1) 查询用户信息:

(2)新增、修改、删除用户信息:

相关推荐
桂月二二4 小时前
探索前端开发中的 Web Vitals —— 提升用户体验的关键技术
前端·ux
CodeClimb5 小时前
【华为OD-E卷 - 第k个排列 100分(python、java、c++、js、c)】
java·javascript·c++·python·华为od
沈梦研5 小时前
【Vscode】Vscode不能执行vue脚本的原因及解决方法
ide·vue.js·vscode
hunter2062065 小时前
ubuntu向一个pc主机通过web发送数据,pc端通过工具直接查看收到的数据
linux·前端·ubuntu
qzhqbb5 小时前
web服务器 网站部署的架构
服务器·前端·架构
刻刻帝的海角5 小时前
CSS 颜色
前端·css
轻口味6 小时前
Vue.js 组件之间的通信模式
vue.js
浪浪山小白兔6 小时前
HTML5 新表单属性详解
前端·html·html5
lee5767 小时前
npm run dev 时直接打开Chrome浏览器
前端·chrome·npm
2401_897579657 小时前
AI赋能Flutter开发:ScriptEcho助你高效构建跨端应用
前端·人工智能·flutter