Организовать свой код Axios по-другому?

Архитектура внешний интерфейс JavaScript

Поскольку Jquery был заменен на mvvm,$.ajaxОн также был заменен на axios.До использования этого метода, я думаю, большинство людей также думали об инкапсуляции запроса, а затем вызывать каждый раз, чтобы сделать службу запросов Get и Post.Некоторые люди привыкли писать прямо в vue.this.$axios.get(), редька и овощи имеют свою любовь, нет разницы между хорошим и плохим.

источник вдохновения

Напишитеd4axiosВдохновленopen-figen, Теперь функция не такая богатая, но ее достаточно для работы с большинством сценариев, таких как загрузка, загрузка, получение, отправка и другие запросы, с ts, он может решить согласованность типов данных спереди и сзади, преобразование тип данных, чтобы обеспечить удобство запроса. Пусть код сосредоточится на обработке данных, а не на копировании и вставке кода шаблона.

Не забудьте включить поддержку декораторов в файле [ts | js]config.json."experimentalDecorators":true

использовать в проектеd4axios

d4axios (Decorators for Axios)основан наaxiosГруппа методов декоратора метода запроса может быстро управлять службой и контролировать ее, улучшать метод запроса службы во внешнем интерфейсе, эффективно снижать когнитивную сложность службы и обеспечивать интерфейс данных внешнего и внутреннего интерфейса службы. согласуется в случае TS пола

npm i d4axios

yarn add d4axios

1. Импортировать информацию о конфигурации

Здесь представлены несколько методов настройки, вы можете использовать исходный метод настройки axios, или вы можете использоватьd4axiosпредоставленный метод

// 在 vue3下我们建议使用 `createService` 
// 其他情况下使用 `serviceConfig`
import { createApp } from 'vue'
import {createService,serviceConfig} from 'd4axios'


createApp(App).use(createService({ ... /* 一些配置信息 */}))

1.1 Предоставляемые элементы конфигурации Axios

createServiceа такжеserviceConfigИспользуемые элементы конфигурации одинаковы и полностью совместимы с конфигурацией axios. Для дооснащения существующего проекта можно использовать:

// 可以直接使用由d4axios提供的服务
createService()

// 可直接传入axios的相关配置,由d4axios自动基于配置相关构建
createService({axios:{ baseURL:"domain.origin" }})

// 可直接传入已经配置好的 `axios` 实例对象
const axios = Axios.create({ /* 你的配置*/ });


createService({axios})

1.2 Предоставление конфигурации на основе запроса и соответствующих данных

createService({
    beforeRequest(requestData){
        // form对象会被转为JSON对象的浅拷贝,但是会在该方法执行完后重新转为form对象
        // 你可在请求前追加一些补充的请求参数
        // 比如对请求体进行签名等等
        return requestData
    },
    beforeResponse(responseData){
        // 默认情况下会返回 axios的response.data值,而不会返回response的完整对象
        // 可以修改返回的响应结果
        return responseData
    }
})

1.3 Обеспечение быстрых аксиомinterceptorsнастроить

createService({
    interceptors:{
        request:{
            use(AxiosRequestConfig){},
            reject(){}
        },
        response{
            use(AxiosResponse){},
            reject(){}
        }
    }
})

После завершения настройки будет возвращен объект экземпляра axios, и вы сможете продолжить выполнять другие операции над объектом axios, который можно привязать к vue.prototype.$axios для использования.

Vue.prototype.$axios = serviceConfig({... /*一些配置*/})

2. Создайте сервис запросов

Чтобы лучше организовать бизнес-логику,d4axiosПредоставляет на выбор ряд организационных методов

import {Service,Prefix,Get,Post,Download,Upload,Param,After,Header} from 'd4axios'

@Service("UserService") // 需要提供一个服务名称,该名称将在使用服务的时候被用到
@Prefix("/user") // 可以给当前的服务添加一个请求前缀
export class UserService {

    @Get("/:id") // 等同于 /user/:id
    @After((respData)=>{
            //在输出给最终结果前,可以对结果做一些简单处理
            return respData 
    })
    async getUserById(id:string){
        // 异步请求需要增加 `async` 属性以便语法识别
        // 支持restful的方式
    }


    @Post("/regist")
    @Header({'plantform':'android'}) // 请求前追加一些header参数
    async registUser(form:UserForm){
        // 可以在请求的时候做一些参数修改
        form.nickName = createNickName(form.nickName);

        // return的值是最终请求的参数
        return {
            ...form,
            plant:"IOS"
        };
    }

    @Download("/user/card") // 支持文件下载
    async downloadCard(@Param("id") id:stirng){
        // 当我们的参数较少并且不是一个key-value形式的值时
        // 可以使用@Param辅助,确定传参名称
    }
    
    @Upload("/user/card") // 支持文件上传
    async uploadCard(file:File){
        return {file}
    }

    // 可以定义同步函数,直接做服务计算
    someSyncFunc(){
        return 1+1
    }

    // 我们还可以直接定义非请求函数
    async someFunc(){
        // 所有的当前函数都是可以直接调用的
        return await this.getUserById(this.someSyncFunc());
    }
   
}

3. Использование услуг

Существует несколько способов использования сервисов, первый — вызвать другой сервис в одном сервисе. Второй — вызвать службу в реакции или vue, для этих двух методов существуют разные, и один и тот же метод тоже можно использовать.

3.1 Использование в vue или реакцииuseServiceслужба импорта

// 在 vue 或者 react中,可以直接使用 useService 导入一个服务对象
import {useService} from 'd4axios'
import SomeService from './some.service'

const someService  = useService(SomeService)

3.2 В сервисеUseпозвонить в другую службу

import {Use} from 'd4axios'
import SomeService from './some.service'
// 也可以直接像上面一样的导入进来是用
const someService  = useService(SomeService)

@Service("MyService")
export class MyService {
    @Use(SomeService)  // use 导入服务
    // 默认的属性名为小写驼峰
    // 用 S<T> 包裹服务名称,这样可以得到相应的async方法的响应类型
    someService !: S<SomeService> 
    
    async someMethod(){
     // 就可以使用了,
      await this.someService.something();
    }
}

4. Переписывание ответа

По умолчанию d4axios поддерживает значение типа асинхронного ответа, т.е.

 export interface ResponseDataType<T> { }

Определите файл d4axios.d.ts в корневом пути проекта. Затем определите в файле, переписав этот тип, вы можете получить тип ответа типа ответа, например


export interface ResponseDataType<T> { 
    data : T;
    msg:string ;
    code:string ;
}

После этого вы можете получить оперативную информацию о соответствующем контенте.

dataType.png

5. Другие операции на основе декораторов

5.1 Может использоваться в классах, использующих декораторыUseУслуги импорта, такие как:

import {Component,Vue,} from 'vue-class-decorator'
import SomeService from './some.service'

@VueServiceBind(MyService,OtherService) // 只能在vue的这种形式下使用,可以绑定多个值
@Component
export default class MyVueComp extends Vue {

    @Use(SomeService)  // use 导入服务
    // 默认的属性名为小写驼峰
    // 用 S<T> 包裹服务名称,这样可以得到相应的async方法的响应类型
    someService !: S<SomeService> 

    myService !: S<MyService>

    otherService !: S<OtherService>
}

5.2 Это можно использовать в общих сервисах vue.mapServiceформа

// 传统的模式下

import { mapService } from 'd4axios';
import MyService from './MyService.service'

export default {
    computed:{
        ...mapService(MyService,OtherService)
    },
    created(){
        this.myService.getName(10086);
    }
}