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


目標

/*
		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異步調用

異步調用分析

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

多次異步調用的依賴分析

/*
		多次異步調用的結果順序不確定
		異步調用結果如果存在依賴需要嵌套
*/

Example(傳統ajax)

<!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是一個對象,從他可以獲取異步操作的信息.

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得到錯誤信息
  });
});

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>
<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請求

<!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參數中函數的參數接受該值
*/

Example

<!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');
			});
*/

Example1

<!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>

對象方法

/*
		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>

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 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>
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>
axios攔截器

請求攔截器

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.interceptors.request.use(function (config) {
        console.log(config.url)
        config.headers.mytoken = 'nihao';
        return config;
    }, function (err) {
        console.log(err)
    })
    axios.get('http://localhost:3000/adata').then(function (data) {

    })
</script>
</body>
</html>
響應攔截器
// 添加一個響應攔截器
axios.interceptors.response.use(function(res){
	// 在這里對返回的數據進行處理
	return res;
},function(err){
	// 處理響應的錯誤信息
})

<!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.interceptors.response.use(function (res) {
        // console.log(res)
        var data = res.data;
        return data
        // return res;
    }, function (err) {
        console.log(err)
    })
    axios.get('http://localhost:3000/adata').then(function (data) {
        console.log(data)
    })
</script>
</body>
</html>

接口調用async/await

/*
		1.async/await是ES7引入的新語法,可以更加方便的進行異步操作.
		2.async關鍵字用於函數上(async函數的返回值是Prornise的實例對象)
		3.await關鍵字用於async函數當中(await可以得到異步結果)
*/

Example

<!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">
    /*
        async/await 處理異步操作
     */
    axios.defaults.baseURL = 'http://localhost:3000';
    // axios.get('adata').then(function (ret) {
    //     console.log(ret.data)
    // })

    async function queryData() {
        var ret = await new Promise(function (resolve, reject) {
            setTimeout(function () {
                resolve('nihao')
            }, 1000);
        });
        return ret
    }
    queryData().then(function (data) {
        console.log(data)
    });
</script>
</body>
</html>
async/await處理多個異步請求
async function queryData(id){
	const info = await axios.get('/async1');
	const ret = await axios.get('async2?info='+info.data);
	retrun ret;
}

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

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">
    /*
      async/await處理多個異步任務
    */
    axios.defaults.baseURL = 'http://localhost:3000';

    async function queryData() {
        var info = await axios.get('async1');
        var ret = await axios.get('async2?info=' + info.data);
        return ret.data;
    }

    queryData().then(function(data){
        console.log(data)
    })
</script>
</body>
</html>

基於接口的案例

/*
    圖書相關的操作基於后台接口數據進行操作
    需要調用接口的功能點
    		1. 圖書列表數據加載    GET  http://localhost:3000/books
    		2. 添加圖書   POST  http;//localhost:3000/books
    		3. 驗證圖書名稱是否存在  GET http://localhost:3000/books/book/:name
    		4. 編輯圖書-根據ID查詢圖書信息  GET http://localhost:3000/books/:id
    		5. 編輯圖書-提交圖書信息	PUT  http://localhost:3000/books/:id
    		6. 刪除圖書   DELETE http://localhost:3000/books/:id
*/

Example1

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <link rel="stylesheet" type="text/css" href="css/index.css">
</head>
<body>
  <div id="app">
    <div class="grid">
      <div>
        <h1>圖書管理</h1>
        <div class="book">
          <div>
            <label for="id">
              編號:
            </label>
            <input type="text" id="id" v-model='id' disabled="false" v-focus>
            <label for="name">
              名稱:
            </label>
            <input type="text" id="name" v-model='name'>
            <button @click='handle' :disabled="submitFlag">提交</button>
          </div>
        </div>
      </div>
      <div class="total">
        <span>圖書總數:</span>
        <span>{{total}}</span>
      </div>
      <table>
        <thead>
          <tr>
            <th>編號</th>
            <th>名稱</th>
            <th>時間</th>
            <th>操作</th>
          </tr>
        </thead>
        <tbody>
          <tr :key='item.id' v-for='item in books'>
            <td>{{item.id}}</td>
            <td>{{item.name}}</td>
            <td>{{item.date | format('yyyy-MM-dd hh:mm:ss')}}</td>
            <td>
              <a href="" @click.prevent='toEdit(item.id)'>修改</a>
              <span>|</span>
              <a href="" @click.prevent='deleteBook(item.id)'>刪除</a>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript" src="js/axios.js"></script>
  <script type="text/javascript">
    /*
      圖書管理-添加圖書
    */
    axios.defaults.baseURL = 'http://localhost:3000/';
    axios.interceptors.response.use(function(res){
      return res.data;
    }, function(error){
      console.log(error)
    });
    Vue.directive('focus', {
      inserted: function (el) {
        el.focus();
      }
    });
    Vue.filter('format', function(value, arg) {
      function dateFormat(date, format) {
        if (typeof date === "string") {
          var mts = date.match(/(\/Date\((\d+)\)\/)/);
          if (mts && mts.length >= 3) {
            date = parseInt(mts[2]);
          }
        }
        date = new Date(date);
        if (!date || date.toUTCString() == "Invalid Date") {
          return "";
        }
        var map = {
          "M": date.getMonth() + 1, //月份 
          "d": date.getDate(), //日 
          "h": date.getHours(), //小時 
          "m": date.getMinutes(), //分 
          "s": date.getSeconds(), //秒 
          "q": Math.floor((date.getMonth() + 3) / 3), //季度 
          "S": date.getMilliseconds() //毫秒 
        };
        format = format.replace(/([yMdhmsqS])+/g, function(all, t) {
          var v = map[t];
          if (v !== undefined) {
            if (all.length > 1) {
              v = '0' + v;
              v = v.substr(v.length - 2);
            }
            return v;
          } else if (t === 'y') {
            return (date.getFullYear() + '').substr(4 - all.length);
          }
          return all;
        });
        return format;
      }
      return dateFormat(value, arg);
    })
    var vm = new Vue({
      el: '#app',
      data: {
        flag: false,
        submitFlag: false,
        id: '',
        name: '',
        books: []
      },
      methods: {
        handle: async function(){
          if(this.flag) {
            // 編輯圖書
            var ret = await axios.put('books/' + this.id, {
              name: this.name
            });
            if(ret.status == 200){
              // 重新加載列表數據
              this.queryData();
            }
            this.flag = false;
          }else{
            // 添加圖書
            var ret = await axios.post('books', {
              name: this.name
            })
            if(ret.status == 200) {
              // 重新加載列表數據
              this.queryData();
            }
          }
          // 清空表單
          this.id = '';
          this.name = '';
        },
        toEdit: async function(id){
          // flag狀態位用於區分編輯和添加操作
          this.flag = true;
          // 根據id查詢出對應的圖書信息
          var ret = await axios.get('books/' + id);
          this.id = ret.id;
          this.name = ret.name;
        },
        deleteBook: async function(id){
          // 刪除圖書
          var ret = await axios.delete('books/' + id);
          if(ret.status == 200) {
            // 重新加載列表數據
            this.queryData();
          }
        },
        queryData: async function(){
          // 調用后台接口獲取圖書列表數據
          // var ret = await axios.get('books');
          // this.books = ret.data;

          this.books = await axios.get('books');
        }
      },
      computed: {
        total: function(){
          // 計算圖書的總數
          return this.books.length;
        }
      },
      watch: {
        name: async function(val) {
          // 驗證圖書名稱是否已經存在
          // var flag = this.books.some(function(item){
          //   return item.name == val;
          // });
          var ret = await axios.get('/books/book/' + this.name);
          if(ret.status == 1) {
            // 圖書名稱存在
            this.submitFlag = true;
          }else{
            // 圖書名稱不存在
            this.submitFlag = false;
          }
        }
      },
      mounted: function(){
        // var that = this;
        // axios.get('books').then(function(data){
        //   console.log(data.data)
        //   that.books = data.data;
        // })

        // axios.get('books').then((data)=>{
        //   console.log(data.data)
        //   this.books = data.data;
        // })

        this.queryData();
      }
    });
  </script>
</body>
</html>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM