在 Vuex 操作中直接操作状态与使用“提交”和“获取者”

Ini*_*igo 5 vue.js vuex

我知道直接从商店外部(例如从组件)操作 Vuex 状态通常是不好的做法;但我正在努力了解从action 中读取/更改状态的最佳实践是什么。

据我所知,行动本身有一个context对象作为参数,从中可以得到的state,还有getterscommitdispatch作为属性。但我对使用这些的最佳实践感到困惑。例如:

      testAction: ({commit, getters, state}) => {

        if(state.foo === 'bar'){ // is this bad practice? 
            // ...do a thing
        }
        if(getters.getFoo === 'bar'){ // should I always read the state with a getter like this instead?
            // ...do a thing
        }

        commit('setFoo', 'foobar'); // do I always need to set the state via commit like this

        state.foo = 'foobar' // or is it fine to just do this?

      }
Run Code Online (Sandbox Code Playgroud)

请看评论。在动作中操纵状态的“正确”方法是什么?我总是需要使用commitgetters吗?如果是这样,为什么context对象甚至公开状态?你什么时候会在动作中使用它?谢谢。

Geo*_*esA 7

通过查看文档,更改操作的定义如下:

动作 动作类似于突变,不同之处在于: 动作不是改变状态,而是提交突变。动作可以包含任意异步操作。

突变 真正改变 Vuex 存储中状态的唯一方法是提交突变。Vuex 突变与事件非常相似:每个突变都有一个字符串类型和一个处理程序。处理函数是我们执行实际状态修改的地方,它将接收状态作为第一个参数:(...) 要记住的一个重要规则是突变处理函数必须是同步的

这是当务之急的是国家修改使用做了突变,否则更新不会正确地通过Vue公司的应用程序发出的,该组件将不会相应更新。但是您不会被迫使用操作来提交突变。您可以将操作视为允许您处理状态和异步方法的复杂更改的突变组合。因此,如果您的操作足够简单,请使用更改,否则使用操作。但是,请注意,由于突变是同步的,如果操作很重,它们可能会冻结您的前端,直到请求的操作结束(此处对 Akryum 进行了很好的解释,vuejs 核心成员))。

以类似的方式,getter 是一种“格式化”从商店检索的数据的方式,如文档中所述:

有时我们可能需要根据商店状态计算派生状态,例如过滤项目列表并对其进行计数。

这意味着如果您只需要状态中的一个简单密钥,则不需要创建 getter,您可以简单地从状态中检索所需的信息。

看看你的例子:

testAction: ({commit, getters, state}, testData) => {

    if(state.foo === 'bar'){ // is this bad practice? ==> Good to go !
        // ...do a thing
    }

    if(getters.getFoo === 'bar'){ // should I always read the state with a getter like this instead?  ==> Good to go ! but it depends on the way you can retrieve data from the state (like if you need to know the number of items within a list)
        // ...do a thing
    }

    commit('setFoo', 'testData'); // do I always need to set the state via commit like this  ==> **YES** !

    state.foo = 'foobar' // or is it fine to just do this? ==> never do this

}
Run Code Online (Sandbox Code Playgroud)

也为你的组件更容易集成VueX中,API公开了一组函数访问的存储属性,并以此作为计算的属性或方法: mapActionsmapMutationsmapGettersmapState