MockApi装饰器方案

DONG HAO
2023-02-09 / 0 评论 / 174 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2023年02月09日,已超过435天没有更新,若内容或图片失效,请留言反馈。
在项目开发初期,需要前后端约定数据结构,Mock数据开发的时候,可以使用下面的MockApi
可以在控制台看到mock数据的结构,方便联调。

装饰器

import axios from 'axios'
import type { AxiosRequestConfig } from 'axios'
import { isFunction } from 'lodash'
import { Random } from 'mockjs'

export function MockGet(url: string) {
    return Mock({ url, method: 'GET', })
}

export function MockPost(url: string) {
    return Mock({ url, method: 'POST', })
}

export function MockPut(url: string) {
    return Mock({ url, method: 'PUT', })
}

export function resolve<T>(data: T, delay = 1000): Promise<T> {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve(data)
        }, delay)
    })
}
export function Mock(config: AxiosRequestConfig) {
    return function(target: any, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) {
        descriptor.value = function(...args: any[]) {
            return axios(config).then(({ data, }) => {
                // @ts-ignore
                const res = {
                    error_code: 0,
                    status: true,
                    data,
                }
                console.warn('Mock', `[${config.method}] ${config.url}`, res, args);
                return res.data;
            })
        }
        return descriptor
    }
}

/**
 * mockApiLog
 * @param type log类型
 * @param id logId
 * @param input 输入
 * @param output 返回
 * @param pending 耗时
 */
function mockApiLog(id: string, input: any, output: any, pending?: number) {
    console.group('%c%s(%s)', 'color:#0764E9;padding:2px;', '[MockApi]', id)
    console.log('%c耗时:', 'color:green;padding:2px;', `${pending} ms`)
    console.log('%c参数:', 'color:green;padding:2px;', input)
    console.log('%c返回:', 'color:green;padding:2px;', output)
    console.groupEnd();
}

export interface MockApiConfig {
    pending?: number,
}

/**
 * 拦截接口调用,返回mock数据
 * @param mock mock方法或者直接返回mock数据
 * @returns
 */
export function MockApi(mock: any, config?: MockApiConfig) {
    return function(target: any, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) {
        let { pending, } = config || {}
        if (pending === undefined) {
            pending = Random.integer(200, 2000)
        }

        const key = `${target.name}.${propertyKey}`

        descriptor.value = function(...args: any[]) {
            const output = isFunction(mock)
                ? mock.apply(this, [...args])
                : mock;

            const input = JSON.parse(JSON.stringify(args))
            return resolve(output, pending).then(data => {
                mockApiLog(key, input, data, pending);
                return data
            })
        }
        return descriptor
    }
}

使用

export function projectsMockData(...args: any[]) {
    const tagStructure = mock({
        'tagStructure|1-10': [
            {
                id: '@id',
                name: '@cword(1, 5)',
            }
        ],
    })
    return mock({
        'items|0-20': [{
            id: '@id',
            name: '@ctitle(1, 10)',
            icon: () => Random.pick(
                Random.range(1, 6).map(i => `${i}`)
            ),
            description: '@cword(6, 30)',
            'tags|3': [() => Random.pick(tagStructure.tagStructure).id],
            'members|0-16': [
                {
                    id: '@id',
                    name: '@cname',
                    email: '@email',
                }
            ],
            update_ts: '@datetime',
            created_at: '@datetime',
        }],
        ...tagStructure,
    });
}
@MockApi(projectsMockData, { pending: 1000, })
0

评论 (0)

取消