fetch在vue中的封装使用

这里写自定义目录标题

  • fetch的特性
    • 定义
    • 功能快捷键
    • 开始
      • 封装requist.js
    • 使用

fetch的特性

定义

Fetch 是一个现代的概念, 约等同于 XMLHttpRequest,其最大的两个特性:

  1. 可以在Service Workers使用;
  2. 基于Promise,天然支持Proomise;

功能快捷键

在Vue 项目开发中,我们与接口打交道最多了,如何来优雅的使用请求变得尤为重要了。 通常我们通过客户端向后端发送HTTP请求来接收接口数据,然后将这些接口数据完美的呈现到网页上。
同时,与接口打交道那么就会用到网络请求,与 Vue 结合的网络请求库有哪些呢?
vue-resource
axios
fetch
本章将使用 fetch 来完成接口的请求,以及对fetch 请求的封装,来满足业务开发。

开始

fetch 是与 XMLHttpRequest同级的方式,而非对ajax的封装。所以在现代浏览器中可以直接使用,无需引用任何库类,低级浏览器中,需要使用降级方案,这点不在我们此次文章之中(IE:你们都看我干什么?)
fetch在vue中的封装使用_第1张图片

封装requist.js

创建单独文件来封装Fetch,封装的同时,我们需要和 后端 协商好一些约定,如请求头 , 状态码, 等等
同时可以引入必要的UI 提示框, 不同的状态码,提示不同的响应,

请求头 : 来实现一些具体的业务,必须携带一些参数才可以请求(例如:会员业务)
状态码 : 根据接口返回的不同code , 来执行不同的业务,这块需要和后端约定好。
响应拦截器: 这块就是根据 后端 返回来的状态码判定执行不同业务
首先,我们先看一下成品requist结构是什么样的
fetch在vue中的封装使用_第2张图片
首先,第一步我们引入了vant的提示框
然后定义了一个 Request class,然后是对于错误请求的error处理,以及对于正确请求的success处理,以及需要业务弹窗错误的businessError处理。最后,是定义一个request对象,并将其export出去
然后我们看一下最核心的,即定义的Request class

class Request {
    constructor(parms) {
        this.withBaseURL = parms.withBaseURL
        this.baseURL = parms.baseURL
    }
    request(parames) {
        let url = parames.url || ''
        let method = parames.method || 'GET'
        let data = parames.data || ''
        this.withBaseURL = (url.indexOf('http') == -1)
        let requestUrl = this.withBaseURL ? this.baseURL + url : url;
        let options = {
            method,
            credentials: 'include',
            headers: {
                'Content-Type': 'application/json; charset=UTF-8',
            },
            body: JSON.stringify(data)
        }
        if (method == 'GET') {
            delete options.body;
            let qs = '?';
            for (const key in parames.data) {
                qs += key + '=' + parames.data[key] + '&'
            }
            qs = qs.substring(0, qs.length - 1)
            qs.length > 1 ? requestUrl += qs : ''
        }
        return fetch(requestUrl, options)
            .then(function (response) {
                return response.json();
            })
            .then(function (res) {
                return successFn(res)
            }).catch(function (err) {
                error(err)
            })
    }
}

在class 中,我们定义了一个构造函数,其接收一个对象,用于控制request的白名单与请求前缀,然后是其关键的request方法,这个方法也接受一个JSON,对象默认三个属性,分别是请求url,method,以及需要传递的参数
白名单用不是核心,我这里定义的白名单是为了处理不属于同一个后端的请求,如果你的项目中没有,可以不定义。
options是为了配置对于请求fetch控制不同配置的 init 对象:
对于get请求,需要一些特殊的处理,fetch中,get不可以放置body,其次参数需要拼接在url之后。
最后,我们定义一个fetch请求,将我们处理好的参数放置进去,随后,使用successFn作为响应拦截器。error作为网络错误的处理函数。
这样,我们对于request的封装基本已经完成了,完整代码如下

/*
 * @Author: WJK
 * @Date: 2020-03-01 13:21:27
 * @LastEditTime: 2020-03-02 13:10:41
 */
import { Toast } from 'vant';
class Request {
    constructor(parms) {
        this.withBaseURL = parms.withBaseURL
        this.baseURL = parms.baseURL
    }
    request(parames) {
        let url = parames.url || ''
        let method = parames.method || 'GET'
        let data = parames.data || ''
        this.withBaseURL = (url.indexOf('http') == -1)
        let requestUrl = this.withBaseURL ? this.baseURL + url : url;
        let options = {
            method,
            credentials: 'include',
            headers: {
                'Content-Type': 'application/json; charset=UTF-8',
            },
            body: JSON.stringify(data)
        }
        if (method == 'GET') {
            delete options.body;
            let qs = '?';
            for (const key in parames.data) {
                qs += key + '=' + parames.data[key] + '&'
            }
            qs = qs.substring(0, qs.length - 1)
            qs.length > 1 ? requestUrl += qs : ''
        }
        return fetch(requestUrl, options)
            .then(function (response) {
                return response.json();
            })
            .then(function (res) {
                return successFn(res)
            }).catch(function (err) {
                error(err)
            })
            
    }
}
function error(err) {
    Toast({
        message: '网络不给力!请稍后再试',
        icon: 'none',
        duration: 3500
    })
}
function successFn(data) {
    switch (data.code) {
        case 0:
            return data.data
            break;
        default:
            businessError(data.msg)
            break;
    }

}
function businessError(params) {
    Toast({
        message: params,
        duration: 2000
    })
}
const request = new Request({
    baseURL: process.env.VUE_APP_API,
    withBaseURL: true
})


export default request

使用

封装了之后,接下来就是如何使用,我们可以将项目中所有的请求,集中在一个api.js中进行处理,当需要调用的时候,可以直接引用使用
代码如下:

import request from './request'

let publicurl = '/'

/**
 * @msg: 获取首页数据
 * @param {type} 
 * @return: 
 */
export function index(data) {
  return request.request({
    url: `${publicurl}front/index`,
    method: 'POST',
    data,
  })
}

将request对象引用进来,使用的时候,直接调用方法即可,publicurl用于放置统一请求前缀,method中用于放置请求类型,data中用于放置请求参数。
最后,当我们需要调用这个请求的时候,可以在vue中使用

import { index } from "@/apis/index";

//调用
index({ json: "" })
      .then()
      .catch();

封装后的的fetch~,要更符合模块化使用的规范,也不容易在请求过程中,留下奇怪的bug
fetch在vue中的封装使用_第3张图片

你可能感兴趣的:(javascript,vue,fetch)