观看Vuex状态更改与v模型无法按预期工作的情况

时间:2020-03-19 04:57:37

标签: javascript vue.js vuex

我已经用Vuex创建了一个全局错误状态,我没有一个包含所有当前错误对象的数组。

ShowPhonebook

我有一个组件,可以使用Vuex状态动态显示所有错误,而我想做的是删除所有将error属性设置为false的对象,该错误属性状态由setError突变处理,并且组件内部的v-model属性。

我正在尝试通过观察更改并从数组中删除所需的项来做到这一点,但是当属性更改为false时,它并不能正确删除,我该如何实现呢?

这是现场演示https://codesandbox.io/s/vue-template-h5hf7

const store = new Vuex.Store({
  state: {
    errors: []
  },

  getters: {
    getErrors: state => state.errors
  },

  mutations: {
    setError: (state, message) => {
      state.errors.push({ error: true, message });
    },
    removeError: (state, i) => {
      state.errors.splice(i, 1);
    }
  }
});

1 个答案:

答案 0 :(得分:2)

您的观察者将仅直接响应数组的突变(例如正在添加或删除数组的项)。为了也观察阵列中项目的变化,您需要使用深度监视程序。

此外,每当遍历数组并同时从数组中删除项目时,都应以相反的顺序进行迭代,否则会丢失某些元素。

watch: {
  getErrors: {
    deep: true,
    handler(newErrors) {
      for (let i = newErrors.length - 1; i >= 0; i--) {
        if (!newErrors[i].error) {
          newErrors.splice(i, 1)
        }
      }
    }
  }
}

请注意,这可能会触发对处理程序的另一次调用,因为您正在更改要观察的事物。


编辑

感谢codesandbox

问题与<v-snackbar>不更新模型有关。我不确定如何实现<v-snackbar>,但似乎重用该组件时,其超时将被取消,并且不会发出input事件。由于同时添加和删除了多个错误,因此某些组件被重用。

您需要做的是将每个<v-snackbar>正确地键入相同的error对象。现在,您可以使用数组中的索引键对它们进行键控,但这会随着从数组中删除元素而改变。因此,我们必须为每个错误对象提供自己的唯一ID。

以下是您需要进行的代码更改的摘录:

// Define this at file-level
let nextKey = 1

mutations: {
  setError: (state, message) => {
    state.errors.push({
      key: nextKey++,
      error: true,
      message,
    })
  }
}
<v-snackbar
  v-for="error in getErrors"
  :key="error.key"
>