05 . Vue前端交互,fetch,axios,以asyncawait方式調用接口使用及案例

目標javascript

/*
		1. 說出什麼是先後端交互模式
		2. 說出Promise的相關概念和用法
		3. 使用fetch進行接口調用
		4. 使用axios進行接口調用
		5. 使用asynnc/await方式調用接口
		6. 基於後臺接口實現案例
*/

先後端交互模式

接口調用方式
/*
		原生ajax
		基於jQuery的ajax
		fetch
		axios
*/
傳統形式的URL
/*
		格式: schema://host:port/path?query#fragment
		
				1. schema: 協議. 例如http,https,ftp等
				2. host:  域名或者IP地址
				3. port:  端口,http默認端口80,能夠省略
				4. path:  路徑,例如/abc/a/b/c
				5. query:  查詢參數uname=list&age=12
				6. fragment: 錨點(哈希Hash),用於定位頁面某個位置
*/
Restful形式的URL
/*
			HTTP請求方式
					1. GET		查詢
					2. POST		添加
					3. PUT		修改
					4. DELETE 刪除
*/

Promise

傳統js異步調用

異步調用分析html

/*
		1. 定時任務
		2. Ajax
		3. 事件函數
*/

屢次異步調用的依賴分析vue

/*
		屢次異步調用的結果順序不肯定
		異步調用結果若是存在依賴須要嵌套
*/

Example(傳統ajax)java

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

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>

<body>
<div id="app">

</div>

<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el: '#app',
        data: {},
        methods: {}
    })
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<div>先後端交互</div>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript">
    /*
        先後端交互,異步編程與Promise概述
     */

    var ret = '---'

    $.ajax({
        url: 'http://localhost:3000/data',
        success: function (data) {
            ret = data
            console.log(ret)
        }
    });
    console.log(ret)
</script>

</body>
</html>
Promise概述

Promise是異步編程的一種解決方案,從語法上講,Promise是一個對象,從他能夠獲取異步操做的信息.node

Promise好處
/*
		使用Promise主要有如下好處:
			能夠避免多層異步調用嵌套問題(回調地獄)
			Promise對象提供了簡介的API,使得控制異步操做更加容易
*/
Promise使用
/*
		基本用法
    	實例化Promise對象,構造函數中傳遞函數,該函數用於處理異步任務.
    	resolv和reject兩個參數用於處理成功和失敗兩種狀況,並經過p.then獲取處理結果.
*/

var p = new Promise(function(resolve,reject){
  // 成功時調用 resolve()
  // 失敗時調用 reject()
  p.then(function(ret){
    	// 從resolve獲得正常結果
  },function(ret){
      // 從reject獲得錯誤信息
  });
});

Example1jquery

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

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>

<body>
<div id="app">

</div>

<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el: '#app',
        data: {},
        methods: {}
    })
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<div>先後端交互</div>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript">
    /*
        Promise基本使用
     */
    var p = new Promise(function (resolve, reject) {
        // 這裏用於實現異步任務
        setTimeout(function () {
            var flag = false;
            if (flag) {
                // 正常狀況
                resolve('hello');
            } else {
                // 異常狀況
                reject('500');
            }
        }, 100);
    });
    p.then(function (data) {
        console.log(data)
    }, function (info) {
        console.log(info)
    })

</script>

</body>
</html>
處理原生Ajax
function queryData(){
	return new Promise(function(resolve,reject){
		var xhr - new XMLHttpRequest();
		xhr.cnreadystatechange = function(){
			if(xhr.readyState != 4) return;
			if(xhr.status == 200){
				resolve(xhr.responseText)
			}else{
				reject('出錯了');
				}
			}
			xhr.open('get','/data');
			xhr.send(null);
			})
}

處理屢次Ajax請求ios

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

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>

<body>
<div id="app">

</div>

<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el: '#app',
        data: {},
        methods: {}
    })
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<div>先後端交互</div>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript">
    /*
        基於Promise發送Ajax請求
     */
    function queryData(url) {
        var p = 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', url);
            xhr.send(null);
        });
        return p;
    }

    // queryData('http://localhost:3000/data')
    //     .then(function(data){
    //         console.log(data)
    //     },function(info){
    //         console.log(info)
    //     });

    // 發送多個Ajax請求而且保證順序
    queryData('http://localhost:3000/data')
        .then(function (data) {
            console.log(data)
            return queryData('http://localhost:3000/data1');
        })

        .then(function (data) {
            console.log(data);
            return queryData('http://localhost:3000/data2');
        })

        .then(function (data) {
            console.log(data)
        });
</script>

</body>
</html>
then參數中的函數返回值
/*
		1. 返回Promise實例對象
				返回的該實例對象會調用下一個then
				
		2. 返回普通值
				返回的普通值會直接傳遞給下一個then,經過then參數中函數的參數接受該值
*/

Exampleajax

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  
  <script type="text/javascript">
    /*
      then參數中的函數返回值
    */
    function queryData(url) {
      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', url);
        xhr.send(null);
      });
    }
    queryData('http://localhost:3000/data')
      .then(function(data){
        return queryData('http://localhost:3000/data1');
      })
      .then(function(data){
        return new Promise(function(resolve, reject){
          setTimeout(function(){
            resolve(123);
          },1000)
        });
      })
      .then(function(data){
        return 'hello';
      })
      .then(function(data){
        console.log(data)
      })

  </script>
</body>
</html>
Promise經常使用API
/*
		實例方法
			p.then() 獲得異步任務的正確結果
			p.catch() 獲取異常信息
			p.finally()  成功與否都會執行(尚且不是正式標準)
			
		queryData()
			.then(function(data){
				console.log(data);
			})
			
			.catch(function(data){
				console.log(data);
			})
			
			.finally(function(){
				console.log('finished');
			});
*/

Example1chrome

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  
  <script type="text/javascript">
    /*
      Promise經常使用API-實例方法
    */
    // console.dir(Promise);
    function foo() {
      return new Promise(function(resolve, reject){
        setTimeout(function(){
          // resolve(123);
          reject('error');
        }, 100);
      })
    }
    // foo()
    //   .then(function(data){
    //     console.log(data)
    //   })
    //   .catch(function(data){
    //     console.log(data)
    //   })
    //   .finally(function(){
    //     console.log('finished')
    //   });

    // --------------------------
    // 兩種寫法是等效的
    foo()
      .then(function(data){
        console.log(data)
      },function(data){
        console.log(data)
      })
      .finally(function(){
        console.log('finished')
      });
  </script>
</body>
</html>

對象方法npm

/*
		Promise.all()  併發處理多個異步任務,全部任務都執行成功才能獲得結果
		Promise.race()  併發處理多個異步任務,只要有一個任務完成就能獲得結果
*/

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

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

Example

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

<script type="text/javascript">
    /*
      Promise經常使用API-對象方法
    */
    // console.dir(Promise)
    function queryData(url) {
        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', url);
            xhr.send(null);
        });
    }

    var p1 = queryData('http://localhost:3000/a1');
    var p2 = queryData('http://localhost:3000/a2');
    var p3 = queryData('http://localhost:3000/a3');
    // Promise.all([p1,p2,p3]).then(function(result){
    //   console.log(result)
    // })
    Promise.race([p1, p2, p3]).then(function (result) {
        console.log(result)
    })
</script>
</body>
</html>

fetch請求組件

fetch

XMLHttpRequest是一個設計粗糙的API, 配置和調用方式很是混亂,並且基於事件的異步模型寫起來不友好,兼容性很差.

基本特性
/*
		更加簡單的數據獲取方式,功能更強大,更靈活,能夠看作是xhr升級版
		基於Promise實現
*/
基本用法

Example

fetch('/abc').then(data=>{
	return data.text();
}).then(ret=>{
	// 注意這裏獲得的纔是最終的數據
	console.log(ret);
})

Example1

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

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>

<body>
<div id="app">

</div>

<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el: '#app',
        data: {},
        methods: {}
    })
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<script type="text/javascript">
    /*
        Fetch API基本用法
     */
    fetch('http://localhost:3000/fdata').then(function (data) {
        // text() 方法屬於fetchAPI的一部分,他返回一個Promise實例對象,用於獲取後臺返回數據
        return data.text();
    }).then(function (data) {
        // 這裏獲得的纔是最終的數據
        console.log(data);
    })
</script>

</body>
</html>

Example2

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
		<title>Examples</title>
		<meta name="description" content="">
		<meta name="keywords" content="">
		<link href="" rel="stylesheet">

		<script type="text/javascript" src="lib/vue.js"></script>
	</head>
	<body>

		<div id="box">
			<button @click="handleClick()">獲取影片信息</button>
			<ul>
				<li v-for="data in datalist">
					<h3>{{ data.name }}</h3>
					<img :src="data.poster">
				</li>
			</ul>
		</div>

		<script>
			new Vue({
				el: "#box",
				data: {
					datalist: []
				},
				methods: {
					handleClick() {
						fetch("./json/test.json").then(res => res.json()).then(res => {
							console.log(res.data.films)
							this.datalist = res.data.films
						})
					}
				}
			})
		</script>


		<!-- new Vue({
		el: "#box",
		data:{
			datalist:["111","222","333"]
		}
	}) -->
	</body>
</html>
fetch請求參數

經常使用配置選項

/*
		method(String): HTTP請求方法,默認爲GET(GET,POST,PUT,DELETE)
		body(String): HTTP的請求參數
		headers(Object) HTTP的請求頭,默認爲{}
*/

GET請求方式的參數傳遞

fetch('/abc?id=123').then(data=>{
	return data.text();
}).then(ret=>{
	// 注意這裏獲得的纔是最終的數據
	console.log(ret)
})


fetch('/abc/123',{
	method 'get'
}).then(data=>{
	return data.text();
}).then(ret=>{
	// 注意這裏獲得的纔是最終的數據
	console.log(ret);
});

Example1

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

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>

<body>
<div id="app">

</div>

<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
    var vm = new Vue({
        el: '#app',
        data: {},
        methods: {}
    })
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<script type="text/javascript">
    /*
        Fetch API:  調用接口傳遞參數
     */
    // fetch('http://localhost:3000/books?id=123',{
    //     method: 'get'
    // })
    // .then(function (data) {
    //     return data.text();
    // }).then(function (data) {
    //     console.log(data)
    // });

    fetch('http://localhost:3000/books/123',{
        method: 'get'
    })
        .then(function (data) {
            return data.text();
        }).then(function (data) {
        console.log(data)
    });
</script>

</body>
</html>

POST請求方式參數傳遞

fetch('/books',{
	method: 'post',
	body: 'uname=list&pwd=123',
	headers: {
		'Content-Type': 'application/x-www-form-urlencoded',
}
}).then(data=>{
		return data.text();
}).then(ret=>{
		console.log(ret);
})
fetch響應結果

響應數據格式

/*
		text():  將返回體處理成字符串類型
		json():  返回結果和JSON.parse(responseText)同樣
*/

fetch('/abc' then(data=>{
  // return data.text();
  return data.json();
}),then(ret=>{
  console.log(ret);
});

axios請求組件

axios基本特性
/*
		axios是一個基於Promise用於瀏覽器和node.js的HTTP客戶端.
			具備如下特徵:
					支持瀏覽器和node.js
					支持promise
					能攔截請求和響應
					自動轉換JSON數據
*/
axios基本用法
axios.get('/adata')
	.then(ret=>{
		// data屬性名稱是固定的,用於獲取後臺響應的數據
		console.log(ret.data)
})

Example1

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script type="text/javascript">
    axios.get('http://localhost:3000/adata').then(function (ret) {
        // 注意data屬性是固定的用法,用於獲取後臺的實際數據
        console.log(ret.data)
    })
</script>
</body>
</html>
axios的經常使用api

GET傳遞參數

/*
		經過URL傳遞參數
		經過params選項傳遞參數
*/

Exmaple2

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script type="text/javascript">
    // axios.get('http://localhost:3000/axios?id=1234').then(function (ret) {
    //     // 注意data屬性是固定的用法,用於獲取後臺的實際數據
    //     console.log(ret.data)
    // })

    axios.get('http://localhost:3000/adata', {
        params: {
            id: 700
        }
    })
        .then(function (ret) {
            console.log(ret.data)
        })

    // axios.get('http://localhost:3000/axios/1234').then(function (ret) {
    //     // 注意data屬性是固定的用法,用於獲取後臺的實際數據
    //     console.log(ret.data)
    // })
</script>
</body>
</html>

POST傳遞參數

經過選項傳遞參數(默認傳遞的是json格式的數據)

Example1

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script type="text/javascript">
    axios.post('http://localhost:3000/axios', {
      uname: 'lisi',
      pwd: 123
    }).then(function(ret){
      console.log(ret.data)
    })
</script>
</body>
</html>

經過URLSearchParams傳遞參數(application/x-www-form-urlencoded)

Example2

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script type="text/javascript">
    var params = new URLSearchParams();
    params.append('uname','youmen');
    params.append('pwd','123');
    axios.post('http://localhost:3000/axios',params).then(function(ret) {
        console.log(ret.data)
    })
</script>
</body>
</html>
axios的響應結果
/*
		data: 實際響應回來的數據
		header: 響應頭信息
		status: 響應狀態碼
		statusText: 響應狀態信息
*/

Example1

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script type="text/javascript">
    /*
        axios 響應式結果與全局配置
     */
    axios.get('http://localhost:3000/axios-json').then(function(ret) {
        console.log(ret.data)
    })
</script>
</body>
</html>
axios的全局配置
/*
		axios.default.timeout=3000; //超時時間
				axios.defaults.baseURL='http://localhost:3000/app';  // 默認地址
				
		axios.defaults.headers['mytoken'] = 'asadfjksdfjkdsaf'  // 設置請求頭
*/

Example1

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script type="text/javascript">
    /*
        axios 響應式結果與全局配置
     */
    axios.defaults.baseURI = 'http://localhost:3000/';
    // 設置頭信息
    axios.defaults.headers['mytoken'] = 'hello';
    
    axios.get('axios-json').then(function(ret) {
        console.log(ret)
    })


</script>
</body>
</html>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
		<title>Examples</title>
		<meta name="description" content="">
		<meta name="keywords" content="">
		<link href="" rel="stylesheet">
		<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
		<script type="text/javascript" src="lib/vue.js"></script>
	</head>
	<body>

		<div id="box">
			<button @click="handleClick()">正在熱映</button>

			<ul>
				<li v-for="data in datalist">
					<h1>{{ data.name }}</h1>
					<img :src="data.poster">
				</li>
			</ul>
		</div>

		<script>
			new Vue({
				el: "#box",
				data: {
					datalist: []
				},
				methods: {
					handleClick() {
						axios.get("./json/test.json").then(res => {
							// axios 自歐東包裝data屬性 res.data
							console.log(res.data.data.films)
							this.datalist = res.data.data.films
						}).catch(err => {
							console.log(err);
						})
					}
				}
			})
		</script>
	</body>
</html>
相關文章
相關標籤/搜索