Vuex

作者: LoveBugs_King | 来源:发表于2019-04-08 02:01 被阅读0次

    我们平时都会用vuex来管理Vue项目中的全局变量,觉得方便又好用。
    现在我们来更深入分析了解一下。

    为什么要出现Vuex?

        Vue开发的应用,页面渲染是组件粒度的,每个组件通过订阅 “响应式数据”,来更新组件渲染。组件嵌套组件形成树状结构的组件关系表
        这就出现了1个问题:如何做到多个组件共同订阅一个“响应式数据”,当其中1个组件通过监听事件对该数据做出改变,如何通知所有组件进行重新渲染?

        可能有人会说,实现全局变量方式很多呀。比如往Vue.prototype.xx进行扩展定义 或者 通过window.xxx定义。但是这样有两点问题
        1、比如把window.xx赋值给组件a中响应式属性num,当我们对window.xx进行修改,并不会触发数据num的set函数,也就无法重新渲染组件。而vuex可以做到。我们可以来看个例子:

    set函数未触发

        2、我们不能方便地跟踪每一个状态的变化,而vuex帮我们做到了,只要我们根据文档来操作。

        我们知道,vue的组件间数据传递的方式有几种:
        1、vue 2.0.3后,父子组件间数据传递支持双向流动。父组件中,通过:dataName.sync="data"把数据传给子组件,子组件通过props接受数据,子组件通过this.$emit('update:dataName', newValue)更新数据传递给父组件即可。
        2、eventBus任意组件间实现数据传递。比如两个组件a.vue和b.vue,我们先定义一个bus.js,其内引入Vue(import Vue from 'vue');暴露new Vue(export default newVue())。在两个组件中都引入bus.js(import Bus from 'common/js/bus.js';)。a组件通过Bus.$emit('funName', newVue)把数据传递出去,b组件通过Bus.$on('funName', target => {..})接受数据。

        一般来说,vuex的一个store模式就够我们的简单应用使用。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。

    Vuex的使用

    vuex的初始化,const store=new Vuex.Store({state(state:state的缩写),getters,mutations,actions})。

    一、组件中获取store中状态的方法

    1、在computed中获取
        可以在computed中通过store.state.count获取。缺点:组件依赖全局状态单例,在模块化的构建系统中,在每个需要使用 state 的组件中需要频繁地导入,并且在测试组件时需要模拟状态。
        所以我们一般在new Vue时把store对象注入,在computed中通过this.$store.state.count获取

    一般用法

    2、当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性,让你少按几次键:

    例子1

    当映射的计算属性的名称与 state 的子节点名称相同时,我们也可以给 mapState 传一个字符串数组。

    例子2

    通过扩展运算符,mapState 辅助函数与局部计算属性混合使用

    例子3

    二、getter模块的运用

        上面的介绍我们已经可以直接拿到状态了,并且能把状态拿来计算(比如上面的countPlusLocalState)。
        但是,我们如果在多个组件中都需要用到这种计算方法,在每个组件都要复制这个方法或者写成共享函数多处导入它,都不理想。
         于是有了getter这一层。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

    getter的定义,state是第一个参数,可以接受其他getter作为第二个参数

    如何取getter中定义的计算属性:
    1、在computed通过属性访问

    通过属性访问

    注意,getter 在通过属性访问时是作为 Vue 的响应式系统的一部分缓存其中的。
    2、可用mapGetters 辅助函数来简化操作

    通过...mapGetters混入 将一个 getter 属性另取一个名字,使用对象形式

    3、在computed通过方法访问

    让 getter 返回一个函数,来实现给 getter 传参,在对 store 里的数组进行查询时非常有用。

    注意,getter 在通过方法访问时,每次都会去进行调用,而不会缓存结果

    三、提交mutation来修改状态(同步)。

    1、mutation中函数的定义 和 普通提交mutation(this.$store.commit)。

    state 作为第一个参数,第二个参数是传的参数

    2、通过mapMutations辅助函数提交mutation(会将组件中的 methods 映射为 store.commit 调用,需要在根节点注入 store)。

    mapMutations辅助函数提交mutation

    使用常量替代 Mutation 事件类型。
            可以使 linter 之类的工具发挥作用,同时把这些常量放在单独的文件中可以让你的代码合作者对整个 app 包含的 mutation 一目了然。

    使用常量替代 Mutation 事件类型

    四、提交Action来修改状态(异步)。

    Action 类似于 mutation,不同在于:Action 提交的是 mutation,而不是直接变更状态。Action 可以包含任意异步操作。

    例子

    context 对象是一个与 store 实例具有相同方法和属性的对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。

    当我们需要调用 commit 很多次的时候:

     参数解构 来简化代码

    分发 Action。

    在action内异步调用操作 异步分发

    通过...mapActions来分发。

    使用 mapActions 辅助函数将组件的 methods 映射为 store.dispatch 调用

    相关文章

      网友评论

          本文标题:Vuex

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