简介
本文主要是为了介绍前端交互的相关知识,而严格来讲,这也不算是
Vue
的专属知识,但是却是必须要指定的。本文开始简单说了
ajax
、
jquery
的方式,但是随着
SPA
开发模式的大火,相继出现了一些新的交互方式,而我们应该对这些知识有所了解。此文可以作为后端工程师了解前端交互的入门,对于想要转纯前端的同学应该也有一定的帮助作用。
有兴趣的朋友可以看看之前的两篇文章:
- Vue学习笔记(一)—— 常用特性
- Vue学习笔记(二)—— 组件开发
1、前后端交互模式
1.1 接口调用方式
- 原生
ajax
- 基于
的jQuery
(主要是基于ajax
的操作)dom
-
fetch
-
axios
1.2 URL地址格式
1、 传统形式的URL
- 格式:schema://host:port/path?query#fragment
- schema :协议。例如
、http
、https
等ftp
- host : 域名或
地址IP
- port : 端口,
默认端口http
,可以省略80
- path : 路径,例如
/abc/a/b/c
- query : 查询参数,例如
uname=lisi&age=12
- fragment : 锚点(哈希
),用于定位页面的某个位置hash
- schema :协议。例如
一个最简单 URL
地址必须包含:协议、域名和端口。端口是可以省略的。
- 符合规则的
URL
-
http://www.baidu.com
-
http://www.baidu.com/java/web
-
http://www.baidu.com/java/web?flag=1
-
http://www.baidu.com/java/web?flag=1#function
-
2、Restful形式的URL
-
请求方式HTTP
- GET 查询
- POST 添加
- PUT 修改
- DELETE 删除
- 符合规则的URL地址
-
GEThttp://www.test.com/books
-
POSThttp://www.test.com/books
-
PUThttp://www.test.com/books/123
-
DELETEhttp://www.test.com/books/123
-
可以看到,有的地址是一样的, 但是它们的提交方式不同。
2. Promise 用法
写在前面
Promise
是ES6中引入的一种新的语法,专门用来处理异步编程。
可以通过一个简单的方式来查看
Promise
的对象情况。如下先定义一个
html
文件。
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<script>
console.dir(Promise)
</script>
</body>
</html>
在浏览器中打开上面的
html
文件,然后
F12
来查看,如下图所示。
2.1 异步调用
- 异步效果分析
- 定时任务
- Ajax
- 事件函数
- 多次异步调用的依赖分析
- 多次异步调用的结果顺序不确定
- 异步调用结果如果存在依赖需要嵌套
关于异步依赖需要嵌套,可参考以下代码:
$ajax({
success: function(data){
if(data.status ==200){
$ajax({
success: function(data){
if(data.status ==200){
$ajax({
success: function(data){
if(data.status == 200){
// ....
}
}
});
}
}
});
}
}
});
如果需要嵌套18层,那就是地狱了。所以这种写法也叫“回调地狱”。为了解决这个问题,所以引入了 Promise
。
2.2 Promise 概述
Promise
是异步编程的一种解决方案,从语法上讲,
Promise
是一个对象,其实它也是一个函数,从它可以获取异步操作的消息。
使用
Promise
主要有以下好处:
- 可以避免多层异步调用嵌套问题(回调地狱)
-
对象提供了简介的Promise
,使得控制异步操作更加容易API
了解更多内容,可到 此处 查看。
2.3 Promise 基本用法
- 实例化
对象,构造函数中传递函数,该函数中用于处理异步任务Promise
-
和resolve
两个参数用于处理成功和失败两种情况,并通过reject
获取处理结果p.then
语法如下:
var p = new Promise(function(resolve,reject){
// 成功时调用 resolve()
// 失败时调用 reject()
});
p.then(function(ret){
// 从resolve得到正常结果
},function(ret){
// 从reject得到错误信息
});
2.4 基于Promise 处理Ajax请求
1、处理原生Ajax
function queryData(){
return new Promise(function(resolve,reject){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState != 4){
return;
}
if(xhr.readyState == 4 && xhr.status == 200){
resolve(xhr.responseText);
} else {
reject('出错了');
}
}
xhr.open('get','/data');
xhr.send(null);
});
return p;
}
// 调用
queryData('http://localhost:3000/data')
.then(function(data){
console.log(data);
},function(data){
console.log(data)
})
2、发送多次Ajax请求
queryData()
.then(function(data){
return queryData();
})
.then(function(data){
return queryData();
})
.then(function(data){
return queryData();
});
通过多个的方式,悠雅的解决了
then
的回调地狱问题。
ajax
2.5 then参数中的函数返回值
1、返回
Promise
实例对象
- 返回的该实例对象会调用下一个
then
2、返回普通值
- 返回的普通值会直接传递给下一个
,通过then
参数中函数的参数接收该值then
2.6 Promise 常用的 API
1、实例方法
-
得到异步任务的正确结果p.then()
-
获取异常信息p.catch()
-
成功与否都会执行(尚且不是正式标准,也许你看到本文时已经是了)p.finally()
演示代码如下
queryData()
.then(function(data){
// 这里处理的是resolve方法
// 如果添加第二个函数,处理的是reject方法
console.log(data);
})
.catch(function(data){
// 这里处理的是 reject 方法
// 所以catch 相当于then 的第二个参数,这种说法不可取,但是可以这里理解
console.log(data);
})
.finally(function(){
console.log('finished');
});
2、对象方法
-
并发处理多个异步任务,所有任务都执行完成才能得到结果Promise.all()
-
并发处理多个异步任务,只要有一个任务完成就能得到结果Promise.race()
大体的语法如下:
Promise.all([p1,p2,p3]).then((result) => {
console.log(result)
})
Promise.race([p1,p2,p3]).then((result) => {
console.log(result)
})
3、接口调用 - fecth用法
3.1 fecth 概述
1、基本特征
- 更加简单的数据获取方式,功能更强大、更灵活,可以看做是
(传统的xhr
)的升级版ajax
- 基于
实现Promise
2、语法结构
fetch(url).then(fn2)
.then(fn3)
...
.catch(fn)
具体内容可以查看官网API。
3.2 fecth 的基本用法
fetch('/abc').then(data => {
// text() 方法是fetch API的一部分,返回一个Promise对象,用于获取后台返回的数据
return data.text();
}).then(ret => {
// 注意这里得到的才是最终的数据
console.log(ret)
})
3.3 fecth 请求参数
1、常用配置选项
- method(String):
请求方法,默认为HTTP
(GET
)GET、POST、PUT、DELETE
- body(String):
的请求参数HTTP
- headers(Object):
的请求头,默认为HTTP
{}
代码的风格如下:
fetch('/abc',{
method: 'GET'
}).then(data => {
return data.text();
}).then(ret => {
// 注意这里得到的才是最终的数据
console.log(ret);
})
2、GET请求方法的参数传递
- 传统的参数传递
fetch('/abc?id=123').then(data => {
return data.text();
}).then(ret => {
// 注意这里得到的才是最终的数据
console.log(ret);
})
- RESTFUL风格的参数传递
fetch('/abc/123',{
method: 'GET'
}).then(data => {
return data.text();
}).then(ret => {
// 注意这里得到的才是最终的数据
console.log(ret);
})
3、DELETE请求方法的参数传递
fetch('/abc/123',{
method: 'DELETE'
}).then(data => {
return data.text();
}).then(ret => {
// 注意这里得到的才是最终的数据
console.log(ret);
})
4、POST请求方法的参数传递
- 第一种用法,
查询字符串query
fetch('/books',{
method: 'POST',
body:'uname=lisi&pwd=123',
headers: {
'Context-Type':'application/x-www-form-urlencoded',
}
}).then(data => {
return data.text();
}).then(ret => {
// 注意这里得到的才是最终的数据
console.log(ret);
})
结果如下图所示
- 第二种用法,
格式json
fetch('/books',{
method: 'POST',
body: Json.stringify({
'uname': 'lisi",
'pwd': '123'
}),
headers: {
'Context-Type':'application/json',
}
}).then(data => {
return data.text();
}).then(ret => {
// 注意这里得到的才是最终的数据
console.log(ret);
})
结果如下图所示
5、PUT请求方法的参数传递
// 和post的用法基本一样,这里需要传递修改数据的id
fetch('/books/123',{
method: 'POST',
body: Json.stringify({
'uname': 'lisi",
'age': 23
}),
headers: {
'Context-Type':'application/json',
}
}).then(data => {
return data.text();
}).then(ret => {
// 注意这里得到的才是最终的数据
console.log(ret);
})
PUT 和 POST 一样,都可以使用两种方式来处理请求。
3.4 fecth 响应结果
响应数据格式
- text():将返回体处理成字符串类型
- json():返回结果和
一样JSON.parse(responseText)
fetch('/abc').then(data => {
// return data.text();
return data.json();
}).then(ret => {
// 注意这里得到的才是最终的数据
console.log(ret);
})
// 和下面的效果相同
fetch('/abc').then(data => {
return data.text();
}).then(ret => {
// 注意这里得到的才是最终的数据
var obj = JSON.parse(ret)
console.log(obj);
})
4、接口调用 - axios用法
4.1 axios 的基本特性
axios(官网:https://github.com/axios/axios)是一个基于
Promise
用于浏览器和
node.js
的
HTTP
客户端。
主要有以下特性:
- 支持浏览器和
node.js
- 支持
(Promise
的语法都可以直接使用)Promise
- 能拦截请求和相应
- 自动转换
数据JSON
4.2 axios 的基本用法
基本形式如下:
axios.get('/adata')
.then(ret => {
// data属性名称是固定的,用于获取后台相应的数据
console.log(ret.data)
})
4.3 axios 的常用API
-
查询数据GET
-
添加数据POST
-
修改数据PUT
-
删除数据DELETE
4.4 axios的参数传递
1、GET传递参数
- 通过
传递参数URL
// 传统传参
axios.get('/adata?id=123')
.then(ret => {
console.log(ret.data)
})
// Restful形式传承
axios.get('/adata/123')
.then(ret => {
console.log(ret.data)
})
- 通过
选项传递参数params
// params 参数是axios专门提供的
// 比较推荐这种方式
axios.get('/adata',{
params: {
id:123
}
}).then(ret => {
console.log(ret.data)
})
2、DELETE传递参数
- 参数传递方式和
类似GET
// 传统传参
axios.delete('/adata?id=123')
.then(ret => {
console.log(ret.data)
})
// Restful形式传承
axios.delete('/adata/123')
.then(ret => {
console.log(ret.data)
})
// params 参数传参
axios.delete('/adata',{
params: {
id:123
}
}).then(ret => {
console.log(ret.data)
})
3、POST传递参数
- 通过选项传递参数(
)默认传递的是json格式的数据
axios.post('/adata',{
uname:'tom',
pwd:123
}).then(ret => {
console.log(ret.data)
})
- 通过
传递参数(URLSearchParams
)application/x-www-form-urlencoded
是
URLSearchParams
提供的标准
axios
API
const params = new URLSearchParams();
params.append('param1','value1');
params.append('param2','value2');
axios.post('/api/test',params).then(ret => {
console.log(ret.data)
})
4、PUT传递参数
- 参数传递方式和
类似POST
axios.put('/adata/123',{
uname: 'tom',
pwd: 123
}).then(ret => {
console.log(ret.data)
})
4.5 axios 的响应结果
响应结果的主要属性
-
:实际响应回来的数据data
-
:响应头信息headers
-
:响应状态码status
-
:响应状态信息statusText
axios.post('/axios-json').then(ret => {
console.log(ret)
})
4.6 axios 的全局配置
-
// 超时时间axios.defaults.timeout = 3000;
-
// 默认地址axios.defaults.baseURL = 'http://localhost:3000/app';
-
// 设置请求头axios.defaults.header['mytoken'] = 'ogerindxq345348usdgq34498tu';
4.7 axios 拦截器
1、请求拦截器
在请求发出之前设置一些信息,代码如下:
// 添加一个请求拦截器
axios.interceptors.request.use(function (config) {
// 在请求发出之前进行一些消息设置
return config;
},function(err) {
// 处理响应的错误消息
});
2、响应拦截器
在获取数据之前对数据做一些加工处理,代码如下:
// 添加一个响应拦截器
axios.interceptors.response.use(function (res) {
// 在这里对返回的数据机进行处理
// res不是实际的数据对象,通过res.data获得实际数据
return res;
},function(err) {
// 处理响应的错误消息
});
接口调用 - async/await 用法
5.1 async/await 的基本用法
- async/await是
引入的新语法,可以更加方便的进行异步操作ES7
- async关键字用于函数上(
函数的返回值是async
实例对象)Promise
- await关键字用于async函数当中(
可以得到异步的结果)await
async function queryData(id) {
const ret = await axios.get('/data');
return ret;
}
queryData.then(ret => {
console.log(ret)
})
通过和
async
关键字,可以使代码更简洁,因为不需要使用
await
函数。另外,
then
返回
async
对象,可以使用
Promise
继续处理,如上面的参考代码所示。
then
5.2 async/await 处理多个步请求
多个异步请求的场景
async function queryData(id) {
const info = await axios.get('/async1');
const ret = await axios.get('async2?info=' + info.data);
return ret;
}
queryData.then(ret => {
console.log(ret)
})
总结
以上就是关于前端交互的基本知识总结。算是系统学习前端交互知识的一次总结,也是当前
SPA
开发所必须的知识,同时还方便以后的再次学习。下一篇将介绍的是路由的相关知识,有兴趣可以看看。