0.0.2 • Published 2 years ago

lc-universe-ajax v0.0.2

Weekly downloads
-
License
ISC
Repository
-
Last release
2 years ago

@lx-frontend/ajax

一个规范Ajax使用的框架

安装

使用npm:

npm install @lx-frontend/ajax

使用yarn:

yarn add @lx-frontend/ajax

Example

// 请求库实例
import axios from 'axios';
import { Ajax } from '@lx-frontend/ajax';

// rest配置
const rest = {
  firstModule: {
    getCall: ['get', '/the/request/url', requestOptions],
    postCall: ['post', '/the/post/url', requestOptions]
  }
}

// 实例化配置
const options = {
  rest,
  baseUrl
}

// 实例化
const ajax = new Ajax(options)

完成Ajax实例化之后,即可使用如下方式发起请求:

ajax.$rest.firstModule.getCall().then(res => {/***/})

ajax.$rest.firstModule.postCall(data).then(res => {/***/})

options配置

// const ajax = new Ajax(options)
{
  rest
  baseUrl
  // boolean,是否发送FormData类型的数据,如果为true,则会将data数据转化成FormData形式,且修改请求头header中的Content-Type字段,默认为false,发送json数据
  sendFormData
  // wx/node/browser 如果是node或browser可以省略该参数
  // 如果是wx,则必须带上该参数,且需要将wx对象传递给engine
  envType,
  // 发起请求的引擎,node和browser不需要该参数
  // 微信环境则需要将微信引擎对象传递给该属性,配合envType使用
  engine,
  // ... 其他axios支持的所有配置
}

rest

该框架要求所有请求必须属于一个模块,rest对象的每个属性则代表一个模块,模块下是具体的请求函数配置。

rest的配置遵循如下模式:

{
  moduleName: {
    funcName: [method, url, requestOptions]
    // ...
  }
  // ...
}

例如: 如下rest配置中,firstModule是模块名称,该模块下有两个名为getCallpostCall的请求

const rest = {
  firstModule: {
    getCall: ['get', '/the/request/url', {/* requestOptions */}],
    postCall: ['post', '/the/post/url', {/* requestOptions */}]
  }
}

rest的结构决定了Ajax在实例化之后的调用方式,比如,getCallpostCall将通过如下方式调用:

// const ajax = new Ajax(options)
// 实例化之后,请求函数组成的模块将被挂载到 $rest 属性下
ajax.$rest.firstModule.getCall().then(/***/)
ajax.$rest.firstModule.postCall().then(/***/)

请求配置 method, url, requestOptions

模块下具体的请求通过一个三元数组配置而来,数组项分别表示:请求的方法,请求的路径,以及对请求的配置。

method: string类型,目前仅支持get, put, post, patch, delete方法

url: string类型,该路径将和requestOptions的baseUrl属性拼接,组成最终的请求路径。

requestOptions: object, 详见requestOptions

requestOptions

requestOptions的参数有两种类型

  1. 初始化参数中,除rest,engineType,engine之外的参数,如果和初始化参数重复,则这里的优先级最高
  2. 任何自定义的参数,该参数会被携带在请求响应response中,可以通过该参数在拦截器中执行任何逻辑
{
  baseUrl,
  sendFormData,
  // ...
}

ajax实例方法

// 实例化
const ajax = new Ajax(options)

ajax.extend(obj) // 直接将obj上的属性赋值到ajax对象上

ajax.extendRest(mod) // 扩展$rest对象,mod的配置格式见rest对象下的属性

在Vue中使用

import { Ajax } from '@lx-frontend/ajax'

const ajax = new Ajax(options)

Vue.use(Ajax)

const app = new Vue({
  ajax,
  // ...
})

插件的作用是,声明了一个全局的mixin,在应用始化阶段,获取ajax.$rest,并将将其挂载到Vue.prototype上,方便在页面组件中以this.$rest的方式获取ajax上的请求方法。

对项目遗留配置的兼容

改造旧项目时,原项目ajax配置的query, create, delete, putWay, patchWay方法在该库中并不存在,一一去修改这些配置工作量太大,所以下面提供了一种兼容的方法:

import { Ajax, compatibleMethods } from '@lx-frontend/ajax'
import { Ajax } from '@lx-frontend/ajax'

const ajax = new Ajax(options)
// compatibleMethods方法则为ajax添加了`query`, `create`, `deletes`, `putWay`, `patchWay`方法
compatibleMethods(ajax)

需要注意的一点是,delete是JS的保留关键字,无法通过代码添加delete方法,所以将delete改为了deletes

所以原配置只需要做很小的修改,即,将ajax.delete改为ajax.deletes,即可正常工作。

对于新项目则可以不引入该函数,打包时利用treeshaking将该函数代码去除即可。

如何完善项目的ajax的typescript校验?

鉴于目前大部分项目都有restConfig和调用ajax.extendRest,下面将以此为例子。

  1. 首先是 ajax.extendRest 和 new Ajax() 需要进行分离。 如果不将两者分离,就不太方便处理模块化调用后的restConfig类型。
  2. 分离后调用项目内的 IRestTypes 组织类型。一般情况下都可以满足,如果不满足可以来补充或者群里喊一下。
  • 给实例挂上$rest的类型。
// /ajax/instance.js
import Ajax, { compatibleMethods } from '@lx-frontend/ajax'
import { interceptRequest, interceptSuccess, interceptFail } from './interceptor'

const ajax = new Ajax({})
compatibleMethods(ajax)

ajax.interceptors.request.use(interceptRequest)
ajax.interceptors.response.use(interceptSuccess, interceptFail)

export default ajax
// /ajax/index.ts
import ajax from './instance'
import { IRestTypes } from '@lx-frontend/ajax'
import rest from '../rest/config'

export type IRest = IRestTypes<typeof rest>

type IAjax = {
  $rest: IRest
}


export default ajax as IAjax
  • 给全局挂上$rest的类型
import { IRest } from '@/ajax'
// *.d.ts
declare module 'vue/types/vue' {
  // Vue 的全局属性
  interface Vue {
    $rest: IRest
    navigateTo: Function
    navigateBack: Function
    $route: any,
    showWarningMessage: Function
    setEvaluateParams: Function
    showErrorMessage: Function
    redirectTo: Function
    $eventCenter: any
  }
}
  1. 如何改写typescript自动推导的类型?
import { ReWrite, PromiseResponse } from '@lx-frontend/ajax'
import rest from '../rest/config'

interface User {
    showPopup: (params: IShowPopupReq) => PromiseResponse<IShowPopupRes>
}
export type IUser = ReWrite<typeof rest.user, User>

export type IRest = IRestTypes<typeof rest>
export interface IRestConfig extends IRest {
    user: IUser
}
0.0.2

2 years ago

0.0.1

2 years ago