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

简介

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

有兴趣的朋友能够看看以前的两篇文章:html

一、先后端交互模式

1.1 接口调用方式

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

1.2 URL地址格式

一、 传统形式的URL前端

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

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

一个最简单URL地址必须包含:协议域名端口。端口是能够省略的。node

  • 符合规则的URLjquery

    • 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

二、Restful形式的URLios

  • HTTP请求方式git

    • GET     查询
    • POST     添加
    • PUT      修改
    • DELETE   删除
  • 符合规则的URL地址github

    • 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

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

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

  • resolvereject两个参数用于处理成功和失败两种状况,并经过p.then获取处理结果

语法以下:

var p = new Promise(function(resolve,reject){
    // 成功时调用 resolve()
    // 失败时调用 reject()
});

p.then(function(ret){
    // 从resolve获得正常结果
},function(ret){
    // 从reject获得错误信息
});

2.4 基于Promise 处理Ajax请求

一、处理原生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)
    })

二、发送屡次Ajax请求

queryData()
    .then(function(data){
        return queryData();
    })
    .then(function(data){
        return queryData();
    })
    .then(function(data){
        return queryData();
    });

经过多个then的方式,悠雅的解决了ajax的回调地狱问题。

2.5 then参数中的函数返回值

一、返回Promise实例对象

  • 返回的该实例对象会调用下一个then

二、返回普通值

  • 返回的普通值会直接传递给下一个then,经过then参数中函数的参数接收该值

2.6 Promise 经常使用的 API

一、实例方法

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

二、对象方法

  • Promise.all() 并发处理多个异步任务,全部任务都执行完成才能获得结果
  • Promise.race() 并发处理多个异步任务,只要有一个任务完成就能获得结果

大致的语法以下:

Promise.all([p1,p2,p3]).then((result) => {
    console.log(result)
})

Promise.race([p1,p2,p3]).then((result) => {
    console.log(result)
})

三、接口调用 - fecth用法

3.1 fecth 概述

一、基本特征

  • 更加简单的数据获取方式,功能更强大、更灵活,能够看作是xhr(传统的ajax)的升级版

  • 基于Promise实现

二、语法结构

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 请求参数

一、经常使用配置选项

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

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

三、DELETE请求方法的参数传递

fetch('/abc/123',{
    method: 'DELETE'
}).then(data => {
    return data.text();
}).then(ret => {
    // 注意这里获得的才是最终的数据
    console.log(ret);
})

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

结果以下图所示
在这里插入图片描述

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

四、接口调用 - 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的参数传递

一、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)
})

二、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)
})

三、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)
})

四、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 拦截器

一、请求拦截器

在请求发出以前设置一些信息,代码以下:

// 添加一个请求拦截器
axios.interceptors.request.use(function (config) {
    // 在请求发出以前进行一些消息设置
    return config;
},function(err) {
    // 处理响应的错误消息
});

二、响应拦截器

在获取数据以前对数据作一些加工处理,代码以下:

// 添加一个响应拦截器
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开发所必须的知识,同时还方便之后的再次学习。下一篇将介绍的是路由的相关知识,有兴趣能够看看。