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') }
) }