3.2. 将后端传过来的key转成value显示(一般在表格中)。
现在来看第二种使用方式,这种方式一般在表格里面,当我获取表格数据的时候,假如里面有一项数据代表性别,后端给我的是一个 key 值,我在展示的时候需要将这个 key 转成 value。这个问题我最先想到的解决办法是vue的过滤器,但是过滤器又不能支持异步,如果非要使用过滤器的话(函数也一样),我必须在每次使用前先初始化字典数据,但是这样我就没法完全将字典相关代码从业务中脱离出来。(我花了很长时间寻找过滤器的异步方式,现在已经放弃了,根本没有。)
假如我使用一个组件。但是这样的话就和DictSelect一样了,假如表格页大小为10,那它就会同时发起10条相同的请求,这是真的接受不了。
3.3.逻辑判断
第三种情况,没有合适办法,只能在代码中写死。
我封装了一个专门用来请求字典的函数, 他有两个逻辑:
每次发起请求时将当前请求的 Promise 存起来,请求结束后将Promise改为null,每次发起请求时先判断Promise是否存在,如果有就直接返回。这样可以处理那些同一时刻发起多个请求的问题。
发起请求之前先判断 Loca Storage 中是否有缓存,如果有直接取出来,没有的话再发起请求,成功之后会先缓存一份。
/**
* 对get请求进行包装
* 提供数据缓存和防止同时发起相同的请求
* 相同的路径就可以理解为相同的请求
*/
import request from "@/utils//axios";
const promiseRecord = {}; // 用于缓存请求状态
/**
* 通过路径和参数生成唯一字符
* @param {*} apiUrl
*/
const createKey = (apiUrl) => {
return apiUrl;
};
// 普通的 get 请求
const get = (apiUrl) => request.get(apiUrl)
/**
* 用来发起需要缓存的请求
* @param {String} apiUrl
* @param {Boolean} refresh 可能在某些情况下不能使用缓存必须到后台获取
*/
const getCache = (apiUrl, refresh = false) => {
// 用请求路径和参数生成标识,完全相同的请求的标识一样,作为储存的键
let keyName = createKey(apiUrl);
return new Promise((resolve, reject) => {
let data = sessionStorage.getItem(keyName);
let request = () => {
get(apiUrl)
.then((value) => {
sessionStorage.setItem(keyName, JSON.stringify(value));
resolve(value);
})
.catch((error) => {
reject(error);
});
};
if (data && !refresh) {
// 如果用户手动修改了 sessionStorage 里的数据可能会出错,应该做下处理
try {
resolve(JSON.parse(data));
} catch (e) {
request();
}
} else {
request();
}
});
};
/**
* 防止重复处理
*/
const repeat = (apiUrl, request, refresh) => {
// 用请求路径和参数生成标识,完全相同的请求的标识一样,可以使用同一个请求结果
let keyName = createKey(apiUrl);
if (!promiseRecord[keyName]) {
promiseRecord[keyName] = new Promise((resolve, reject) => {
request(apiUrl, refresh)
.then((value) => {
promiseRecord[keyName] = null;
resolve(value);
})
.catch((error) => {
promiseRecord[keyName] = null;
reject(error);
});
});
}
return promiseRecord[keyName];
};
/**
* 返回请求的函数
* @param {String} apiUrl
* @param {Object} options 配置项
*/
const getAxios = (apiUrl, options = {}) => {
// 默认配置
let defaults = {
cache: false, // 是否开启缓存
repeat: false, // 是否开启防止同时发起相同的请求
refresh: false, // 是否刷新(这里也不能保证会刷新,因为get也有缓存,只能保证它会发出请求)
};
let _options = Object.assign(Object.assign({}, defaults), options);
// 什么都不需要 返回原始的axiso get请求
if (!_options.cache && !_options.repeat) {
return get(apiUrl);
}
// 只需要缓存
if (_options.cache && !_options.repeat) {
return getCache(apiUrl, _options.refresh);
}
// 只需要防止同时发起相同的请求
if (!_options.cache && _options.repeat) {
return repeat(apiUrl, get);
}
### 最后
![前15.PNG](https://img-blog.csdnimg.cn/img_convert/2b7847b6b8a0c5d63632bb2525c4688c.webp?x-oss-process=image/format,png)
![前16.PNG](https://img-blog.csdnimg.cn/img_convert/ab64f3e42255f1ddf1450b8bad390d1c.webp?x-oss-process=image/format,png)
>由于文档内容过多,为了避免影响到大家的阅读体验,在此只以截图展示部分内容
>
// 只需要防止同时发起相同的请求
if (!_options.cache && _options.repeat) {
return repeat(apiUrl, get);
}
### 最后
[外链图片转存中...(img-rxkTHlEq-1718090635332)]
[外链图片转存中...(img-sUtpIJ8h-1718090635333)]
>由于文档内容过多,为了避免影响到大家的阅读体验,在此只以截图展示部分内容
>