需求:
- 请求接口之后,缓存当前接口的数据,下次请求同一接口时拿缓存数据,不再重新请求
- 添加缓存失效时间
cache使用map来实现
ES6 模块与 CommonJS 模块的差异
因为esm输出的是值的引用,直接就是单例模式了
版本1
思路:
- 在vuex注册插件,插件会在每次mutations提交之后,判断要不要写入cache
- 在提交actions的时候判断是否有cache,有就拿cache里面的数据,然后把数据commit给mutataios
注意: 在插件里面获取的mutations-type是包含命名空间的,而在actions里面则是没有命名空间,需要补全。
/mutation-types.js
添加-CACHED
*/
export const SET_HOME_INDEX = 'SET_HOME_INDEX-CACHED'
/modules/home/index.js
const actions = {
/**
- @description 如果有缓存,就返回把缓存的数据,传入mutations,
- 没有缓存就从接口拿数据,存入缓存,把数据传入mutations
*/
async fetchAction ({commit},{mutationType,fetchData,oPayload}) {
// vuex开启了命名空间,所这里从cachekey要把命名空间前缀 + type + 把payload格式化成JSON
const cacheKey = NAMESPACE + mutationType + JSON.stringify(oPayload)
const cacheResponse = cache.get(cacheKey || '')
if (!cacheResponse) {
const [err,response] = await fetchData()
if (err) {
console.error(err,'error in fetchAction')
return false
}
commit(mutationType,{response: response,oPayload})
} else {
console.log('已经进入缓存取数据!!!')
commit(mutationType,{response: cacheResponse,oPayload})
}
},loadHomeData ({ dispatch,commit }) {
dispatch(
'fetchAction',{
mutationType: SET_HOME_INDEX,fetchData: api.index,}
)
}
}
const mutations = {
[SET_HOME_INDEX] (state,{response,oPayload}) {},}
const state = {
indexData: {}
}
export default {
namespaced: NAMESPACED,actions,state,getters,mutations
}
编写插件,在这里拦截mutations,判断是否要缓存 /plugin/cache.js
{
store.subscribe(({ type,payload },state) => {
// 需要缓存的数据会在mutations-type后面添加CACHED
const needCache = type.split('-').pop() === 'CACHED'
if (needCache) {
// 这里的type会自动加入命名空间所以 cacheKey = type + 把payload格式化成JSON
const cacheKey = type + JSON.stringify(payload && payload.oPayload)
const cacheResponse = cache.get(cacheKey)
// 如果没有缓存就存入缓存
if (!cacheResponse) {
cache.set(cacheKey,payload.response)
}
}
console.log(cache)
})
}
}
const plugin = cachePlugin()
export default plugin
store/index.js
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
home,editActivity,editGuide
}
plugins: [cachePlugin]
})
const store = new Vuex.Store({
modules: {
home,editActivity,editGuide
}
plugins: [cachePlugin]
})
export default store
版本2
思路:直接包装fetch函数,在里面里面判断是否需要缓存,缓存是否超时。
优化点:
- 把原本分散的cache操作统一放入到fetch
- 减少了对命名空间的操作
- 添加了缓存有效时间
/actions.js
在fetchOrCache判断是需要缓存,还是请求接口
{
if (cacheTimestemp) {
return ((Date.now() - cacheTimestemp) / 1000) <= diff
} else {
return true
}
}