原文:https://www.jianshu.com/p/9ba523578817
看這篇文章之前,默認你是知道nuxt是什么的,並且知道nuxt怎么使用。
如果不了解的,建議先去看看nuxt的基礎知識再來繼續閱讀本篇文章
nuxt中文官網:https://zh.nuxtjs.org/
nuxt官方推薦使用axios作為http請求的類庫。
axios在nuxt中有兩種使用場景:
- 客戶端使用
- 服務端使用
nuxt提供了專用的axios的模塊:https://axios.nuxtjs.org/,並且支持反向代理等功能
當然你也可以不使用專用模塊,以傳統模式引入原生axios,這里不做討論
首先在nuxt.config.js中引入axios模塊,代碼如下:
(如果需要反向代理等功能,需要引入@nuxtjs/proxy,不過不引入好像也可以用,默認自帶的)
modules: [ // Doc: https://axios.nuxtjs.org/usage '@nuxtjs/axios', '@nuxtjs/proxy' ]
然后再nuxt.config.js中做如下配置:
axios: {
prefix: '/api',
credentials: true,
proxy: true
},
proxy:
{
'/api': 'http://bugchang.com'
}
axios:
- prefix:前綴的值,比如請求
get articles/1
實際請求是經過修飾的get api/articles/1
- credentials:是否攜帶證書,這個我沒用到,也不知道具體咋用的,感興趣的可以去研究一下
- proxy:是否開啟代理,為
true
時proxy
中的配置才能生效
proxy:
- 將axios請求地址通過反向代理進行請求,如
get api/articles/1
的最終請求會指向get http://bugchang.com/api/articles/1
這只是最簡單的配置,porxy還有其他形式的配置:
proxy: { '/api/': { target: 'http://bugchang.com/', pathRewrite: { '^/api/': '' } } },
- target:將api前綴的地址請求指向target定義的地址
- pathRewrite:將url中的api替換為空
舉個例子,2個后台接口:
get articles/1
get categories/1
這樣的接口proxy沒法做設置,因為沒規律,不能每個接口都加一條規則吧,所以用axios先給地址加個前綴,這樣就變成了:
get api/articles/1
get api/categories/1
然后我們只要指定/api/
這樣的Url都通過代理指向http://bugchang.com
這個地址,請求的url就會變成:
get http://bugchang.com/api/articles/1
get http://bugchang.com/api/categories/1
但是實際上我們后台的接口並沒有api這個路徑,這樣訪問肯定404,所以我們通過pathRewrite在請求時把/api/這個字符串替換成'':
get http://bugchang.com/articles/1
get http://bugchang.com/categories/1
這樣就達到了我們的目的。
axios配置
在nuxt.config.js中的axios代碼塊中我們可以對axios模塊進行基礎參數的配置,基本上和原生axios沒兩樣
但是值得注意的一點是,我們用原生axios的時候西關定義baseURL,在nuxt中baseURL
的定義需要關注一下,如果你使用了反向代理的功能(也就是proxy: true
),那么就不能定義baseURL,這兩項之間是沖突的,我們可以使用prefix
來代替baseURL
還有一個參數是原生axios沒有的,browserBaseURL
,browserBaseURL
是客戶端的訪問的根Url,因為在nuxt中,前端和后端訪問的地址可能不一樣,比如前端訪問線上地址:http://blog.bugchang.com/,但是后台如果和接口服務在一個服務器上,可以直接訪問http://localhost:5000,這樣可以避免不必要的網絡延遲和映射流量
browserBaseURL
默認是baseURL
的值,若果proxy: true
那么默認值就是prefix
的值
其他選項配置參考官方文檔:https://axios.nuxtjs.org/options
axios的使用
async getCategories () { this.categories = await this.$axios.$get('/categories') }
按照以上的配置后,我們是可以在nuxt的上下文中拿到axios的對象,使用this.$axios
獲取到axios對象,然后進行get或post等請求即可
有三種方式來使用axios進行請求,無論使用哪種效果都是一樣的(本人更偏愛第二種):
- 返回 Promise
function test1(){ this.$axios.get(`http://blog.bugchang.com/articles/1`) .then((res) => { console.log(res) }) }
- 使用 async或await
function test2(){ const { data } = await this.$axios.get(`http://blog.bugchang.com/articles/1`) console.log(data) }
- 使用 回調函數
function test3(callback){ this.$axios.get(`http://blog.bugchang.com/articles/1`) .then((res) => { callback(null, { title: res.data.title }) }) }
以上示例代碼是在客戶端模式下使用的,也就是no-ssr模式,那么服務器端如何使用呢?以nuxt的asyncData方法為例
了解nuxt的生命周期的話,們知道asyncData方法中是沒有this對象的,我們可以把$axios
作為參數傳遞到asyncData方法
代碼如下:
async asyncData ({ params, $axios }) { const { data } = await $axios.get(`/articles/index?pageIndex=1`) return { data, page: 1 } }
服務端如果需要同時請求多個接口怎么寫呢,普通的寫法是不生效的,要這么寫:
async asyncData ({ params, $axios }) { const [articles, category] = await Promise.all([ $axios.$get(`/articles/category/${params.id}`), $axios.$get(`/categories/${params.id}`) ]) ... }
關於$axios.$get和$axios.get的坑
一開始我沒注意到這塊的問題,后來遇到了一些坑才發現是咋回事
$get直接返回responsebody的內容,其他相關信息比如header、cookie什么的上下文信息是不返回的
get與$get正相反,包括上下文信息和消息體在內的內容都會返回
const { data } = await $axios.get(`/articles/index?pageIndex=1\`) const data = await $axios.$get(`/articles/index?pageIndex=1\`) const data = await $axios.get(`/articles/index?pageIndex=1\`).data
以上三種寫法返回的對象是一致的,注意{}
的區別
自定義全局過濾器
如果以上配置無法滿足你的要求,或者你要定義一些全局過濾器,做一些額外操作的話,可以以插件的形式加載
在plugins
文件夾下新建axios.js
,這些配置和原生的axios一樣,不再贅述:
import Cookie from 'js-cookie' export default function (app) { const axios = app.$axios // 基本配置 axios.defaults.timeout = 10000 axios.defaults.headers.post['Content-Type'] = 'application/json' axios.defaults.headers.patch['Content-Type'] = 'application/json' axios.defaults.headers.put['Content-Type'] = 'application/json' // 請求回調 axios.onRequest((config) => { const token = Cookie.get('token') config.headers.Authorization = `Bearer ${token}` }) // 返回回調 axios.onResponse((res) => { if (res.headers.refreshtoken) { Cookie.set('token', res.headers.refreshtoken) } }) // 錯誤回調 axios.onError((error) => { switch (error.response.status) { case 401: location.href = '/login' break } }) }
然后在axios.config.js中將@/plugins/axios注冊到plugins代碼塊中:
plugins: [ '@/plugins/vue-mavon-editor', '@/plugins/axios', '@/plugins/bdtj.js' /* 百度統計 */ ]
自定義局部設置
上面說了全局的攔截和配置,如果說某幾個功能需要一些特殊的header啊或者其他的配置怎么辦呢
this.$axios.setHeader('token', token) this.$axios.setHeader('key', key) for (const item of data.defaultPaper.questionGroupList) { for (const question of item.questionWrapperList) { const { data } = await $axios.get('https://ecs.qmth.com.cn:8878/api/ecs_oe_student/examQuestion/getQuestionContent?questionId=' + question.questionId + '&exam_record_id= ') console.log(data) result.push(data) } }
總結
以上就是個人總結的nuxt使用axios模塊的一些經驗,希望能幫到你
作者:BugChang
鏈接:https://www.jianshu.com/p/9ba523578817
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。