【前端之Vue3数据交互axios】

预讲知识介绍

学习axios前,先了解什么是promise;因为axios中用到的是Promise的一套解决方案和语法,而promise是解决回调函数处理问题的

普通函数和回调函数区别演示

普通函数: 正常调用的函数,一般函数执行完毕后才会继续执行下一行代码

回调函数: 一些特殊的函数,表示未来才会执行的一些功能,后续代码不会等待该函数执行完毕就开始执行了

如下test.html中代码演示二者区别:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>普通函数和回调函数</title>
    <script>
        function general() {
            console.log("普通函数:普通函数是正常调用的函数,一般函数执行完毕后才会继续执行下一行代码")
        }
        //普通函数调用
        general();
        console.log("普通函数代码后的代码")
        console.log("-------------分割线--------------")

        // 设置一个2000毫秒后会执行一次的定时任务
        function callBack() {
            setTimeout(function () {
                console.log("回调函数:表示未来才会执行的一些功能,后续代码不会等待该函数执行完毕就开始执行了")
            }, 2000)
        }
        //回调函数调用
        callBack();
        console.log("回调函数代码后的代码")
    </script>


</head>

<body>

</body>

</html>

控制台输出结果:
在这里插入图片描述

Promise 简介

ES6规定:Promise对象是一个构造函数,用来生成Promise实例

Promise 是异步编程的一种解决方案,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果
从语法上说Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

(1)Promise 对象代表一个异步操作,有三种状态

  • Pending进行中)、
  • Resolved已完成,又称 Fulfilled)、
  • Rejected已失败)。

只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。

(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。

Promise对象的状态改变,只有两种可能:
Pending变为Resolved
Pending变为Rejected
只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。

promise.then方法会等promise对象状态发生改变后才会执行
.catch方法是跟在`.then方法后面,用于指定发生错误时的回调函数。
具体参考下述代码

Promise 基本用法

如下promise.html中代码演示:
分别执行图片中resolve()方法、reject()方法、和发生异常代码来演示3种情况:
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Promise</title>
</head>
<script>
    /*
    Promise对象有以下两个特点。
    (1)Promise对象代表一个异步操作,有三种状态:
    `Pending`(进行中)、`Resolved`(已完成,又称 Fulfilled)和`Rejected`(已失败)。
    只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
    这也是`Promise`这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。

    (2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。
    Promise对象的状态改变,只有两种可能:从`Pending`变为`Resolved`和从`Pending`变为`Rejected`。
    只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。
    */
    // resolve 函数,在回调函数中如果调用了resolve方法,promise会由pending状态转换为resolved状态
    // reject 函数,在回调函数中如果调用了reject方法,promise会由pending状态转换为rejected状态

    let promise = new Promise(function (resolve, reject) {
        console.log("代码顺序1:回调函数promise");
        // resolve("success");
        // reject("fail");
        // throw new Error("发生了异常信息。。。");
    });

    console.log("代码顺序2:不会等promise状态发生改变就会执行:other code1");

    //promise.then方法会等promise对象状态发生改变后才会执行
    promise
        .then(function (result) {
            console.log("代码顺序3:promise转换为resolved状态时才会执行的函数:" + result);
        })
        .catch(function (result) {
            //promise状态为rejected或promise出现异常时才会执行的函数;
            console.log("代码顺序4:ppromise状态为rejected或promise出现异常时才会执行的函数:" + result);
        });
    console.log("代码顺序5:不会等promise状态发生改变就会执行:other code2");
</script>

</html>

控制台输出结果:
情景1:resolve()方法在这里插入图片描述
情景2:reject()方法在这里插入图片描述
情景3:异常在这里插入图片描述

async 和 await 的使用

async 和 await 的简介及特点

asyncawait是ES6中用于处理异步操作的新特性。
通常,异步操作会涉及到Promise对象,而async/await则是在Promise基础上提供了更加直观和易于使用的语法。

async:用于标识函数

  • async标识函数后,async函数的返回值会变成一个promise对象
  • 如果函数内部返回的数据是一个非promise对象,async函数的结果会返回一个成功状态 promise对象
  • 如果函数内部返回的是一个promise对象,则async函数返回的状态与结果由该对象决定
  • 如果函数内部抛出的是一个异常,则async函数返回的是一个失败的promise对象

await

  • await右侧的表达式一般为一个promise对象,但是也可以是一个其他值
  • 如果表达式是其他值,则直接返回该值
  • 如果表达式是promise对象,await返回的是promise成功的值
  • await会等右边的promise对象执行结束,然后再获取结果,后续代码也会等待await的执行
  • await必须在async函数中,但是async函数中可以没有await
  • 如果await右边的promise失败了,就会抛出异常,需要通过 try ... catch捕获处理

async 用法代码演示

async 代码演示图片中4种场景:
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>async</title>
  </head>
  <script>
    /*
    async和await是ES6中用于处理异步操作的新特性。
    通常,异步操作会涉及到Promise对象,而async/await则是在Promise基础上
    提供了更加直观和易于使用的语法。

    async 用于标识函数的
      1. async标识函数后,async函数的返回值会变成一个promise对象
      2. 如果函数内部返回的数据是一个非promise对象,async函数的结果会返回一个成功状态 promise对象
      3. 如果函数内部返回的是一个promise对象,则async函数返回的状态与结果由该对象决定
      4. 如果函数内部抛出的是一个异常,则async函数返回的是一个失败的promise对象
    */

    async function fun1() {
      //return 10;//成功测试
      // throw new Error("something errors")//异常测试
      // let promise = Promise.resolve(
      //   "resolve方法能快速产生一个【成功】的响应对象!"
      // );
      let promise = Promise.reject(
        "reject方法能快速产生一个【失败】的响应对象!"
      );
      return promise;
    }

    let promise = fun1();

    promise
      .then(function (result) {
        console.log("fun1函数调用成功:" + result);
      })
      .catch(function (result) {
        console.log("fun1函数调用失败或异常:" + result);
      });
  </script>
</html>

控制台输出结果(图片按上述场景顺序):
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

await 用法代码演示

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>await</title>
</head>
<script>
  /*
  async和await是ES6中用于处理异步操作的新特性。
  await
    1. await右侧的表达式一般为一个promise对象,但是也可以是一个其他值
    2. 如果表达式是promise对象,await返回的是promise成功的值
    3. await会等右边的promise对象执行结束,然后再获取结果,后续代码也会等待await的执行
    4. 如果表达式是其他值,则直接返回该值
    5. await必须在async函数中,但是async函数中可以没有await
    6. 如果await右边的promise失败了,就会抛出异常,需要通过 try ... catch捕获处理
  */

  async function fun1() {
    return 10;
    return promise;
  }

  async function fun2() {
    let result = await fun1();      // 返回普通值测试

    // 异常测试,出现异常,后面代码不会执行
    // let result = await Promise.reject("异常测试,出现异常,后面代码不会执行!");
    try {
      // 异常测试,如果出现异常并且想捕获打印异常,可以使用try-chach
      let result = await Promise.reject(" 异常测试,如果出现异常并且想捕获打印异常,可以使用try-chach!");
    } catch (e) {
      console.log(
        "await测试【异常信息】:" + e
      );
    }
    console.log(
      "await测试【无需使用promise.then方法获取成功结果,直接使用await获取promise成功的值】:" +
      result
    );
  }

  //调用fun2函数
  fun2();
</script>

</html>

Axios介绍

前言:

  • AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
  • AJAX 不是新的编程语言,而是一种使用现有标准的新方法。
  • AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
  • AJAX 不需要任何浏览器插件,但需要用户允许 JavaScript 在浏览器上执行。
  • XMLHttpRequest 只是实现 Ajax 的一种方式。

Ajax工作原理
在这里插入图片描述

Axios官网介绍

Axios 是一个基于 promise 网络请求库,作用于node.js浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。
服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests。它有如下特性

  • 从浏览器创建 XMLHttpRequests
  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求和响应数据
  • 取消请求
  • 自动转换JSON数据
  • 客户端支持防御XSRF

Axios 入门案例

案例需求: 请求后台获取随机土味情话

请求地址:https://api.uomg.com/api/rand.qinghua?format=json
请求方式:get
创建项目:npm create vite
下载依赖:npm i
安装 axios:npm install axios
使用axios发送请求获取message,返回一个promise对象
axios设置请求的参数:三要素:

  • ① 请求地址;
  • ② 请求方式;
  • ③ 请求参数:键值对类型json类型

响应数据 data 属性介绍:
response:响应结果对象
data:服务端响应回来的数据
status:响应状态码
statusText:响应状态码描述
headers:本次响应的所有响应头
config:本次请求的配置信息
request:本次请求发送时所使用的XMLHttpRequest对象

App.vue 代码

<script setup>
//引入axios,axios外面不用{}了,否则报错,直接暴露就行了
import axios from "axios";
//导入响应式数据
import { ref, reactive } from "vue";
//方式1
let msg = ref("");
//方式2
let msgObj = reactive({
  code: "",
  content: "",
});

function getLoveMessage() {
  //使用axios发送请求获取message,返回一个promise对象
  //使用axios设置请求的参数:三要素:①请求地址;②请求方式;③请求参数:键值对类型、json类型....
  let promise = axios({
    method: "get",
    url: "https://api.uomg.com/api/rand.qinghua?format=json ",
    data: {
      //无参数,不写
    },
  });
  promise
    .then(function (response) {
      console.log(response);
      /*
      response:响应结果对象
      data:服务端响应回来的数据
      status:响应状态码
      statusText:响应状态码描述
      headers:本次响应的所有响应头
      config:本次请求的配置信息
      request:本次请求发送时所使用的XMLHttpRequest对象
    */
      console.log(response.data);
      console.log(response.data.code);
      console.log(response.data.content);
      // 方式1
      msg.value = response.data.content;
      // 方式2: 响应对象response.data各个key名称和msgObj中的属性名相同,使用Object.assign的方法,让二者属性一一对应
      Object.assign(msgObj, response.data);
    })
    .catch(function (error) {
      console.log(error);
    });
}
</script>

<template>
  <div>
    <!-- 方式1 -->
    方式1(ref):
    <h1 v-text="msg"></h1>
    <hr />
    <!-- 方式2 -->
    方式2(reactive):
    <h1 v-text="msgObj.content"></h1>
    <button @click="getLoveMessage()">Change</button>
  </div>
</template>

<style scoped></style>

结果演示:

Axios 入门案例演示

额外说明:

① 异常测试模拟请求地址错误,打印异常信息

在这里插入图片描述
在这里插入图片描述

② 请求方式get和post对请求参数的影响说明

如果使用 params 写入请求参数:则无论是什么请求方式,请求参数都会以键值对的形式拼接到url后面

  let promise = axios({
    method: "get",
    // method: "post",
    url: "https://api.uomg.com/api/rand.qinghua",
    params: {
      //无论是什么请求方式,请求参数都会以键值对的形式拼接到url后面
      format: "json",
      username: "tom",
    },
  });

在这里插入图片描述
在这里插入图片描述

如果使用 data 写入请求参数:如果请求方式是post,则data中的数据会以JSON形式放在请求体中,
如果是get请求方式,想要参数以键值对形式发送,则需要使用params
否则 get 请求参数无法传入

  let promise = axios({
    method: "post",
    url: "https://api.uomg.com/api/rand.qinghua",
    data: {
      //如果请求方式是get,想要参数以键值对形式发送,则需要使用params,
      //如果请求方式是post,并且使用data,则data中的数据会以JSON形式放在请求体中
      format: "json",
      username: "tom",
    },
  });

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

Axios get和post方法

发送get请求的方法

  • axios.get(url)

例如:axios.get("https://api.uomg.com/api/rand.qinghua?format=json")

  • axios.get(url,{请求的其他信息})
  • axios.get(url,{params:{键值对参数},header:{设置一些特殊的请求头}})
  • axios.post(url,{要放入请求体中的JSON串},{请求的其他信息})

或者:

  axios.get("https://api.uomg.com/api/rand.qinghua", {
    params: {
      format: "json",
      username: "tom",
      age: 18,
    },
    headers:{
      Accept:"application/json, text/plain, text/html, */*"
    }
  });

发送post请求的方法
例如: return axios.post("https://api.uomg.com/api/rand.qinghua?format=json");

或者:

  axios.post("https://api.uomg.com/api/rand.qinghua",
    {
      format: "json",
      username: "tom",
    },
    {
      params: {
        age: 18,
      },
      headers:{
        Accept:"application/json, text/plain, text/html, */*"
      }
    }
  );

简化上述案例代码: App.vue 代码

<script setup>
//引入axios,axios外面不用{}了,否则报错,直接暴露就行了
import axios from "axios";
//导入响应式数据
import { ref, reactive } from "vue";
//方式1
let msg = ref("");
//方式2
let msgObj = reactive({
  code: "",
  content: "",
});

function getLoveWords() {

  //发送get请求的方法
  // axios.get(url)
  // axios.get(url,{请求的其他信息})
  // axios.get(url,{params:{键值对参数},header:{设置一些特殊的请求头}})
  // axios.post(url,{要放入请求体中的JSON串},{请求的其他信息})
  // return axios.get("https://api.uomg.com/api/rand.qinghua?format=json");

  // return axios.get("https://api.uomg.com/api/rand.qinghua", {
  //   params: {
  //     format: "json",
  //     username: "tom",
  //     age: 18,
  //   },
  //   headers:{
  //     Accept:"application/json, text/plain, text/html, */*"
  //   }
  // });
  //------------------------------------------------------------
  // return axios.post("https://api.uomg.com/api/rand.qinghua",
  //   {
  //     format: "json",
  //     username: "tom",
  //   },
  //   {
  //     params: {
  //       age: 18,
  //     },
  //     headers:{
  //       Accept:"application/json, text/plain, text/html, */*"
  //     }
  //   }
  // );
  //------------------------------------------------------------
  //如果什么都不需要设置, 直接写成如下就行
  return axios.post("https://api.uomg.com/api/rand.qinghua?format=json");
}



async function getLoveMessage() {
  // let response = await getLoveWords();
  // Object.assign(msgObj, response.data);
  //可以直接用结构表达式直接接收response中的属性
  let { data } = await getLoveWords();
  msg.value = data.content;
  Object.assign(msgObj, data);
}


</script>

<template>
  <div>
    <!-- 方式1 -->
    方式1(ref):
    <h1 v-text="msg"></h1>
    <hr />
    <!-- 方式2 -->
    方式2(reactive):
    <h1 v-text="msgObj.content"></h1>
    <button @click="getLoveMessage()">Change</button>
  </div>
</template>

<style scoped></style>

在这里插入图片描述
在这里插入图片描述

Axios 拦截器

创建一个 axios.js 文件,里面设置好拦截器,然后在 App.vue 中引入 axios.js 文件
注意:拦截器中发生异常一定要返回一个promise对象,给 App.vue 方法中的调用者
在这里插入图片描述
在这里插入图片描述

App.vue 代码

<script setup>
//引入自己的axios.js
import axios from "./axios.js";
//导入响应式数据
import { ref, reactive } from "vue";
//方式1
let msg = ref("");
//方式2
let msgObj = reactive({
  code: "",
  content: "",
});

function getLoveWords() {
  //发送post请求的方法,如果什么都不需要设置, 直接写成如下就行
  let promise = axios.post("api/rand.qinghua?format=json");
  return promise;
}

async function getLoveMessage() {
  //可以直接用结构表达式直接接收response中的属性
  let { data } = await getLoveWords();
  msg.value = data.content;
  Object.assign(msgObj, data);
}
</script>

<template>
  <div>
    <!-- 方式1 -->
    方式1(ref):
    <h1 v-text="msg"></h1>
    <hr />
    <!-- 方式2 -->
    方式2(reactive):
    <h1 v-text="msgObj.content"></h1>
    <button @click="getLoveMessage()">Change</button>
  </div>
</template>

<style scoped></style>

axios.js 代码

//导入axios依赖
import axios from "axios";
//使用axios函数创建一个可以发送请求的示例对象
const instance = axios.create({
  baseURL: "https://api.uomg.com/", //请求的基础路径
  //   timeout: 10000, //超时时间
});

// 添加请求拦截器 请求发送之前
instance.interceptors.request.use(
  function (config) {
    console.log("请求拦截器");
    //请求之前设置请求信息的方法
    config.headers.Accept = "application/json, text/plain, text/html, */*";
    // 在发送请求之前做些什么
    //设置完后,必须返回config
    return config;
  },
  function (error) {
    console.log("请求前拦截器异常方法");
    // 对请求错误做些什么,返回一个失败状态的promise,返回给App.vue中getLoveWords方法中的请求
    return Promise.reject(error);
  }
);

// 添加响应拦截器 数据响应回来
instance.interceptors.response.use(
  function (response) {
    // 2xx 范围内的状态码都会触发该函数。
    // 对响应数据做点什么
    console.log("响应拦截器!" + response.data.content);
    console.log(response);
    return response;
  },
  function (error) {
    // 超出 2xx 范围的状态码都会触发该函数。
    // 对响应错误做点什么
    console.log("响应拦截器异常方法!");
    //最后一定要响应一个promise
    return Promise.reject(error);
  }
);

//使用默认导出暴露instance
export default instance;

在这里插入图片描述

模拟异常场景:
在这里插入图片描述在这里插入图片描述

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值