vue的store、vuex状态管理
直接看官方文档很清楚https://vuex.vuejs.org/zh/guide/
说实话官网看的不是很懂,方便自己理解记录几个为什么;
1、流程
1.定义state变量
2.只有 mutations下面定义的mutation方法 能动 State,改变State
3.我们不能直接 store.mutations.increment()
来调用方法,Vuex 规定必须使用 store.commit
来触方法,官方解释如下图
总结,想要改变一个 State,必须要定义一个mutation函数去改变它,想要执行mutation函数必须使用 store.commit
来触发/调用,而不能直接 store.mutations.increment()
来调用方法;
2、为什么要通过提交 mutation 的方式来改变状态数据?
是因为我们想要更明确地追踪到状态的变化,如果你随便在一个地方就改了state.count这个属性的状态,项目大了的话,那就很难明确地追踪到状态的变化
定义mutation方法之后,想要追踪直接在方法里面调试记录就行了;
3、actions是干嘛的?直接用mutation改状态不就行了,还多此一举用actions去执行mutation去改State
首先你要知道mutation必须是同步函数(官方规定的,也就是函数里面不能有异步操作),所以想要异步操作就要action函数来处理,这就需要actions了;注意action提交的是 mutation,而不是直接变更状态
为什么mutation必须是同步函数?
当然你说我在mutation函数里面操作异步啥的也不会报错也没事啊?
是在mutation中执行异步操作并不会报错,也能正确更改状态,所以并不是所谓的“必须同步执行”这么苛刻,只能说你最好不要这么做,你非要这么做也没人说你,但是在 mutation 中混合异步调用会导致你的程序很难调试。
看下图官方解释:
1)如果像上图这样异步的话,我们就不知道什么时候状态会发生改变,所以也就无法追踪了,这与 Mutation 的设计初心相悖,所以强制规定它必须是同步函数。
2)上面的什么debug之类的我看得也有些懵,只能大概理解一下,比如想要调试console.log()打印一下state.count这个属性改变状态前是什么值,改变状态后是什么值
如果没有加那个异步函数,那就直接能打印出count改变前是0, count++改变后就是1,很方便就能调试到了。
现在搞一个异步函数在那,mutation函数已经触发了,那个异步回调函数还没有被调用,所以也就不知道什么时候才触发count++,就导致很难追踪调试;
3)假如异步操作是在action下面进行,那追踪调试的时候只要在mutation函数里面调试,就能很直观的知道state.count这个属性改变状态前后了;
4、提交载荷是啥意思 ?蒙蔽中。。啥生涩的词语;
就是官方给它取了一个高大上的名字:载荷(payload),下面的commit第二个参数就是载荷,大多数情况下,载荷是一个对象,也就是传一个对象进去;
5、vuex 的dispatch和commit提交mutation的区别
说白了就是在mutations下面定义的函数方法,就用commit触发执行,在actions下面定义的方法就用dispatch触发执行
store.commit('你的mutation方法),所以commit就是触发mutations下面定义的方法(注意,我们不能直接 store.mutations.increment()
来调用,Vuex 规定必须使用 store.commit
来触发对应 type 的方法:)
store.dispatch('你的action方法'), 所以dispatch就是触发actions下面定义的方法
可以试一试用dispatch调用mutations下面定义的方法,会不会报错反正我没试过;
6、vuex和localstorage的区别
1)最重要的区别:vuex存储在内存,localstorage则以文件的方式存储在本地
2)应用场景:vuex用于组件之间的传值,localstorage则主要用于不同页面之间的传值。
3)永久性:当刷新页面时vuex存储的值会丢失,localstorage不会。
4)ocalStorage用来存储需要持久化的数据,vuex启动时直接从localstorage获取持久化的数据就实现了应用的持久化的需求
7、为什么要使用vuex而不使用全局变量比如window;
用全局变量初期还好,如果项目复杂你定义的window各种变量就很乱,你就要对这个全局变量进行封装管理优化,更方便的调用,到最后你发现这个过程实际就是重复的造轮子,自己封装成了个vuex,何必呢;