vuex的mutations和actions的区别这么理解是否正确

发布于 2022-09-12 02:23:28 字数 436 浏览 9 评论 0

网上看了很多教程,都说的是mutations不支持异步,actions支持异步,但还是不太懂
今天看到别人的源码里,在actions里写了很多请求,有了点启发

我现在理解的是:

  1. 可以在mutations和actions里写异步请求,并被外部组件调用。但是在mutations里的异步请求成功后不能更新state,actions里的异步请求成功后可以commit调用mutations去更新state
  2. 如果我把异步函数写在外部组件里,请求成功后commit调用mutations更新state也是可以的

不知道这两个理解对不对?


如果上边两个理解正确,我突然又想到在mutations写两个函数A和B,A用来异步请求,B用来更新state,然后外部组件commit调用A异步请求成功后,A再commit调用B来更新state,这样是否可行?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

失退 2022-09-19 02:23:28

首先翻译一下你的问题,其实你的问题就一个

在vuex中更新state时,为什么将异步方法写在actions中,而不是mutations,这是为什么?

vuex中更新state的方法

首页,在 vuex 中只有 mutations 可以更新state

  • commit 一个 mutation,mutation 负责更改 state
  • dispatch 一个 action,在 action 中 commit 一个 mutation

所以按照上述使用方法,我们在使用时,如果不涉及异步操作,可以直接 commit 一个 mutation 去更改 state,如果有异步就需要将异步方法写在 dispatch 中,然后在 dispatch 中commit mutation 去更改 state

现在来回答开始提到的问题

我们从源码角度来回答这个问题,以下代码来自 vuex 源码,做了部分提示警告逻辑的删减,不影响整体逻辑,vuex 源码

// 这个就是 Store 类的 commit 方法
function commit (_type, _payload, _options) {
    // check object-style commit
    const {type, payload, options} = unifyObjectStyle(_type, _payload, _options)
    // 定义mutation对象,type 其实就是我们要操作的 mutation 的方法名, payload 是参数(载荷)
    const mutation = { type, payload }
    // entry 就是要被执行的 mutation 方法
    const entry = this._mutations[type]
    
    // 省略了一些中间不影响逻辑的代码
    
    // 注册一些回调函数,可以看到 mutation 方法(entry)最终是在这个回调函数中执行,直接就执行结束,没有任何的 return 以及 异步处理,这样也就是说在 commit 中不可以写异步逻辑
    this._withCommit(() => {
        entry.forEach(function commitIterator (handler) {
            handler(payload)
        })
    })
    this._subscribers
    .slice() // shallow copy to prevent iterator invalidation if subscriber synchronously calls unsubscribe
    .forEach(sub => sub(mutation, this.state))
}
function dispatch (_type, _payload) {
    // check object-style dispatch
    const {type,payload} = unifyObjectStyle(\type, _payload)
    // 定义 action 对象,type 是 actions 对象中的一个属性,payload 是载荷
    const action = { type, payload }
    // 待执行的 action 方法
    const entry = this._actions[type]
    try {
        this._actionSubscribers
        .slice() // shallow copy to prevent iterator invalidation if subscriber synchronously calls unsubscribe
        .filter(sub => sub.before)
        .forEach(sub => sub.before(action, this.state))
    } catch (e) {}
    
    // 在这里执行了 action 方法,并将结果用 Promise.all 方法处理
    const result = entry.length > 1
    ? Promise.all(entry.map(handler => handler(payload)))
    : entry[0](payload)
    
    // 这里的 result.then 执行完以后会 return 一个结果出去(其实就是我们自己调用的异步逻辑的结果)
    return result.then(res => {
        try {
            this._actionSubscribers
            .filter(sub => sub.after)
            .forEach(sub => sub.after(action, this.state))
        } catch (e) {}
        return res
    })
}
千秋岁 2022-09-19 02:23:28

这种你可以去看vuex的源码实现,不多,1天看的完的
在vuex里,改变state的唯一方法是提交commit来触发_mutations
而调用actions时会判断是不是Promise,调用异步处理
你在mutations里写情求他都不会跑then方法,你怎么改变

黑凤梨 2022-09-19 02:23:28

从另一个方面去理解,action,mutations都是vuex组成的一部分,

  • actions 类似于mutations, 大体归类到事件;
  • mutation像事件注册,需要相应的条件触发,action像是管理触发条件的

他们在vuex里各司其职,不用纠结为什么不在mutation里写异步请求,因为它就是这样设计的
如果好奇为什么要这样设计,楼上大神解释了源码,学习了学习了

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文