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 的简介及特点
async
和await
是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
是一个基于 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;
模拟异常场景: