【问题标题】:Vuex 2.0 Dispatch versus CommitVuex 2.0 调度与提交
【发布时间】:2017-03-16 09:11:44
【问题描述】:

有人能解释一下你什么时候会使用 dispatch 和 commit 吗?

我了解提交会触发突变,而分派会触发操作。

但是,调度不也是一种动作吗?

【问题讨论】:

    标签: javascript vue.js vuex


    【解决方案1】:

    正如你所说的,$dispatch 触发一个动作,commit 触发一个突变。以下是您可以如何使用这些概念:

    您总是在路由/组件中的方法中使用$dispatch$dispatch 向您的 vuex 存储发送消息以执行某些操作。该操作可以在当前滴答声之后的任何时间执行,因此您的前端性能不会受到影响。

    您永远不会从您的任何组件/路线中commit。它在操作中完成,并且在您有一些数据要提交时完成。原因:提交是同步的,可能会冻结你的前端直到它完成。

    让我们考虑这种情况:如果您必须从服务器获取一些 json 数据。在这种情况下,您需要异步执行此操作,以便您的用户界面不会无响应/冻结一段时间。因此,您只需 $dispatch 一个操作并期望它稍后完成。您的操作会执行此任务,从服务器加载数据并稍后更新您的状态。

    如果您需要知道某个操作何时完成,以便在此之前显示一个 ajax 微调器,您可以返回一个 Promise,如下所述(例如:加载当前用户):

    以下是您如何定义“loadCurrentUser”操作:

    actions: {
        loadCurrentUser(context) {
            // Return a promise so that calling method may show an AJAX spinner gif till this is done
            return new Promise((resolve, reject) => {
                // Load data from server
                // Note: you cannot commit here, the data is not available yet
                this.$http.get("/api/current-user").then(response => {
                    // The data is available now. Finally we can commit something
                    context.commit("saveCurrentUser", response.body)  // ref: vue-resource docs
                    // Now resolve the promise
                    resolve()
                }, response => {
                    // error in loading data
                    reject()
                })
            })
        },
        // More actions
    }
    

    在您的突变处理程序中,您执行源自操作的所有提交。以下是您如何定义“saveCurrentUser”提交:

    mutations: {
        saveCurrentUser(state, data) {
            Vue.set(state, "currentUser", data)
        },
        // More commit-handlers (mutations)
    }
    

    在你的组件中,当它是createdmounted时,你只需调用如下所示的动作:

    mounted: function() {
        // This component just got created. Lets fetch some data here using an action
        // TODO: show ajax spinner before dispatching this action
        this.$store.dispatch("loadCurrentUser").then(response => {
            console.log("Got some data, now lets show something in this component")
            // TODO: stop the ajax spinner, loading is done at this point.
        }, error => {
            console.error("Got nothing from server. Prompt user to check internet connection and try again")
        })
    }
    

    如上所示返回一个 Promise 完全是可选的,也是一个并非所有人都喜欢的设计决策。有关是否返回 Promise 的详细讨论,您可以阅读此答案下的 cmets:https://stackoverflow.com/a/40167499/654825

    【讨论】:

    • 很好的回应!非常详尽的例子。
    • 只是为了记录——你可以从一个组件提交——它应该是同步的(意味着没有 ajax)。问题不在于锁定前端 - 它是关于混乱的流程(我提交了一个更改,但它还没有 - 哦,ajax 没有完成..)如果你提交一个不需要的状态值可以在任何地方持久化,那么从组件中就可以了。这就是我从研究中得到的理解 - 欢迎更正。
    • @Yehosef 同意!这是我一年多前的理解,当时的文档建议始终从操作提交,而不是直接从组件提交。我同意你的观点,我们可以直接从组件中为简单值提交突变,只要我们确定它不会导致任何导致不可预测行为的竞争条件。
    • @Mani 当你想进行跨模块调用时,你提交或调度吗?
    • @Bertie92 我同意,我们应该能够直接提交小型应用程序。在概念层面上,我想将每个存储模块视为module pattern,将操作处理程序视为公共接口,并将提交视为私有方法。考虑到这种概念模型,直接提交相当于从外部调用模块的私有方法,这似乎有风险,但对于小型应用程序来说应该没问题。
    猜你喜欢
    • 2019-09-06
    • 2017-12-21
    • 2020-12-31
    • 2019-05-13
    • 2018-01-10
    • 1970-01-01
    • 1970-01-01
    • 2020-06-11
    • 2019-08-08
    相关资源
    最近更新 更多