«

NuxtJS 通过 2种方式引入axios进行异步数据请求

emer 发布于 2019-10-31 16:10   5326 次阅读     


第一种 使用nuxt 提供的 Axios插件 @nuxtjs/axios

1.安装

npm install @nuxtjs/axios -d

2.配置 nuxt.config.js

exports default { modules: [ '@nuxtjs/axios', ], axios: { // proxyHeaders: false  } } 

3.在提供context(上下文对象)中取得$axios

Component

async asyncData({ $axios }) { const ip = await $axios.$get('http://icanhazip.com') return { ip } } 

4.使用Nuxt plugin扩展Axios

nuxt会在vue.js程序启动前调用 plugins目录下的脚本,
并且以context(上下文对象)作为参数, 可以取到$axios

创建 plugins/axios.js 并定义axios的拦截器,定义请求的各个阶段需要进行的处理

export default function({ $axios, redirect }) { // request interceptor  $axios.interceptors.request.use( config => { 
// do something before request is sent  return config 
}, error => { 
// do something with request error  return Promise.reject(error) 
} ) 
$axios.onRequest(config => {
 console.log('Making request to ' + config.url) }) // response interceptor  

$axios.interceptors.response.use(
 /**  * Determine the request status by custom code  * Here is just an example  * You can also judge the status by HTTP Status Code  */ 

response => { 
const res = response.data if (res.code === 20000) { 
return res 
} else { 
redirect('/404') // if the custom code is not 200, it is judged as an error.  } return Promise.reject(new Error(res.msg || 'Error')) }, error => { console.log('err' + error) // for debug  return Promise.reject(error) } 
) 
$axios.onError(error => {
 const code = parseInt(error.response && error.response.status) 
if (code === 400) { redirect('/404') } else if (code === 500) { redirect('/500') 
} }) } 



5.添加插件到nuxt.config.js配置文件

plugins: [
    '@/plugins/axios'
  ],

第二种 直接引入axios,并模块化请求

1.npm安装

npm install axios

2.创建Axios扩展request.js

/api/request.js主要做了3件事,
- 创建axios实例 - 增加request拦截器,在请求发出前做自定义处理,比如加上token,sessionID - 增加response拦截器,收到响应信息后判断响应状态,如果出错可以使用Message组件提示 - PS:在AsyncData方法中调用时,在服务器端执行,没有UI,所以无法进行UI展示提示.所以需要通过process.server变量判断当前环境是不是服务器

/api/request.js

import axios from 'axios'

import { Message, Notification } from 'element-ui' // 这里使用了element-ui的消息提示方法,也可自行定义 

axios.defaults.headers['X-Requested-With'] = 'XMLHttpRequest'
axios.defaults.headers.post['Content-Type'] = 'text/plain;charset=UTF-8'
let service = axios.create({
   baseURL: 'http://localhost:3000/',//这个一定要写当前运行的地址,否则渲染失败
  timeout: 10000
})

 // 请求拦截 可在请求头中加入token等
service.interceptors.request.use(config => {

  return config
}, error => {
  return Promise.reject(error)
})

// 响应拦截 对响应消息作初步的处理
service.interceptors.response.use(resp => {
  if (resp.data) {
    if (resp.data.code !== '0') {
      Message({
        type: 'error',
        message: resp.data.message,
        duration: 5000
      })
    }
    return { code: resp.data.code, data: resp.data.data, msg: resp.data.message }
  } else {
    return resp
  }
}, error => {
  if (error.response) {
    switch (error.response.states) {
      case 400: {
        if (error.response && error.response.data && error.response.data.message) {
          Notification.error({
            title: '400错误',
            message: error.response.data.message,
            duration: 5000,
            closable: true
          })
        }
        break
      }
    }
  }
})

export default service




3.创建API接口文件

创建API接口文件,抽出所有模块的异步请求 - 将同模块的请求写在一起,将ajax请求和页面隔离 - 如果后端API调整,只需要修改对应接口文件

/api/blog.js

import request from './request' /
**  * 获取博客详情  * @param id 博客ID  */ 
export function getBlog(id) { 
return request({ url: 'blog/detail/' + id, method: 'get' 
}) }
 /** * 获取博客列表 * @param page 页码 * @param max 每页显示数量 */ export function getList(page, max) {
 return request({ url: 'blog/list', method: 'get', params: { page, max } }
) } 




4.vue组件使用

/pages/detail/_id.vue

import { getBlog} from '~/api/blog' 
asyncData({ params, redirect}) { 
return getBlog(params.id) //直接使用API导出的方法进行请求  
.then(({ data }) => { return { blog: data }
 }).catch((e) => { 
redirect('/404') }
) }