Skip to content

52.mutation 和 action 的区别

  • 在 action 中可以处理异步逻辑,可以获取数据后将结果提交给 mutation,mutation 中则是修改 state。
  • 在 action 中可以多次进行 commit 操作,包括 action 中也可以调用 action。
  • 在非 mutation 中修改数据,在严格模式下会发生异常
  • dispatch 时会将 action 包装成 promise,而 mutation 则没进行包装

1.action 异步逻辑

js
dispatch (_type, _payload) {
    // ...
    const result = entry.length > 1
    ? Promise.all(entry.map(handler => handler(payload)))
    : entry[0](payload)

    // 最终返回promise
    return new Promise((resolve, reject) => {
        // 等待所有action执行完毕
        result.then(res => {
            // ...
            resolve(res)
        }, error => {
            // ...
            reject(error)
        })
    })
}
dispatch (_type, _payload) {
    // ...
    const result = entry.length > 1
    ? Promise.all(entry.map(handler => handler(payload)))
    : entry[0](payload)

    // 最终返回promise
    return new Promise((resolve, reject) => {
        // 等待所有action执行完毕
        result.then(res => {
            // ...
            resolve(res)
        }, error => {
            // ...
            reject(error)
        })
    })
}

2.严格模式下发生异常

源码

js
class Store {
  commit(_type, _payload, _options) {
    this._withCommit(() => {
      // commit 中的处理
      entry.forEach(function commitIterator(handler) {
        handler(payload);
      });
    });
  }
  _withCommit(fn) {
    const committing = this._committing;
    this._committing = true;
    fn(); // 如果函数内部有异步修改状态逻辑,则watch时会报错
    this._committing = committing;
  }
}
class Store {
  commit(_type, _payload, _options) {
    this._withCommit(() => {
      // commit 中的处理
      entry.forEach(function commitIterator(handler) {
        handler(payload);
      });
    });
  }
  _withCommit(fn) {
    const committing = this._committing;
    this._committing = true;
    fn(); // 如果函数内部有异步修改状态逻辑,则watch时会报错
    this._committing = committing;
  }
}
js
function enableStrictMode(store) {
  watch(
    () => store._state.data,
    () => {
      if (__DEV__) {
        assert(
          store._committing,
          `do not mutate vuex store state outside mutation handlers.`
        );
      }
    },
    { deep: true, flush: "sync" } // 同步监控
  );
}
function enableStrictMode(store) {
  watch(
    () => store._state.data,
    () => {
      if (__DEV__) {
        assert(
          store._committing,
          `do not mutate vuex store state outside mutation handlers.`
        );
      }
    },
    { deep: true, flush: "sync" } // 同步监控
  );
}

Released under the MIT License.