【问题标题】:change input text value vuex更改输入文本值 vuex
【发布时间】:2020-08-31 11:18:23
【问题描述】:

当我尝试更改组件的输入文本时,我在控制台中收到此错误:

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

我也将 nuxt 与 vuex 一起使用。

我的店里有这个:

editor.js

export const state = () => ({
  project_blocks: [{
    id: null,
    type: 'text-right',
    content:{
      title: 'Title 2',
      text: 'Text 2',
    }
  },{
      id: null,
      type: 'text-left',
      content:{
        title: 'Title 1',
        text: 'Text 1',
      }
    }],
});

export const mutations = {
  SET_BLOCKS(state, blocks){
    state.project_blocks = blocks;
  },
};


export const getters = {
  project_blocks(state){
    return state.project_blocks;
  }
};

在我的组件中我有:

Index.vue

<template>
   <component v-for="(block, index) in project_blocks" :key="'module'+index" :block="block" :is="block.type"></component>
</template>

<script>
   export default{
      computed: {
         project_blocks:{
           get(){
             return this.$store.getters['editor/project_blocks'];
           },
           set(val){
             this.$store.commit('editor/SET_BLOCKS', val);
           }
         },
       }
   }
</script>

在我的“组件类型”中,我有:

TextLeft.vue

<template>
   <input type="text" v-model="block.content.title">
   <input type="text" v-model="block.content.text">
</template>

<script>
   export default{
      props:['block']
   }
</script>

当我尝试更改这些输入文本的文本时,我收到此错误:[vuex] do not mutate vuex store state outside mutation handlers 我不知道如何修复它:(

谢谢大家!

【问题讨论】:

    标签: vue.js vuex nuxt.js


    【解决方案1】:

    错误消息在这里(令人惊讶?)很有帮助。当你对某个东西进行 v-model 时,你是在说“当这个输入发生变化时,修改我给你的这个东西的值。”

    但是,正如错误所说,这会导致您直接改变打算由 Vuex 存储的数据,这不是 Vuex 喜欢做的事情。你应该使用你的突变。

    编辑:以下评论是错误的。谢谢,涛! 旁注:您的 set(val) 函数不应位于 computed 中,而应位于 methods 中。

    【讨论】:

    • 使用computed-setter 是完全有效的。 Computed 默认情况下仅是 getter,但当您需要它们时它们可以是 getter/setter(即:在输入中用作 v-model 时)。
    • 啊,好电话。我不确定-Vuex-fluent 所以我不知道那种模式。谢谢指正!
    【解决方案2】:

    Vuex 抱怨 v-model 直接改变状态,因为你传递了一个 getter (observable) 给它。

    要正确更新状态,您应该使用操作。添加一个执行该突变的操作并将其分派到您计算的设置器中:

    computed: {
      project_blocks:{
        get(){
          return this.$store.getters['editor/project_blocks'];
        },
        set(val){
          this.$store.dispatch('editor/setBlocks', val);
        }
      }
    }
    

    存储/编辑器模块:

    actions: {
      setBlocks({ commit }, payload) {
        commit('SET_BLOCKS', payload);
      }
    }
    

    突变保持不变。


    forms 中提供的示例之所以有效,是因为它们使用了obj 的子属性。如果他们使用 obj 本身(顶级 getter 值),他们会得到和你一样的错误。

    【讨论】:

    • 我也试过这个选项,但出现了同样的警告
    • 我在这里发布的内容应该可以。您应该创建一个minimal reproducible example,这将使我们能够测试任何潜在的解决方案并找出所有方面。如果到那时您还没有找到答案,我只能在大约 10 到 12 小时内进一步调查。
    【解决方案3】:

    主要操作点是异步调用。您可以使用 Vuex 突变,但不能直接更改状态。这是正确的不变性定义(您可以查看 Vuex 文档)。 我认为现在的主要问题是您的计算属性返回 vuex getters 结果,并且项目上有 vuex 观察者。当您更改它时 - 会显示错误。

    【讨论】:

    • 根据docs,mutations 和 actions 之间的第一个区别是 “不是改变 state,actions commit mutation。” 第二个是它们可以包含 async操作。
    • 但它并没有告诉你只在动作中使用突变。它告诉你,你应该只通过动作中的 Vuex 突变来改变状态。主要的不可变规则是您不能直接更改状态。 Vuex 突变是同步的,动作是异步的。如果你不需要异步,更好的方法是使用突变。
    • 您不能将 observables 与 v-model 一起使用。您需要在 observable 上调用 next(),这就是该操作的作用。 getter/setter 的优点是组件中不需要两个名字,也不需要在@change 中指定方法。我相信它更干净。
    • 您可以阅读link 突变章节。在页面底部,他们描述了操作/突变的差异以及添加操作的原因。
    • Getter/setter 有优势。但是这里作者应该在较低级别使用它。
    【解决方案4】:

    我修复了错误! 我在我的组件中创建了一个数据值,并通过两个突变单独更改了这个值。

    TextLeft.vue:

    <template>
       <input type="text" v-model="title">
       <input type="text" v-model="text">
    </template>
    
    <script>
       export default{
          props:['block'],
          data(){
             title: this.block.content.title,
             text: this.block.content.text
          },
          watch:{
              title(val){
                 this.$store.commit('editor/SET_TITLE', { index: this.block.index, 
    title: val });
          },
              text(val){
                this.$store.commit('editor/SET_TEXT', { index: this.block.index, text: val });
          }
        }
       }
    </script>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-08
      • 2017-10-07
      • 2015-06-18
      • 2012-12-14
      • 2014-04-22
      • 1970-01-01
      • 1970-01-01
      • 2016-04-25
      相关资源
      最近更新 更多