Hoody's Blog
NuxtJS 添加Axios进行异步数据请求

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

第一种 使用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

/**
 * 封装Axios
 * 处理请求、响应错误信息
 */
import { Message } from 'element-ui'  //引用饿了么UI消息组件
import axios from 'axios' //引用axios

// create an axios instance
const service = axios.create({
  baseURL: '/api/', // 所有异步请求都加上/api,nginx转发到后端Springboot
  withCredentials: true, // send cookies when cross-domain requests
  timeout: 5000 // request timeout
})

// request interceptor
service.interceptors.request.use(
  config => {
    // do something before request is sent
    // config.headers['-Token'] = getToken()
    return config
  },
  error => {
    // do something with request error
    console.log(error) // for debug
    return Promise.reject(error)
  }
)

// response interceptor
service.interceptors.response.use(
  /**
   * If you want to get http information such as headers or status
   * Please return  response => response
   */

  /**
   * 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 //res is my own data

    if (res.code === 20000) {
    // do somethings when response success
    //   Message({
    //     message: res.message || '操作成功',
    //     type: 'success',
    //     duration: 1 * 1000
    //   })
      return res
    } else {
      // if the custom code is not 200000, it is judged as an error.
      Message({
        message: res.msg || 'Error',
        type: 'error',
        duration: 2 * 1000
      })
      return Promise.reject(new Error(res.msg || 'Error'))
    }
  },
  error => {
    console.log('err' + error) // for debug
    Message({
      message: error.message,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(error)
  }
)

export default service //导出封装后的axios

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) => {  //从nuxt context 中获取 redirect 进行跳转
        redirect('/404')
      })
  }
添加新评论,支持Markdown格式