Vue学习笔记(三) —— 前后端交互

简介

本文主要是为了介绍前端交互的相关知识,而严格来讲,这也不算是Vue的专属知识,但是却是必须要指定的。本文开始简单说了ajaxjquery 的方式,但是随着SPA开发模式的大火,相继出现了一些新的交互方式,而我们应该对这些知识有所了解。此文可以作为后端工程师了解前端交互的入门,对于想要转纯前端的同学应该也有一定的帮助作用。

有兴趣的朋友可以看看之前的两篇文章:

  • Vue学习笔记(一)—— 常用特性
  • Vue学习笔记(二)—— 组件开发

1、前后端交互模式

1.1 接口调用方式

  • 原生ajax
  • 基于jQueryajax (主要是基于 dom 的操作)
  • fetch
  • axios

1.2 URL地址格式

1、 传统形式的URL

  • 格式:schema://host:port/path?query#fragment

    • schema :协议。例如httphttpsftp
    • host : 域名或IP地址
    • port : 端口,http默认端口80,可以省略
    • path : 路径,例如/abc/a/b/c
    • query : 查询参数,例如uname=lisi&age=12
    • fragment : 锚点(哈希hash),用于定位页面的某个位置

一个最简单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地址

    • http://www.test.com/books             GET
    • http://www.test.com/books             POST
    • http://www.test.com/books/123     PUT
    • http://www.test.com/books/123     DELETE

可以看到,有的地址是一样的, 但是它们的提交方式不同。

2. Promise 用法

写在前面

Promise是ES6中引入的一种新的语法,专门用来处理异步编程。

可以通过一个简单的方式来查看Promise的对象情况。如下先定义一个html文件。


<html lang="en">
<head>
    
head>
<body>
    <script>
        console.dir(Promise)
    script>
body>
html>

在浏览器中打开上面的html文件,然后F12来查看,如下图所示。
Vue学习笔记(三) —— 前后端交互_第1张图片

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对象,构造函数中传递函数,该函数中用于处理异步任务

  • resolvereject两个参数用于处理成功和失败两种情况,并通过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);
})

结果如下图所示
Vue学习笔记(三) —— 前后端交互_第2张图片

  • 第二种用法,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);
})

结果如下图所示
Vue学习笔记(三) —— 前后端交互_第3张图片

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);
})

PUTPOST 一样,都可以使用两种方式来处理请求。

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.jsHTTP客户端。

主要有以下特性:

  • 支持浏览器和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

URLSearchParamsaxios提供的标准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/awaitES7引入的新语法,可以更加方便的进行异步操作
  • async关键字用于函数上(async函数的返回值是Promise实例对象)
  • await关键字用于async函数当中(await可以得到异步的结果)
async function queryData(id) {
    const ret = await axios.get('/data');
    return ret;
}

queryData.then(ret => {
    console.log(ret)
})

通过asyncawait关键字,可以使代码更简洁,因为不需要使用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开发所必须的知识,同时还方便以后的再次学习。下一篇将介绍的是路由的相关知识,有兴趣可以看看。

你可能感兴趣的:(管理/方法/理论,web前端)