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

新手上路,请多包涵

为什么我会收到此错误:

错误 [vuex] 不要在突变处理程序之外改变 vuex 存储状态。

这是什么意思?

当我尝试 输入编辑输入文件 时会发生这种情况。

pages/todos/index.vue

 <template>
  <ul>
    <li v-for="todo in todos">
      <input type="checkbox" :checked="todo.done" v-on:change="toggle(todo)">
      <span :class="{ done: todo.done }">{{ todo.text }}</span>
      <button class="destroy" v-on:click="remove(todo)">delete</button>

      <input class="edit" type="text" v-model="todo.text" v-todo-focus="todo == editedTodo" @blur="doneEdit(todo)" @keyup.enter="doneEdit(todo)" @keyup.esc="cancelEdit(todo)">

    </li>
    <li><input placeholder="What needs to be done?" autofocus v-model="todo" v-on:keyup.enter="add"></li>
  </ul>
</template>

<script>
import { mapMutations } from 'vuex'

export default {
  data () {
    return {
      todo: '',
      editedTodo: null
    }
  },
  head () {
    return {
      title: this.$route.params.slug || 'all',
      titleTemplate: 'Nuxt TodoMVC : %s todos'
    }
  },
  fetch ({ store }) {
    store.commit('todos/add', 'Hello World')
  },
  computed: {
    todos () {
      // console.log(this)
      return this.$store.state.todos.list
    }
  },
  methods: {
    add (e) {

      var value = this.todo && this.todo.trim()
      if (value) {
        this.$store.commit('todos/add', value)
        this.todo = ''
      }

    },
    toggle (todo) {
      this.$store.commit('todos/toggle', todo)
    },
    remove (todo) {
      this.$store.commit('todos/remove', todo)
    },

    doneEdit (todo) {
      this.editedTodo = null
      todo.text = todo.text.trim()
      if (!todo.text) {
        this.$store.commit('todos/remove', todo)
      }
    },
    cancelEdit (todo) {
      this.editedTodo = null
      todo.text = this.beforeEditCache
    },
  },
  directives: {
    'todo-focus' (el, binding) {
      if (binding.value) {
        el.focus()
      }
    }
  },
}
</script>

<style>
.done {
  text-decoration: line-through;
}
</style>

stores/todos.js

 export const state = () => ({
  list: []
})

export const mutations = {
  add (state, text) {
    state.list.push({
      text: text,
      done: false
    })
  },
  remove (state, todo) {
    state.list.splice(state.list.indexOf(todo), 1)
  },
  toggle (state, todo) {
    todo.done = !todo.done
  }
}

有什么想法可以解决这个问题吗?

原文由 Run 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 576
2 个回答

在属于 Vuex 的状态上使用 v-model 可能有点棘手。

并且您在 v-model 上使用了 todo.text

 <input class="edit" type="text" v-model="todo.text" v-todo-focus="todo == editedTodo" @blur="doneEdit(todo)" @keyup.enter="doneEdit(todo)" @keyup.esc="cancelEdit(todo)">

使用 :value 读取值和 v-on:inputv-on:change 执行在显式 Vuex 突变处理程序中执行突变的方法

这个问题在这里处理: https ://vuex.vuejs.org/en/forms.html

原文由 Badis Merabet 发布,翻译遵循 CC BY-SA 4.0 许可协议

您好,我遇到了同样的问题,并使用以下方法之一克隆我的对象来解决它:

 { ...obj} //spread syntax
Object.assign({}, obj)
JSON.parse(JSON.stringify(obj))

对于您的代码,我认为您需要替换这部分

computed: {
  todos () {
    // console.log(this)
    return this.$store.state.todos.list
  }
}

有了这个

computed: {
  todos () {
    // console.log(this)
    return {...this.$store.state.todos.list}
  }
}

我不确定这是否是最好的方法,但希望这对遇到同样问题的其他人有所帮助。

原文由 user3772028 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题