vue3+ts+axios 数据缓存器

1,249 阅读2分钟

1.起步,在utils中新建cache.ts

/**
 * 对请求的数据进行缓存
 */
import { ReqResponse } from '@/shims';
import { isBoolean } from 'lodash';
import { App } from 'vue';

export default class Cacher {
  private static cacher?: Cacher;
  private cacheObj: Map<string, any>;//数据容器
  private capacity: number = -1;//缓存数量
  private capacityArr: string[];//api 容器
  static instance = this.getInstance();// 获取缓存实例

  //设置私有构造
  private constructor() {
    this.cacheObj = new Map();
    this.capacityArr = []
  }
  private static getInstance() {
    if (!this.cacher) {
      this.cacher = new Cacher();
    }
    return this.cacher
  }
  /**
   * 设置最多存储多少个数据  超出会将一个数据删除
   * @param num capacity size
   */
  setCapacity(num: number) {
    console.log('设置缓存数量----:', num)
    this.capacity = num
  }
  /**
   * 存储数据
   * @param api data key
   * @param data  data
   * @returns 是否成功
   */
  private set(api: string, data: any): Boolean {
    this.cacheObj.set(api, data);
    return true
  }
  /**
   * 根据api去缓存中查找数据 如果没有就去请求数据
   * @param api is request url
   * @returns axios responese
   */
  private get(api: string): any {
    if (this.cacheObj.has(api)) {
      this.capacity < this.capacityArr.length && this.shift(api)
      return this.cacheObj.get(api)
    } else {
      return false
    }
  }
  /**
   * 将前的api移到最后,防止超出容量被删除
   * @param api 
   */
  private shift(api: string) {
    const _index = this.capacityArr.indexOf(api)
    const _del = this.capacityArr.splice(_index, 1)[0];
    this.capacityArr.push(_del)
  }

  /**
   * 根据api去删除缓存中的数据
   * @param api 
   * @returns 
   */
  remove(api: string): Boolean {
    return this.cacheObj.delete(api)
  }
  /**
   * 超出容量删除第一个数据
   * @param api data key
   */
  private handle(api: string) {
    this.capacityArr.push(api);
    if (this.capacity && this.capacityArr.length > this.capacity) {
      const _d = this.capacityArr.shift();
      _d && this.remove(_d)
    }
  }
  /**
   * 获取数据
   * @param call axios 回调函数
   * @returns 
   */
  getData(call: (res: any) => Promise<ReqResponse.Result<ReqResponse.Data>>) {
    return (api: string, params: {}) => {
      const _this = this;
      return new Promise((resolve, reject) => {
        //获取缓存中的值 如果没有就去请求
        let data = _this.get(api);
        if (isBoolean(data)) {
          console.log('请求后端---222---')
          call(params).then(res => {
            _this.set(api, res);
            _this.handle(api)
            resolve(res);
          }).catch(err => {
            reject(err)
          });
        } else {
          console.log('在前端缓存中得到的数据---111---')
          resolve(data);
        }
      });
    };
  }
}
export const Cache = {
  install: function (app: App, capacity?: number) {
    //设置缓存数量
    capacity && capacity > 1 && Cacher.instance.setCapacity(capacity)
  }
}

2.在api中使用

import { ReqResponse } from '@/shims';
import axios from '@/utils/axios';
import Cacher from '@/utils/cache';

/**
 * 登录
 * @param data {username password}
 */
const login = (params: {}) => {
  const url = `/miniAuth/oauth/wechat/token`
  const begin = Cacher.instance.getData((data: {}) => {
    return axios.request<ReqResponse.Data>({
      url: url,
      method: 'POST',
      data,
    });
  });
  return begin(url, params)
};

//使用
login({ openId: '123456', nickname: '', headimgurl: '' }).then((res: any) => {
  console.log('我是返回的参数--', res.data);
});

3.如果需要设置缓存api的个数的话

import {Cache} from '@/utils/cache'
 //我这里设置的是3个
createApp(App).use(Cache,3).mount('#app');

shims.d.ts

import { AxiosRequestConfig } from 'axios';
import Cacher from '@/utils/cache'
namespace ReqResponse {

  export interface Result<T = any> {
    code: number;
    msg: string;
    data: T;
  }

  export interface Data {
    error_code: string;
    error_description: string;
  }
}

declare module 'axios' {
  export interface AxiosInstance {
    request<T = any, R = ReqResponse.Result<T>>(config: AxiosRequestConfig): Promise<R>;
    get<T = any, R = ReqResponse.Result<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
    delete<T = any, R = ReqResponse.Result<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
    head<T = any, R = ReqResponse.Result<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
    options<T = any, R = ReqResponse.Result<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
    post<T = any, R = ReqResponse.Result<T>>(url: string, data?: any, config?: AxiosRequestConfig): Promise<R>;
    put<T = any, R = ReqResponse.Result<T>>(url: string, data?: any, config?: AxiosRequestConfig): Promise<R>;
    patch<T = any, R = ReqResponse.Result<T>>(url: string, data?: any, config?: AxiosRequestConfig): Promise<R>;
  }
}
首次发文,请大家多多指教