Vuex和前端缓存的整合策略详解


Posted in Javascript onMay 09, 2017

如何存放或更新缓存?

缓存数据来源是预知的,我们可以预先定义哪些 mutation 是缓存相关的。

我们期望这个过程更自然一点,通过某种变化自动映射,使以后不管缓存类别增加还是减少都能修改极少的代码来应对变化。

Vuex的插件可以拦截 mutations,借助这个机制,我们可以制定一种策略化的规则。

可以规定,所有需要更新缓存的 mutationType 都要符合这种格式:module-type-cacheKey,非缓存的 mutationType 格式为 module-type。

那么就可以拦截 mutation,去做我们想做的事了:

store.subscribe(({ type, payload }) => {
 const cacheKey = type.split('-')[2]
 if (cacheKey) {
  Cache.save(cacheKey, payload)
 }
})

如何从缓存取数据避免请求?

只需要在缓存相关的 action 中加入缓存判断。

action
fetchData({commit}) {
 const cacheData = Cache.get(cacheKey)
 if(!cacheData) {
  Api.getData().then(data => {
   commit(mutationType, data)
  })
 } else {
  commit(mutationType, cacheData)
 }
}

设计优化

以上的确已经足够完成缓存 读取 --> 更新 的工作了。但试想一下将来某个其他数据类别要做缓存,我们就要把上面的代码格式再搬一遍。

即:把新的需要缓存的数据类别对应的 mutationType 加 cacheKey 后缀,把获取数据的 action 中加缓存判断。

虽然实际编码中也没有多大的工作量,但感觉还不是最好的开发体验。

action优化

action 中的痛点是:每次都需要重复写缓存判断。可以把这个判断过程拿出来放到一个大家都能访问到的公共的地方,且最好是与 Vuex 契合的。

Vuex 支持 action 相互调用,我们可以设置一个单独的 action 用来提交。

commitAction({ commit }, mutationType, getData) {
 const cacheKey = mutationType.split('-')[2]
 const cacheData = Cache.get(cacheKey || '')
 if(!cacheData) {
  getData().then(data => {
   commit(mutationType, data)
  })
 } else {
  commit(mutationType, cacheData)
 }
},
fetchData({ dispatch }) {
 dispatch('commitAction', mutationType, Api.getData)
}

不管是否需要缓存最终都走同一个 action 去提交,由这个 action 去做决策。

mutation优化

mutation 的痛点在于:加后缀啊!加后缀啊!!

如果一个数据的相关逻辑复杂,可能对应很多个 mutationType,每个都需要:加后缀!

要是代码能自动识别需要走缓存的 mutationType 就完美了!

mutationType 默认的格式为 module-type,假如业务中一个 module 对应一个数据类别,我们就可以基于 module 作缓存识别。

cacheConfig.js
export default {
 module1: 'key1',
 module2: 'key2',
 //...
}
action
commitAction({ commit }, mutationType, getData) {
 const module = mutationType.split('-')[0]
 const cacheKey = CacheConfig[module] || ''
 const cacheData = Cache.get(cacheKey)
 if(!cacheData) {
  getData().then(data => {
   commit(mutationType, data)
  })
 } else {
  commit(mutationType, cacheData)
 }
},
fetchData({ dispatch }) {
 dispatch('commitAction', mutationType, Api.getData)
}
interceptor
store.subscribe(({ type, payload }) => {
 const module = type.split('-')[0]
 const cacheKey = CacheConfig[module]
 if (cacheKey) {
  Cache.save(cacheKey, payload)
 }
})

当我们需要新增或减少缓存数据,只需要去 cacheConfig 中增加或减少一项模块配置。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
让您的菜单不离网站
Oct 03 Javascript
JavaScript 对话框和状态栏使用说明
Oct 25 Javascript
改写一个简单的菜单 弹性大小
Dec 02 Javascript
js语法学习之判断一个对象是否为数组
May 13 Javascript
js脚本实现数据去重
Nov 27 Javascript
jquery中show()、hide()和toggle()用法实例
Jan 15 Javascript
Node.js中的缓冲与流模块详细介绍
Feb 11 Javascript
javascript闭包概念简单解析(推荐)
Jun 03 Javascript
浅谈AngularJs指令之scope属性详解
Oct 24 Javascript
jQuery扩展方法实现Form表单与Json互相转换的实例代码
Sep 05 jQuery
一篇文章让你搞懂JavaScript 原型和原型链
Nov 23 Javascript
vue-router懒加载的3种方式汇总
Feb 28 Vue.js
基于JS实现限时抢购倒计时间表代码
May 09 #Javascript
js使用i18n实现页面国际化的方法
May 09 #Javascript
Angular中$state.go页面跳转并传递参数的方法
May 09 #Javascript
Vue 2.0中生命周期与钩子函数的一些理解
May 09 #Javascript
JavaScript中splice与slice的区别
May 09 #Javascript
详解node中创建服务进程
May 09 #Javascript
微信小程序 自动登陆PHP源码实例(源码下载)
May 08 #Javascript
You might like
php Undefined index和Undefined variable的解决方法
2008/03/27 PHP
PHP模块 Memcached功能多于Memcache
2011/06/14 PHP
一个实用的php验证码类
2017/07/06 PHP
Laravel5.7框架安装与使用学习笔记图文详解
2019/04/02 PHP
用JavaScript脚本实现Web页面信息交互
2006/12/21 Javascript
利用google提供的API(JavaScript接口)获取网站访问者IP地理位置的代码详解
2010/07/24 Javascript
服务器端的JavaScript脚本 Node.js 使用入门
2012/03/07 Javascript
JS隐藏参数post传值实例
2013/04/18 Javascript
js中Image对象以及对其预加载处理示例
2013/11/20 Javascript
javascript使用switch case实现动态改变超级链接文字及地址
2014/12/16 Javascript
php基于redis处理session的方法
2016/03/14 Javascript
jQuery遍历json的方法分析
2016/04/16 Javascript
原生Javascript和jQuery做轮播图简单例子
2016/10/11 Javascript
jQuery  ready方法实现原理详解
2016/10/19 Javascript
微信小程序图片自适应支持多图实例详解
2017/06/21 Javascript
EasyUI中的dataGrid的行内编辑
2017/06/22 Javascript
JavaScript页面倒计时功能完整示例
2019/05/15 Javascript
微信小程序云开发(数据库)详解
2019/05/17 Javascript
Python 文件操作技巧(File operation) 实例代码分析
2008/08/11 Python
python实现dnspod自动更新dns解析的方法
2014/02/14 Python
探究Python中isalnum()方法的使用
2015/05/18 Python
几种实用的pythonic语法实例代码
2018/02/24 Python
Django集成CAS单点登录的方法示例
2019/06/10 Python
Python3实现mysql连接和数据框的形成(实例代码)
2020/01/17 Python
Python面向对象中类(class)的简单理解与用法分析
2020/02/21 Python
Python抓包程序mitmproxy安装和使用过程图解
2020/03/02 Python
Python: tkinter窗口屏幕居中,设置窗口最大,最小尺寸实例
2020/03/04 Python
使用HTML5 Canvas为图片填充颜色和纹理的教程
2016/03/21 HTML / CSS
配置管理计划的主要内容有哪些
2014/06/20 面试题
大学自荐信
2013/12/12 职场文书
创业计划实施的7大步骤
2014/02/05 职场文书
竞选大学学委演讲稿
2014/09/13 职场文书
教师节感谢信
2015/01/22 职场文书
golang 生成对应的数据表struct定义操作
2021/04/28 Golang
mysql 8.0.24 安装配置方法图文教程
2021/05/12 MySQL
jackson json序列化实现首字母大写,第二个字母需小写
2021/06/29 Java/Android