【问题标题】:Updating a filtered multi-row Vuex backed form results in "do not mutate vuex store state"更新过滤的多行 Vuex 支持的表单会导致“不改变 vuex 存储状态”
【发布时间】:2026-01-06 15:55:02
【问题描述】:

我在 Nuxt/Vuex 中有一个多行表单,我成功地对行进行了 CRUDing。我可以创建、更新和删除行。沙盒在这里。 https://codesandbox.io/s/multirow-fields-hkzql

我有另一种形式,我根据行中的值过滤行。我可以创建和删除行但不能更新它们。沙盒在这里。 https://codesandbox.io/s/testing-filtered-multirow-fields-24cxb

当我编辑过滤表中的字段时,我得到 [vuex] do not mutate vuex store state outside mutation handlers 错误。

// store/Table.js snippet
export const getters = {
  getField,
  filteredRows: state => {
    return state.rows.filter(row => row.key > 1);
  }
};
<!-- component/MultiRow.vue snippet -->
<tr v-for="row in filteredRows" :key="row.key">
  <td>
    <input v-model="row.key">
  </td>
  <td>
    <input v-model="row.value">
  </td>
  <td>
    <button class="btn" @click="removeRow(row)">Remove row</button>
  </td>
</tr>

vuex-map-fields有解决办法吗?没有它有解决办法吗?

【问题讨论】:

  • 你能分享你的“removeRow”方法吗?
  • Delete 在这两种情况下都运行良好。查看代码沙箱链接。

标签: vuex nuxt.js


【解决方案1】:

您在严格模式下使用 Vuex,因此您无法从突变之外的状态更新对象的属性,如下所述:https://vuex.vuejs.org/guide/forms.html

要解决您的问题,首先创建一个新的变异方法:

  updateRow(state, row) {
    const index = state.rows.findIndex(i => i.key === row.key);
    if (index > -1) {
      state.rows[index] = row;
    }
  }

然后将您的v-model 替换为:value + @input,以便使用这种新的变异方法更新“行”值:

    <tbody>
      <tr v-for="row in filteredRows" :key="row.key">
        <td>
          <input :value="row.key" @input="updateRow(row)">
        </td>
        <td>
          <input :value="row.key" @input="updateRow(row)">
        </td>
        <td>
          <button class="btn" @click="removeRow(row)">Remove row</button>
        </td>
      </tr>
    </tbody>

并更新您的方法列表:

  methods: {
    ...mapMutations("Table", ["addRow", "removeRow", "updateRow"])
  }

【讨论】:

  • 感谢您关注此问题。我制作了一个沙盒副本来尝试一下。 codesandbox.io/s/filtered-multirow-fields-solution-1-je6gn 不幸的是我没有成功。按照您的方法,我看到事件是由未传入表单的当前状态触发的,因此状态实际上并未更新。您可以通过按添加来查看这一点,此时更新的字段会恢复。我确实从 $event 中传递了字段的值。您也可以在沙箱中看到这一点。我注意到修改密钥是个坏主意,所以我禁用了它。
  • 感谢@Nicolas Pennec 为我指明了正确的方向。我将保持开放状态,虽然它已经解决了一些问题,但我想看看是否有人在校园内有一个 vuex-map-fields 解决方案,它不那么冗长且更易于维护。
最近更新 更多