Vue中前端與后端如何實現(xiàn)交互
Promise的基本使用
基本使用
new一個promise,為其傳入一個函數(shù)作為參數(shù),這個函數(shù)中傳入兩個參數(shù),分別用來執(zhí)行異步任務(wù)成功和失敗的回調(diào)函數(shù)。
function query(){ ?? ?var p=new Promise(function(resolve,reject){ ?? ??? ?setTimeout(function(){ ?? ??? ?var flag=true; ?? ??? ?if(flag){ ?? ??? ??? ?resolve('對了'); ?? ??? ?} ?? ??? ?else{ ?? ??? ??? ?reject('錯了'); ?? ??? ?} ?? ??? ?},1000) ?? ?}); ?? ?return p; } query().then(function(data){ ? //第一個函數(shù)接收成功的值 ?? ?console.log(data); },function(data){ ? ? ? ? ? ? //第二個函數(shù)接收失敗的值 ?? ?console.log(data); }); 輸出結(jié)果:‘對了'
多個請求,鏈?zhǔn)骄幊?/h3>
當(dāng)我們發(fā)送多個請求時,傳統(tǒng)的ajax會出現(xiàn)多層嵌套的回調(diào)地獄,Promise為我們提供了鏈?zhǔn)骄幊獭?/p>
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('服務(wù)器錯誤'); ? ? ? ? ? } ? ? ? ? }; ? ? ? ? xhr.open('get', url); ? ? ? ? xhr.send(null); ? ? ? }); ? ? ? return p; ? ? } ? ? // 發(fā)送多個ajax請求并且保證執(zhí)行順序 ? ? queryData('http://localhost:3000/data') ? ? ? .then(function(data){ ? ? ? ? console.log(data) ? ? ? ?//想要鏈?zhǔn)骄幊滔氯?,必須return ? ? ? ? return queryData('http://localhost:3000/data1'); ? ? ? }) ? ? ? .then(function(data){ ? ? ? ? console.log(data); ? ? ? ? return queryData('http://localhost:3000/data2'); ? ? ? }) ? ? ? .then(function(data){ ? ? ? ? console.log(data) ? ? ? });
Promise的API—實例方法
.then()
: 傳入兩個參數(shù)時,只執(zhí)行成功的。傳入一個參數(shù)時,那個參數(shù)執(zhí)行的是成功的回調(diào)。- 得到成功的結(jié)果
.catch()
:傳入兩個參數(shù)時,只執(zhí)行錯誤的。傳入一個參數(shù)時,那個參數(shù)執(zhí)行的是失敗的回調(diào)。- 得到異常的結(jié)果
.finally()
不是正式標(biāo)準(zhǔn)- 無論成功與否都會執(zhí)行
<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){ ? ? ? ? # 得到異步任務(wù)正確的結(jié)果 ? ? ? ? console.log(data) ? ? ? },function(data){ ? ? ? ? # 獲取異常信息 ? ? ? ? console.log(data) ? ? ? }) ? ? ? # 成功與否都會執(zhí)行(不是正式標(biāo)準(zhǔn))? ? ? ? .finally(function(){ ? ? ? ? console.log('finished') ? ? ? }); ? </script>
Promise的API—對象方法(直接通過Promise函數(shù)名稱調(diào)用的方法)
(1)Promise.all()并發(fā)處理多個異步任務(wù),所有任務(wù)都執(zhí)行完成才能得到結(jié)果。
Promise.all
方法接受一個數(shù)組作參數(shù),數(shù)組中的對象(p1、p2、p3)均為promise實例(如果不是一個promise,該項會被用Promise.resolve轉(zhuǎn)換為一個promise)。它的狀態(tài)由這三個promise實例決定
(2)Promise.race()并發(fā)處理多個異步任務(wù),只要有一個任務(wù)完成就能得到結(jié)果。
Promise.race
方法同樣接受一個數(shù)組作參數(shù)。當(dāng)p1, p2, p3中有一個實例的狀態(tài)發(fā)生改變(變?yōu)閒ulfilled或rejected),p的狀態(tài)就跟著改變。并把第一個改變狀態(tài)的promise的返回值,傳給p的回調(diào)函數(shù)
? <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('服務(wù)器錯誤'); ? ? ? ? ? } ? ? ? ? }; ? ? ? ? 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){ ? ? ? ?//請求時間和發(fā)送順序有關(guān),先發(fā)送先返回。 ? ? ? ?// ? all 中的參數(shù) ?[p1,p2,p3] ? 和 返回的結(jié)果一 一對應(yīng)["HELLO TOM", "HELLO JERRY", "HELLO SPIKE"] ? ? ? ?console.log(result) //["HELLO TOM", "HELLO JERRY", "HELLO SPIKE"] ? ? ?}) ? ? Promise.race([p1,p2,p3]).then(function(result){ ? ? ? // 由于p1執(zhí)行較快,Promise的then()將獲得結(jié)果'P1'。p2,p3仍在繼續(xù)執(zhí)行,但執(zhí)行結(jié)果將被丟棄。 ? ? ? console.log(result) // "HELLO TOM" ? ? }) ? </script>
接口調(diào)用-fetch用法
基本使用
- 更加簡單的數(shù)據(jù)獲取方式,高性能更強大、更靈活,可以看做是xhr的升級版
- 給Promise實現(xiàn)
- Fetch API是新的ajax解決方案 Fetch會返回Promise
- fetch不是ajax的進(jìn)一步封裝,而是原生js,沒有使用XMLHttpRequest對象。
fetch(url, options).then() ?<script type="text/javascript"> ? ?/* ? ? ?Fetch API 基本用法 ? ? ??? ?fetch(url).then() ? ? ?? ?第一個參數(shù)請求的路徑 ? Fetch會返回Promise ? 所以我們可以使用then 拿到請求成功的結(jié)果? ? ?*/ ? ?fetch('http://localhost:3000/fdata').then(function(data){ ? ? ?// text()方法屬于fetchAPI的一部分,它返回一個Promise實例對象,用于獲取后臺返回的數(shù)據(jù) ? ? ?return data.text(); ? //text()是fetch的一個api,返回的是一個Promise的對象 ? ?}).then(function(data){ ? ? ?// ? 在這個then里面我們能拿到最終的數(shù)據(jù) ? ? ? ?console.log(data); ? ?}) ?</script>
常用配置選項
- fetch(url, options).then()
- HTTP協(xié)議,它給我們提供了很多的方法,如POST,GET,DELETE,UPDATE,PATCH和PUT
- 默認(rèn)的是 GET 請求
- 需要在 options 對象中 指定對應(yīng)的 method method:請求使用的方法
- post 和 普通 請求的時候 需要在options 中 設(shè)置 請求頭 headers 和 body
GET請求
傳統(tǒng)url請求傳參—通過“?”傳遞參數(shù)
前端代碼
fetch('http://localhost:3000/books?id=123', { ? ? ? ? ? ? ?? ?# get 請求可以省略不寫 默認(rèn)的是GET? ? ? ? ? ? ? ? ? method: 'get' ? ? ? ? ? ? }) ? ? ? ? ? ? .then(function(data) { ? ? ? ? ? ? ?? ?# 它返回一個Promise實例對象,用于獲取后臺返回的數(shù)據(jù) ? ? ? ? ? ? ? ? return data.text(); ? ? ? ? ? ? }).then(function(data) { ? ? ? ? ? ? ?? ?# 在這個then里面我們能拿到最終的數(shù)據(jù) ? ? ? ? ? ? ? ? ? console.log(data) ? ? ? ? ? ? });
后端代碼
app.get('/books'(req.res)=>{ ?? ?res.send("傳統(tǒng)url傳遞參數(shù)"+req.query.id); })
restful形式url傳遞參數(shù)—通過“/”傳遞參數(shù)
前端代碼
fetch('http://localhost:3000/books/456', { ? ? ? ? ? ? ?? ?# get 請求可以省略不寫 默認(rèn)的是GET? ? ? ? ? ? ? ? ? method: 'get' ? ? ? ? ? ? }) ? ? ? ? ? ? .then(function(data) { ? ? ? ? ? ? ? ? return data.text(); ? ? ? ? ? ? }).then(function(data) { ? ? ? ? ? ? ? ? console.log(data) ? ? ? ? ? ? });
后端代碼
app.get('/book/:id',(req.res)=>{ ?? ?res.send("restful形式傳遞參數(shù)"+req.params.id); })
DELETE請求
與GET方式相似,只需把method屬性改為“delete”
POST請求方式的參數(shù)傳遞
post傳遞參數(shù)時,option對象中除了method屬性,需要額外增加headers和body屬性
前端代碼
body為查詢字符串格式
var url='http://127.0.0.1:3000/product/books/'; ? ? ? fetch(url,{ ? ? ? ? method:'post', ? ? ? ? headers:{ ? ? ? ? ? 'Content-Type':'application/x-www-form-urlencoded' ? ? ? ? }, ? ? ? ? body:'uname=高進(jìn)宇&pwd=11223344' ? ? ? }).then(data=>{ ? ? ? ? return data.text(); ? ? ? }).then(data=>{ ? ? ? ? console.log(data); ? ? ? })
后端代碼
app.post('/books', (req, res) => { ? ? res.send('axios post 傳遞參數(shù)' + req.body.uname + '---' + req.body.pwd) ? })
body為JSON格式
fetch('http://localhost:3000/books', { ? ? ? ? ? ? ? ? method: 'post', ? ? ? ? ? ? ? ? body: JSON.stringify({ ? ? ? ? ? ? ? ? ? ? uname: '張三', ? ? ? ? ? ? ? ? ? ? pwd: '456' ? ? ? ? ? ? ? ? }), ? ? ? ? ? ? ? ? headers: { ? ? ? ? ? ? ? ? ? ? 'Content-Type': 'application/json' ? ? ? ? ? ? ? ? } ? ? ? ? ? ? }) ? ? ? ? ? ? .then(function(data) { ? ? ? ? ? ? ? ? return data.text(); ? ? ? ? ? ? }).then(function(data) { ? ? ? ? ? ? ? ? console.log(data) ? ? ? ? ? ? });
后端代碼
app.post('/books', (req, res) => { ? ? res.send('axios post 傳遞參數(shù)' + req.body.uname + '---' + req.body.pwd) ? })
PUT請求方式的參數(shù)傳遞
fetch響應(yīng)結(jié)果
用fetch來獲取數(shù)據(jù),如果響應(yīng)正常返回,我們首先看到的是一個response對象,其中包括返回的一堆原始字節(jié),這些字節(jié)需要在收到后,需要我們通過調(diào)用方法將其轉(zhuǎn)換為相應(yīng)格式的數(shù)據(jù),比如JSON,BLOB或者TEXT等等
text()
:將返回體處理成字符串形式json()
:返回結(jié)果和JSON.parse(response.Text)一樣
? ? /* ? ? ? Fetch響應(yīng)結(jié)果的數(shù)據(jù)格式 ? ? */ ? ? fetch('http://localhost:3000/json').then(function(data){ ? ? ? // return data.json(); ? // ?將獲取到的數(shù)據(jù)使用 json 轉(zhuǎn)換對象 ? ? ? return data.text(); // ?// ?將獲取到的數(shù)據(jù) 轉(zhuǎn)換成字符串? ? ? }).then(function(data){ ? ? ? // console.log(data.uname) ? ? ? // console.log(typeof data) ? ? ? var obj = JSON.parse(data); ? ? ? console.log(obj.uname,obj.age,obj.gender) ? ? })
接口調(diào)用–axios用法
認(rèn)識
- 基于promise用于瀏覽器和node.js的http客戶端
- 支持瀏覽器和node.js
- 支持promise
- 能攔截請求和響應(yīng)
- 自動轉(zhuǎn)換JSON數(shù)據(jù)
- 能轉(zhuǎn)換請求和響應(yīng)數(shù)據(jù)
axios的基礎(chǔ)用法
axios的常用API
get()
post()
delete()
put()
axios 全局配置
配置公共的請求頭
axios.defaults.baseURL = 'https://api.example.com';
配置 超時時間
axios.defaults.timeout = 2500;
配置公共的請求頭
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
配置公共的 post 的 Content-Type
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
GET請求
發(fā)送get請求
axios.get('http://localhost:3000/adata').then(function(ret){? ? ? ? # ?拿到 ret 是一個對象 ? ? ?所有的對象都存在 ret 的data 屬性里面 ? ? ? // 注意data屬性是固定的用法,用于獲取后臺的實際數(shù)據(jù) ? ? ? console.log(ret.data) ? ? ? console.log(ret) ? ? })
get 請求傳遞參數(shù)
通過傳統(tǒng)的url 以 ? 的形式傳遞參數(shù)
axios.get('http://localhost:3000/axios?id=123').then(function(ret){ ? ? ? console.log(ret.data) ? ? })
restful 形式傳遞參數(shù)
axios.get('http://localhost:3000/axios/123').then(function(ret){ ? ? ? console.log(ret.data) ? ? })
通過params 形式傳遞參數(shù)
前端代碼
axios.get('http://localhost:3000/axios', { ? ? ? params: { ? ? ? ? id: 789 ? ? ? } ? ? }).then(function(ret){ ? ? ? console.log(ret.data) ? ? })
后端代碼
router.get('/axios', (req, res) => { ? ? res.send('axios get 傳遞參數(shù)' + req.query.id) })
DELETE請求傳參
傳參形式和GET請求一樣
POST請求
通過選項傳遞參數(shù)(默認(rèn)傳遞的是json格式的數(shù)據(jù))
前端代碼
axios.post('http://localhost:3000/axios', { ? ? ? uname: 'lisi', ? ? ? pwd: 123 ? ? }).then(function(ret){ ? ? ? console.log(ret.data) ? ? })
后端代碼
router.post('/axios', (req, res) => { ? ? res.send('axios post 傳遞參數(shù)' + req.body.uname + '---' + req.body.pwd) ? })
通過 URLSearchParams傳遞參數(shù)(application/x-www-form-urlencoded)
var params = new URLSearchParams(); ? ? params.append('uname', 'zhangsan'); ? ? params.append('pwd', '111'); ? ? axios.post('http://localhost:3000/axios', params).then(function(ret){ ? ? ? console.log(ret.data) ? ? })
PUT請求
與post請求一樣。
axios的響應(yīng)結(jié)果
data
:實際響應(yīng)回來的數(shù)據(jù)。headers
:響應(yīng)頭信息。status
:響應(yīng)狀態(tài)碼。statusText
:響應(yīng)狀態(tài)信息。
axios攔截器
請求攔截器
請求攔截器的作用是在請求發(fā)送前進(jìn)行一些操作
例如在每個請求體里加上token,統(tǒng)一做了處理如果以后要改也非常容易
axios.interceptors.request.use(function(config) { ? ? ? console.log(config.url) ? ? ? # 1.1 ?任何請求都會經(jīng)過這一步 ? 在發(fā)送請求之前做些什么 ?? ? ? ? config.headers.mytoken = 'nihao'; ? ? ? # 1.2 ?這里一定要return ? 否則配置不成功 ? ? ? ? return config; ? ? }, function(err){ ? ? ? ?#1.3 對請求錯誤做點什么 ? ? ? ? ? console.log(err) ? ? })
響應(yīng)攔截器
響應(yīng)攔截器的作用是在接收到響應(yīng)后進(jìn)行一些操作
例如在服務(wù)器返回登錄狀態(tài)失效,需要重新登錄的時候,跳轉(zhuǎn)到登錄頁
?axios.interceptors.response.use(function(res) { ? ? ? #2.1 ?在接收響應(yīng)做些什么 ? ? ? ? var data = res.data; ? ? ? return data; ? ? }, function(err){ ? ? ? #2.2 對響應(yīng)錯誤做點什么 ? ? ? ? console.log(err) ? ? })
經(jīng)過以上響應(yīng)攔截器處理以后。下面拿到的res就是需要的數(shù)據(jù),不需要再進(jìn)行res.data的操作。
axios.post('http://localhost:3000/axios', { ? ? ? uname: 'lisi', ? ? ? pwd: 123 ? ? }).then(function(res){ ? ? ? console.log(res) ? ? })
async 和 await
async作為一個關(guān)鍵字放到函數(shù)前面
任何一個async函數(shù)都會隱式返回一個promise
await關(guān)鍵字只能在使用async定義的函數(shù)中使用
- await后面可以直接跟一個 Promise實例對象
- await函數(shù)不能單獨使用
async/await 讓異步代碼看起來、表現(xiàn)起來更像同步代碼
async/await是ES7引入的新語法,可以更加方便的進(jìn)行異步操作。
async關(guān)鍵字用于函數(shù)上(async函數(shù)的返回值是Promise對象)。
await關(guān)鍵字用于async函數(shù)當(dāng)中(await可以直接得到異步的結(jié)果)。
async 基礎(chǔ)用法
? ? //async作為一個關(guān)鍵字放到函數(shù)前面 ?? ?async function queryData() { ? ? ? //await關(guān)鍵字只能在使用async定義的函數(shù)中使用 ? ? ?await后面可以直接跟一個 Promise實例對象 ? ? ? var ret = await new Promise(function(resolve, reject){ ? ? ? ? setTimeout(function(){ ? ? ? ? ? resolve('nihao') ? ? ? ? },1000); ? ? ? }) ? ? ? // console.log(ret.data) ? ? ? return ret; ? ? } ?? ?//任何一個async函數(shù)都會隱式返回一個promise ? 我們可以使用then 進(jìn)行鏈?zhǔn)骄幊? ? ? queryData().then(function(data){ ? ? ? console.log(data) ? ? })
async 函數(shù)處理多個異步函數(shù)
axios.defaults.baseURL = 'http://localhost:3000'; ? ? async function queryData() { ? ? ? // ?添加await之后 當(dāng)前的await 返回結(jié)果之后才會執(zhí)行后面的代碼 ?? ? ? ? var info = await axios.get('async1'); ? ? ? // ?讓異步代碼看起來、表現(xiàn)起來更像同步代碼 ? ? ? var ret = await axios.get('async2?info=' + info.data); ? ? ? return ret.data; ? ? } ? ? queryData().then(function(data){ ? ? ? console.log(data) ? ? })
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue.js+Layer表格數(shù)據(jù)綁定與實現(xiàn)更新的實例
下面小編就為大家分享一篇Vue.js+Layer表格數(shù)據(jù)綁定與實現(xiàn)更新的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-03-03淺談vue的iview列表table render函數(shù)設(shè)置DOM屬性值的方法
下面小編就為大家?guī)硪黄獪\談vue的iview列表table render函數(shù)設(shè)置DOM屬性值的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-09-09Nuxt 嵌套路由nuxt-child組件用法(父子頁面組件的傳值)
這篇文章主要介紹了Nuxt 嵌套路由nuxt-child組件用法(父子頁面組件的傳值),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11vue+quasar使用遞歸實現(xiàn)動態(tài)多級菜單
這篇文章主要為大家詳細(xì)介紹了vue+quasar使用遞歸實現(xiàn)動態(tài)多級菜單,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-07-07vue環(huán)形進(jìn)度條組件實例應(yīng)用
在本文中我們給大家分享了關(guān)于vue環(huán)形進(jìn)度條組件的使用方法以及實例代碼,需要的朋友們跟著測試下吧。2018-10-10