美文网首页vue
3.关于Vuex五个核心概念的理解。

3.关于Vuex五个核心概念的理解。

作者: 似朝朝我心 | 来源:发表于2020-10-18 00:45 被阅读0次

    Vuex五个概念的简单理解。

    1.State 保存共享状态信息的地方。
    2.Getters 类似我们单个组件中的计算属性computed,只是它定义在Vuex中。
    3.Mutations 修改状态的地方。
    4.Actions 做异步操作的地方。
    5.Modules 用来专门划分模块的地方,针对不同的模块作数据保存。

    State 单一状态树

    • Vuex使用了单一状态树来管理应用层级的全部状态,单一状态树又叫单一数据源(即Single Source of Truth),也就是将所有的数据信息统一放到store对象进行管理,即使有更多的信息需要划分和管理,store对象有且只有一个,因为只有1个store的时候,能够让我们以最直接的方式找到某个状态的片对,方便我们之后的管理、维护和调试。

    • 如果你的状态信息是保存到多个Store对象中的(也就是说创建了多个store对象分散保留信息),那么之后的管理和维护变得十分艰难,所以说只有1个store对象就好。

    Getters 的基本使用,类似计算属性。

    • 各组件获取store对象中一些state变异后的状态。



      意味着,我们在任何一个组件都可以通过如下代码使用getters中定义的属性。



    Getters作为参数使用

    获取学生年龄>20的人数有几个?




    Getters传递参数

    • getters默认是不能传递参数的,如果希望传递参数,那么只能让getters本身返回一个函数。


    • 我们在上面传入一个参数22(为下面的年龄作判断age),


    • 检索我们stuInfo数组当中age>22的学生。


    • 符合要求的只有一个,Jhon的age是28岁。


    Mutations状态更新

    • 提交(commit)Mutation是Vuex的store状态中的唯一更新方式。

    • Mutation主要包括两部分:
      (1)字符串的事件类型(type)
      (2)一个回调函数(handler),该回调函数的第一个参数就是state

    • Mutation的定义方式:


      =
    • 通过mutation进行状态更新
      拿到我们的store对象,调用我们的commit方法,传入一个事件类型


    Mutations传递事件类型的同时携带参数过去

    在通过mutation更新数据状态的时候,是可以携带一些的而外的参数的,这些参数被称为mutation的载荷(Payload)





    上面演示了携带单个参数传递,倘若我们的参数不止一个的话,这个时候,我们需要通过以对象的形式进行传递,也就是Payload一个对象传递过去,这个时候,再从对象中取出相关的信息。




    Mutation提交的两种风格

    普通提交方式:通过commit进行提交。
    另一种特殊的提交风格:通过一个包含type属性的对象进行提交。




    • 当我们点击按钮的时候,可以看到我们在Mutation中接收的参数_count不再是一个简单的变量属性,而是一个对象了,所以这里使用_count来接收不再合适,而应该用payload来统一代替。



      所以我们可以直接从payload对象里面取出我们的参数_count进行累加


    Mutation响应规则

    Vuex的store对象中的state状态是响应式的,当state中的数据发生改变时,Vue组件会自动更新我们的界面视图。

    在state中定义的属性都会被加入到Vue响应式系统中,而响应式系统通过观察者模式会动态监听state中每个属性的变化,当state中某个属性发生变化时,响应式系统会通知所有界面中用到该属性的地方(组件),让界面发生刷新,(比如我们这里的state中有3个定义的属性:count,stuInfo,books,如果他们当中有某个属性发生变化,都会自动刷新视图)。

    简单的理解就是一种数据的联动,你变我也要跟着变,某个数据发生变化就会产生的一种连锁反应。



    效果图(连锁反应)如下:


    想要让state中的属性被加入到Vue响应式系统,必须遵守的Vuex响应式规则,规则如下:

    • 提前在store对象中进行初始化好我们需要的属性。

    如果没有提前在store对象中初始化我们需要的属性,则state中的属性不会被加入到Vue响应式系统。

    例子:




    点击按钮查看效果:

    总结:通过数组的索引值修改数组的元素本身就是不支持的,也不会加入响应式系统中,倘若真的要向state对象中赠添某个新属性时,可以使用.splice()方法或Vue.set()方法,或者用新对象给旧对象重新赋值

    Vue.set(传入三个参数)方法使用:Vue.set(第一个参数要改哪个对象?第二个参数传入的是对象或者数组,对象用key键(字符串),数组用number下标,第三个参数,你要传入的值)

    对象用key键获取



    数组用下标:




    Vue.delete()方法可以实现响应式删除。


    Mutation类型常量--搬砖转换

    • 在mutation中,如果我们定义了很多事件类型(也就是其中的方法名称太多了)就很容易混淆写错)
      就像这个样子:


    • 当我们的项目在不断增大时,同时Vuex管理的状态也会变得越来越多,那么意味着Mutation中的方法也会越来越多,这也意味着使用者需要花费大量的精力去记住这些方法,甚至在多个文件之间来回切换,查看方法名称,甚至如果不是复制,自己手动敲代码还会写错事件类型。

    当我们的事件类型名称是一致时,就可以使用类型常量进行转换了,避免纠错。



    Mutation类型常量转换的具体步骤(以事件类型:increment为例子作为展示)

    • 在src/store目录下创建一个mutation_type.js文件。



    • 在App.vue文件中导入已经定义好的INCREMENT常量。


    • 在App.vue函数methods定义中我们就可以这样来提交Mutation了,用定义好的常量INCREMENT替换我们的事件类型'increment'。


    • 来到store/index.js文件下我们就可以到mutations中来这样替换事件类型increment了。

    首先同样得导入定义好的常量INCREMENT



    • 这样写的好处


    在Mutation中进行异步操作的弊端

    • 通常情况下,Vuex要求我们在mutations中定义的方法必须是同步的,因为同步的方法可以让devtools捕捉到mutations的快照,但如果是异步操作,这个时候的devtools工具将会变得愚钝了,它并不能很好追踪到mutations中的这个方法操作到底什么时候会被完成。

    • 下面我们以异步操作(setTimeout定时器)作为例子测试devtools跟踪mutations方法时的灵敏度。


    • 我们打开devtools查看状态记录,在mutation中进行异步操作测试,看下devtools工具到底会不会帮助我们实时更新数据的最新状态。


      小结:在mutation中不能有异步操作,只能有同步方法,如有异步操作,必须放到actions里面。

    actions 放置异步操作,它的功能和mutations类似。

    • actions有个类似mutation中传入的state参数,actions它也有个自己的参数叫context(上下文),这个参数context可以理解为整个store对象,也可以理解为指向this.store对象。


    • 那是不是意味着我们可以直接绕过mutations,执行actions操作呢?



    • 答案是可以的,但不推荐这么做,为什么呢?我们可以看下官方的图。


    • 我们看到上面的图执行actions操作的时候有个提交commit方法,因为actions中的参数context相当于一个store对象,所以我们可以直接使用context.commit( )方法。



    • 小结:我们可以看下官方的思维图,理清思路.


    • 拓展:我们的mutations是可以传递参数的,actions是否能传递参数payload呢?答案是可以的。


    • 既然组件定义的methods里面可以传递一个参数?那能否传递过去一个箭头函数呢?其实也是可以的。


    • 如果组件中的methods能传递一个参数,还可以传递一个箭头函数作为参数,那能否同时传递一个参数和一个箭头函数过去呢?也是可以的,只是这时候的携带参数要写成一个对象的形式。


    • 但这种方式不够优雅,因为我们携带的参数和我们携带的回调函数混在一起了,我们要做的就是分离。


    Vuex的modules核心概念

    • modules是模块的意思,为什么需要在Vuex中使用模块化开发思想呢?
    • Vue使用了单一状态数的核心概念,至始至终都只能有且只有一个store对象,那么也就意味着很多状态都要交给Vuex大管家来进行管理。
    • 如果我们的应用变得非常复杂的时候,store对象中的代码量就有可能变得相当的庞大和臃肿,不利于后期的维护查看。
    • 为了解决这个问题,Vuex允许我们开发者使用模块化的开发思想,将一个非常庞大的store大对象分割成一个个小模块(modules)进行管理,而每一个小模块又可以单独抽离出来组成一个单文件,从而进行组织管理。
    • 这种单文件组织的模块化开发使每个独立的模块都拥有了自己的state、mutations、actions、getters。

    modules模块是Vuex针对state单一状态树核心,而提出来的一种将代码块抽离成一个个单文件进行管理开发和维护,让开发者具备模块化开发思想,简单点就是是为了避免Vuex代码篇幅过大,避免代码过于臃肿而提出的一种解决方案思路,方便开发者后期的维护。

    多个模块划分思路

    我们在modules里面定义a、b、c模块都可以拥有和store对象一样的对象属性 。


    简单的模块抽离组织思路

    如何使用modules属性对象中细分出来的单独模块下的state、mutations、actions?

    1.模块中使用state案例

    • 如果我们打开devtools查看state的话,会发现一件非常有意思的事情。


    • 模块中访问state的实现机制,它不关心你的state到底是定义在模块里面还是定义在store这个大对象里面,反正它最终就是能访问到store对象中的state。



    • state取值


      2.模块中使用mutations案例

      3.模块中使用getters案例

    • getters作为参数传递,拿到上层的getters使用


    • getters的第三个参数rootState获取store大对象中的state数据



      4.模块中使用actions案例
    • 注意:模块这里actions访问的是属于模块内部自己的mutations,而不是store大对象里面的mutations,模块中actions区别于state,不会自动添加进store大对象中去.




    • 打印模块中的actions里面的context看看有什么?



    • 模块actions中传多个参数的另外写法:对象的结构赋值
      关于对象的结构赋值上手概念理解:



    项目结构拆分:将store大对象中的state、getters、mutations、actions、modules分别抽离成单个文件放置。

    按照这种模块化的开发思想,所以我们要好好组织一下,重构我们之前的臃肿代码(将state、getters、mutations、actions、modules都写在一个文件里面是不推荐的)。

    操作state

    操作mutations(官方不推荐我们在store对象保留mutations,而state是推荐保留的,因此我们要将mutations抽离成单文件)


    然后来到index.js进行导入,接着在store对象中使用即可。



    getters、actions抽离成单文件,操作同上。

    moudules抽离成单文件,因为模块可能有多个,官方推荐我们建一个文件夹放置模块。

    相关文章

      网友评论

        本文标题:3.关于Vuex五个核心概念的理解。

        本文链接:https://www.haomeiwen.com/subject/kmpwpktx.html