「这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战」
前言
数据字典相信大家都不陌生,项目中总有一些数据,要是用枚举就面临偶尔改动的问题,要是在数据库中单独用一张表来存,又太浪费了。这就出现了数据字典这个东西。
类似数据字典这类数据并不常变,而且这些数据又经常是用来辅助其他数据的展示。比如说类别,通常后台存的是类别code,但在前台我们要展示的是name。
这类接口呢又不只在一个模块中使用,比如说列表中需要展示类别名,然后点开后再详情里有要展示,查俩次接口确实是能解决问题,但大佬们,我们要有点追求,给后台减点负,我们自己也省点力。
原理说明
既然不查接口,自然数据要做缓存,有缓存就读缓存,没缓存就找接口要。 so easy!
用缓存,我们常用的是localStorage、sessionStorage,其他的 IndexedDB、WebSQL等就不提了。
这里考虑到数据还是有更新的,所以说相对localStorage来说,sessionStorage还是更合理,毕竟sessionStorage网页被关了还是会自动清的。我的项目是vue的,我用的是vuex,因为顾虑到一旦数据发生变动,所有页面展示需要跟着变动。
实现
既然需要做缓存,我们需要在请求外包一层,所以关键逻辑就是这样:
function getDictData(name, isRefresh=false) {
// 考虑到有强行更新缓存的逻辑, 假设数据存在store里
if (!isRefresh && store.[name]) {
return new Promise(function(resolve, reject) {
resolve(store[name])
})
}
// 这里通过请求来获取数据, 这里
return new Promise(function(resolve, reject) {
api.getDictData(name).then(res=> {
// 这里需要一些处理,把数据放到缓存里,所以多包一层
dispatch('saveDictData', {
name,
data: res.data
})
resolve(res.data)
}, (error) => {
reject(error)
})
})
}
这个方法返回的是Promise, 所以大家现有的项目现在改,也非常的简单。直接替换原来的接口请求部分。
(这里就不提供存数据的方法了,相信大家对vuex非常熟悉了,不熟悉的话,可以用sessionStorage)
用的时候可以分俩种了,在不确定数据存储有没有的情况,直接调用getDictData方法;在确定有,比如详情弹窗,就可以使用vuex获取state的方法来获取。
探讨
原来有过在接口拦截的层面做这个缓存想法,通过添加hooks来做,过滤url和参数,只是我们的项目本身在接口拦截这层做了不少事,就没再在这里加这个了。各位可以根据自己的项目试试, 有其他方法也欢迎分享!