Vuex严格模式在更新嵌套数组时抛出异常

时间:2016-09-29 14:11:36

标签: vue.js vue-component vuex

我有一个页面,用户可以编辑多个细分。每个细分都有一个名称和一组他可以添加/删除的过滤器。

{
  segments: [
    {
      name: 'Mac',
      filters: [
        {
          field: 'os',
          value: 'mac'
        },
        {
          field: 'browser',
          value: 'chrome'
        }
      ]
    }
  ]
}

Index.vue

<template>
  <div class="segments">
    <segment
      v-for="segment in segments"
      :id="segment.id"
      :name="segment.name"
      :filters="segment.filters">
    </segment>
  </div>
</template>

<script>
import Segment from './Segment'
export default {
  vuex: {
    getters: {
      segments
    }
  },
  components: {
    Segment
  }
}
</script>

Segment.vue

<template>
  <div class="segment">
    <input type="text" class="name" v-model="name" />
    <filters :filters="segment.filters"></filters>
    <button @click="saveSegment()">Save</button>
  </div>
</template>

<script>
import Filters from './Filters'
export default {
  props: ['id', 'name', 'filters'],
  vuex: {
    methods: {
      updateSegment({dispatch}, id, segments) {
        dispatch(SEGMENT_UPDATE, id, segment)
      }
    }
  },
  methods: {
    save () {
      this.updateSegment(this.id, {
        name: this.name,
        filters: this.filters
      })
    }
  }
}
</script>

Filters.vue

<template>
  <ul class="filters">
    <li v-for="filter in filter">
      {{ filter.name }} <button @click="remove($index)">Remove</button>
    </li>
  </ul>
</template>

<script>
export default {
  props: ['filters'],
  methods: {
    remove (index) {
      this.filters.splice(index, 1)
    }
  }
}
</script>

每次删除过滤器时,都会出现Do not mutate vuex store state outside mutation handlers.错误。我知道为什么,因为无论我通过组件属性传递过滤器数组多少次,它们仍然保持被动,并且它们在Filters组件中的更改传播到引发错误的vuex存储。

输入中的段名称也是如此。但是有一个例子如何处理文档中的表单。

但是如何让过滤器工作?为过滤器制作单独的商店?但这将是一团糟,因为页面上会有多个带有自己过滤器的细分......我被卡住了:(

1 个答案:

答案 0 :(得分:0)

我从vuex repo本身的对话中了解到,唯一的方法和最佳决策是深度克隆filters数组,然后将其用作局部变量。

必须这样做,因为JS中的数组总是通过引用传递,而深度克隆从vuex存储中的数组解除绑定filters数组。

这可以通过JSON.parse(JSON.stringify())_.cloneDeep()或任何其他类似方法来实现。