vuex刷新页面数据丢失怎么解决_你是否真正了解Vuex
![](/assets/blank.gif)
很久不写文章了,断了有一年多。这期间加入了新的团队做leader,认识新的朋友,迎接新的挑战。本应该坐下来整理自己的所见与所得,但又担心是否会起到作用,是否大家会认同。就像以前有一个朋友问我写这么多入门的文章有用吗?还有一些文章好像在自说自话。
其实还真是这样,反观自己的文章,其实大部分是自己写给自己的。越长大越孤单,很多想法,很多疑问,很多心里话其实是通过文章间接的与自己沟通。换个角度审视自己的行为与思想。
我也尽可能的想通过自己的文章传达一些技术之外的东西,要明白 “授之以鱼不如授之以渔”。除了技术技巧之外,有什么东西可以受用一生,可以帮助你更快掌握知识点,更快实现目标?我有很多要整理的内容,不放在这里细说,后面我会整理一下自己关于项目管理,团队管理,前端工作流,前端组件化,前端模板化,前端直播的一些成果,在这里和大家分享。
好了,回归正题,今天我们聊一聊 Vuex。看看大家是否真正完全掌握了 Vuex。过去一段时间,我发现大部分同学对技术的理解没有到达一定深度。只是停留在简单的知识点上,并没有深入的去进行思考。这就导致很多知识点其实并没有完全掌握。随便找一个方向进行深入发问,就会触到你的知识盲区。今天我们就对 Vuex 的各个点进行发问,以一个初学者的角度来重新认识下 Vuex
下面的内容中我会用各种问题来进行串联,请大家遇到我的提问时能先简单做下思考。有了结果后再看我的答案。我说的是我的理解,不一定就是对的,希望你也有自己的看法和理解,我的答案只是你心中的答案一个对照。
什么是 Vuex?
在官网的介绍中这样写到:
“Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。”
我们去了解一个技术方案时,第一步应该想清楚 “这个方案解决什么样的问题?”
Q: 那么第一个问题来了, Vuex 是为了解决什么问题呢?是什么样的问题让我们必须要用 Vuex 解决呢?
A: 我们说 Vue.js 是单向数据流模型。在单页面应用中,数据由父组件向子组件进行传递,子组件通过触发父组件事件的方式可以进行数据回传。想象这样一个场景,如果页面有复杂的组件嵌套,并且嵌套层次可能很深。这种情况下我们的数据需要通过 prop 一级一级向下传递,叶子组件的事件需要一级一级向上触发。这样的方式显然是不好的,我们希望父组件能够更方便的与各个子孙组件进行通信。再想象一个场景,单页面多路由的情况下,A页面需要传递数据给B页面,我们如何做路由间的数据传递呢?按照以往的解决方案,一般会选择 storage,cookie或者url携带参数来解决。这种方案也存在数据安全,数据传递大小限制等问题。以上的问题有没有一个更优雅的解决方案呢?
Q: 如果让你来解决以上的问题,不使用现有框架,有什么好的办法吗?
A: 如果我来实现,我会在window下设置一个变量,值为一个空对象。可以将所有需要传递的变量数据存储在这个对象中。通过 Object.defineProperty 对所有属性添加 set 监听,每当属性值发生变化时 通过 window.dispatchEvent 触发一个全局事件。该事件注册到所有组件中,每当属性变化时通知到各个页面与组件,再由各个组件进行取出单独处理。
我们再看下Vuex是不是这样做的,Vuex的核心结构包括:State,Getter,Mutation, Action, Module。我们把 State 看作是那个存储全部共享数据的对象。当你需要跨路由,跨组件进行数据共享时,把需要共享的数据保存到 State 中即可。Vuex 框架会帮你进行同步,只要有修改就会同步到各个组件中。并及时更新页面数据。
数据设置好之后,我们就可以在各个组件中使用 this.$store.state 来获取 state 对象并使用数据。当你需要修改数据时,你需要触发一个 mutation 来进行数据修改,官网的示例我们看下:
const store = new Vuex.Store({state: {count: 1},mutations: {increment (state) {// 变更状态state.count++}}
})
每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler), 在上面的例子中 type 为 increment当我们要修改 state 中的 count 属性时,需要这么做:
store.commit('increment')
通过触发 mutation 下的 increment 事件来修改 对此,官网也有一句解释:
“更改 Vuex 的 store 中的状态的唯一方法是提交 mutation”
Q: 第三个问题来了,为什么不能直接通过 this.$store.state.count = 3 来进行赋值?为什么不能直接对 state 下的数据进行赋值?为什么一定要使用 mutation?
A: 最初提出这个问题时,我听到两个回答是:
“mutation 保证数据可溯源”
“mutation更明确地追踪到状态的变化”
在官网我找到这么一段话:
”再次强调,我们通过提交 mutation 的方式,而非直接改变 store.state.count,是因为我们想要更明确地追踪到状态的变化。这个简单的约定能够让你的意图更加明显,这样你在阅读代码的时候能更容易地解读应用内部的状态改变。此外,这样也让我们有机会去实现一些能记录每次状态改变,保存状态快照的调试工具。有了它,我们甚至可以实现如时间穿梭般的调试体验。“
按照文档内容,上面的两个回答是没问题的。我们可以引申另一个问题:
Q: 数据为什么要溯源?为什么要记录每次状态改变?为什么要保存状态快照?
A: 首先,通过 this.$store.state.count 进行赋值是没有任何问题的,在非严格模式下这么写不会报错,数据修改可以被监听到。为什么非要使用 mutation 使数据可溯源呢?试想:
当我在A页面使用 this.$store.state.count = 10;
然后在B页面再次修改 this.$store.state.count = 3;
你是否可以观察到这个修改顺序?你不能,你只能看到修改的结果是 count 值为3,并不知道过程中是谁修改了他。为了在调试工具中观察到数据变化过程,我们统一使用 mutation 来修改数据,会有一个log系统记录下你的每一次修改,如图:
![](/assets/blank.gif)
理解了为什么必须使用 mutation 更新数据后,我们再来看一看 mutation 还有什么问题。在官网对 mutation 的介绍中有这么一句话:
”一条重要的原则就是要记住 mutation 必须是同步函数。“
Q: 为什么 mutation 必须是同步函数?我在接口请求的异步回调中执行 store.commit('increment') 可以吗?
A: 首先,官网的 mutation 必须是同步函数,是要求 mutation 下的每个事件的回调函数必须是同步代码。对 commit 触发事件的时机并没有要求,也就是你可以在任意异步方法中执行 store.commit() 来修改数据。为什么 mutation 的事件回调必须是同步代码呢?其实还是为了保证溯源的准确性,当遇到下面情况时:
store.commit('A');
store.commit('B');
store.commit('B');
我们希望观察数据变化时,log中能体现正确的执行顺序:A -> B -> C。当这其中任意一个方法是异步处理时,就有可能出现偏差,数据失真,加大了调试的复杂度,其结果可能是:A -> C -> B / C -> A -> B。所以这就是为什么 mutation 的事件回调必须是同步代码。
除了 mutation 外还有一个修改 state 的办法,就是通过 Action。Action 类似于 mutation,不同在于:
1. Action 提交的是 mutation,而不是直接变更状态。
2. Action 可以包含任意异步操作。
也就是说 Action 是 mutation 的包装,但是 Action 中可以执行异步代码。代码示例:
const store = new Vuex.Store({state: {count: 0},mutations: {increment (state) {state.count++}},actions: {increment ({ commit }) {setTimeout(() => {commit('increment')}, 1000)
}}
})
Q: 就因为异步执行代码就发明 actions 吗?actions 和 mutations 为何一个可以异步一个不可以呢?actions 如何保证溯源的准确性呢?
A: 还是那句话,了解一个方案时,要先看这个方案解决什么问题。actions 解决什么问题呢?试想,一个单页面应用下,在各个页面都要获取一下最新的活动数据,然后在接口请求成功后通过 store.commit('updateDialogData') 来更新全局数据。这样做是不是很傻,我们不能在一个公共的地方写这个数据请求吗?
mutations 下是不可以的。所以我们提供一个 actions。这样你就可以把之前需要写到各个组件,各个页面的异步代码放到一起统一管理了。通过 this.$store.dispatch('xxx') 来触发事件。这样的情况下如何保证正确溯源呢?以往我们是通过 mutations 下的 type 来记录历史的。此处同样可以根据 mutations 记录真实的数据变化。但他不是原始的操作顺序,原始的操作顺序需要按照 actions 的触发顺序记录。
与 actions 的做法类似,当我们每次取出 state 下的数据后都要进行一次格式化,那为什么不能在一个公共的位置统一处理呢?Getter 就是解决这个问题,内部包含了对 state 下数据的 格式化整理函数。
同理,当state上的数据堆积过多,我们需要划分不同的数据区时,Module 可以更简单的提供这个功能。
总结:
以上问题其实没有任何深度,只是记录了一次内部探讨过程。分享出来与大家共同学习。我们只需要多思考就可以明白作者为什么要这么设计,这样设计的好处是什么。但往往我们对一个知识点的深度理解就缺少这么几个问题。多去发现问题,提出问题,解决问题。这样才能够快速提高,做到知其然知其所以然。
以上,与君共勉。
vuex刷新页面数据丢失怎么解决_你是否真正了解Vuex相关推荐
- vuex刷新页面数据丢失怎么解决_vuex状态机浅谈
我最近项目上在使用vuex的过程中,遇到下面两个问题 F5刷新后,vuex中状态丢失 v-model需要与vuex结合 针对这两个问题,我的解决办法是 问题1:F5刷新后,vuex中状态丢失 解决办法 ...
- Ajax回退刷新页面问题的解决办法
Ajax回退刷新页面问题的解决办法 参考文章: (1)Ajax回退刷新页面问题的解决办法 (2)https://www.cnblogs.com/GooPolaris/p/7801828.html 备忘 ...
- vuex【解决方案】刷新页面数据丢失(两种方法)—— 含 vuex-along 教程
问题描述 存入vuex中的数据,在用户刷新页面后会丢失 原因解析 js代码运行时所有变量.函数都保存在内存中.刷新页面后,以前申请的内存被释放,脚本代码重新加载,变量会重新赋值. 解决方案一 sess ...
- vuex刷新state数据丢失问题
用vuex来做全局的状态管理时, 发现当刷新网页后,保存在vuex实例store里的数据会丢失. 1. 产生原因 其实很简单,因为store里的数据是保存在运行内存中的,当页面刷新时,页面会重新加载v ...
- js 刷新页面但是不闪烁_前端开发还在手动刷新页面?手把手教你搭建一个自动刷新工具...
作为一名前端,开发web页面是我们的本职工作.在完成一个页面开发的过程中,保存代码然后手动刷新页面查看效果,这样的动作需要重复无数次,虽然一次这样的动作可能只要花费几秒钟的时间,但是次数多了也挺浪费时 ...
- 浏览器 刷新页面后回到顶部_当你在浏览器中,忘记了曾经的登录密码怎么办......
当你在浏览器中,忘记了曾经的登录密码怎么办... 前言 你还在为使用浏览器的时候,忘记密码而烦恼吗?今天要分享的不为人知的小技巧,利用前端技术原理来帮助你找回原密码. 在我们使用各种网站登录时,总会勾 ...
- python selenium刷新页面_python selenium 解决页面刷新后元素找不到问题
1,问题: 当我们第一遍找元素是找到了,而你循环后页面已经新刷新,所以不能用第一遍找出的元素了 即:页面刷新后元素的属性是没变,但是element却变了,所有之前定位的元素element都过期了 2, ...
- 鼠标聚焦到Input输入框时,按回车键刷新页面原因及解决方法
参考地址:http://blog.csdn.net/xuezhongsong/article/details/6859037 方式1:全局控制回车,13-回车键,27-ESC,113-F2 docum ...
- 前端有关解决Vuex页面刷新之后数据丢失的问题
问:有关vuex刷新页面之后数据丢失的问题 答:vuex+缓存解决这个问题. 在使用vuex的时候,刷新页面之后在vuex中存储的数据会丢失,而缓存在刷新页面的时候数据是不会丢失的,所以把vuex和缓 ...
最新文章
- iOS App跳转权限设置
- vue 改变domclass_基于 vue 开发甘特图组件的心路历程(兼设计分享)
- java直接对list使用sql语句_Java和SQL语句阶段考试错题集
- linux:scp命令
- .NET6之MiniAPI(十八):OpenAPI swagger
- esc指令检查打印状态_【行业知识分享】八千字解读ESC系统
- 读书笔记—《销售铁军》随记7
- python龙卷风框架_WEB框架之Tornado
- HTML5+css3 的开心网游戏页面
- Oracle下载及安装超详细教程
- 中国互联网是如何起步的
- LOJ 6437 PKUSC2018 PKUSC
- [软件笔试] 2014暴风影音校招技术笔试题(长春站)
- 支付宝支付与提现转账问题小结
- 第12届信息化领袖峰会丨行程安排新鲜出炉
- ERP实施设防三大雷区(转载)
- Elementui蓝色阴影边框相关问题的解决方案
- 基于javaweb的房屋租赁系统(前端+后端)
- 教学管理系统-实验四 顺序图
- 递归和动态规划的一个区别(递归是自顶向下,然后返回计算;动态规划是自低向上运算)
热门文章
- Linux移植随笔 tslib
- 使用mvc模式读取服务器上的文件,关于C#:如何使用asp.net MVC应用程序从服务器上的网络路径读取...
- java分布式 mq_分布式系统消息中间件—RabbitMQ的使用进阶篇
- python try catch 能知道是哪一行代码_能导致3.7亿美元损失的异常,到底是怎么回事?...
- 大文件下载及视频点播的CDN加速实践
- sqlserver日期dateadd及STUFF等应用
- 3D角色设定全析百图斩
- 【JavaScript脚本】——T1基本语法
- sqli-labs(40)
- shell基础09 gawk程序(上)