Vuex - “不要在突变处理程序之外改变 vuex 存储状态”

2024-04-30

我正在尝试从 Firestore 初始化我的 Vuex 商店。最后一行代码context.commit('SET_ACTIVITIES', acts)是什么造成了错误。我不认为我会直接改变状态,因为我正在使用一个动作。我可能会错过什么?

这是我的 Vuex 商店:

export default new Vuex.Store({
  strict: true,
  state: {
    activities: []
  },
  mutations: {
    SET_ACTIVITIES: (state, activities) => {
      state.activities = activities
    },
  },

  actions: {
    fetchActivities: context => {
      let acts = []
      let ref = db.collection('activities')
      ref.onSnapshot(snapshot => {
        snapshot.docChanges().forEach(change => {
          if(change.type == 'added') {
            acts.push({
              id: change.doc.id,
              name: change.doc.data().name,
              day: change.doc.data().day
            })
          }
        })
      })
      context.commit('SET_ACTIVITIES', acts)
    }
  }

另外,它给我的错误等于 Firestore 中的项目数。如果我只进行一次提交,为什么会这样做?

console:

[Vue warn]:观察者“function () { return this._data.$$state }”回调中出错:“错误:[vuex] 不要在突变处理程序之外改变 vuex 存储状态。”

and

Error: [vuex] do not mutate vuex store state outside mutation handlers.
    at assert (vuex.esm.js?2f62:87)
    at Vue.store._vm.$watch.deep (vuex.esm.js?2f62:763)
    at Watcher.run (vue.runtime.esm.js?2b0e:4562)
    at Watcher.update (vue.runtime.esm.js?2b0e:4536)
    at Dep.notify (vue.runtime.esm.js?2b0e:730)
    at Array.mutator (vue.runtime.esm.js?2b0e:882)
    at eval (store.js?c0d6:36)
    at eval (index.cjs.js?e89a:21411)
    at eval (index.cjs.js?e89a:4904)
    at LLRBNode.inorderTraversal (index.cjs.js?e89a:1899)

您遇到了对象引用和异步方法的问题。

CollectionReference#onSnapshot() https://firebase.google.com/docs/reference/js/firebase.firestore.CollectionReference.html#onsnapshot是异步的,触发快照监听器/观察者QuerySnapshot events.

基本上,代码中发生的事情是分配空数组acts to state.activities(相同的对象引用)在你的突变中,然后,在稍后的时间在你的snapshot事件处理程序,直接将元素推入其中。

一个快速的解决方案是在onSnapshot观察者

fetchActivities: context => {
  let ref = db.collection('activities')
  ref.onSnapshot(snapshot => {
    let acts = []
    snapshot.docChanges().forEach(change => {
      if(change.type == 'added') {
        acts.push({
          id: change.doc.id,
          name: change.doc.data().name,
          day: change.doc.data().day
        })
      }
    })
    context.commit('SET_ACTIVITIES', acts)
  })
}

如果您只想初始获取集合数据,请使用CollectionReference#get() https://firebase.google.com/docs/reference/js/firebase.firestore.CollectionReference.html#get反而。鉴于它返回一个承诺,您可以使用它来采取行动可组合的 https://vuex.vuejs.org/guide/actions.html#composing-actions

async fetchActivities ({ commit }) {
  let snapshot = await db.collection('activities').get()
  let acts = snapshot.docChanges().filter(({ type }) => type === 'added')
      .map(({ doc }) => ({
        id: doc.id,
        name: doc.data().name,
        day: doc.data().day
      }))
  commit('SET_ACTIVITIES', acts)
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Vuex - “不要在突变处理程序之外改变 vuex 存储状态” 的相关文章

随机推荐