Vuex - 计算属性"name"被赋值了,但是它没有setter函数

183

我有一个包含表单验证的组件。它是一个多步骤的结账表单。下面的代码是第一步骤的代码。我想要验证用户输入了一些文本,将他们的名字存储在全局状态中,然后将他们发送到下一个步骤。我正在使用vee-validate和vuex。

<template>
<div>
    <div class='field'>
        <label class='label' for='name'>Name</label>
        <div class="control has-icons-right">

            <input name="name" v-model="name" v-validate="'required|alpha'" :class="{'input': true, 'is-danger': errors.has('name') }" type="text" placeholder="First and Last">
            <span class="icon is-small is-right" v-if="errors.has('name')">
                <i class="fa fa-warning"></i>
            </span>
        </div>
        <p class="help is-danger" v-show="errors.has('name')">{{ errors.first('name') }}</p>

    </div>
    <div class="field pull-right">
        <button class="button is-medium is-primary" type="submit" @click.prevent="nextStep">Next Step</button>
    </div>
</div>
</template>

<script>
export default {
    methods: {
        nextStep(){
            var self = this;

            // from baianat/vee-validate
            this.$validator.validateAll().then((result) => {
                if (result) {
                    this.$store.dispatch('addContactInfoForOrder', self);
                    this.$store.dispatch('goToNextStep');
                    return;
                }
            });
        }
    },
    computed: {
        name: function(){
            return this.$store.state.name;
        }
    }
}
</script>

我有一个用于处理订单状态和记录名称的商店。最终,我希望将多步表单中的所有信息发送到服务器。

export default {
  state: {
    name: '',
  },

  mutations: {
    UPDATE_ORDER_CONTACT(state, payload){
      state.name = payload.name;

    }
  },

  actions: {
    addContactInfoForOrder({commit}, payload) {
      commit('UPDATE_ORDER_CONTACT', payload);
    }
  }
}
当我运行这段代码时,出现了一个错误:Computed property "name" was assigned to but it has no setter. 我该如何将名称字段的值绑定到全局状态?我希望这是持久的,这样即使用户退回一步(在点击“下一步”后),他们也会看到他们在此步骤中输入的名称。

2
除了Roy J的答案之外,似乎在没有setter的情况下在计算属性上使用v-for也会引发此警告。 - jsiegal
6个回答

264
如果你要使用v-model绑定computed属性,那么它需要有一个setter。无论你希望更新的值做什么(很可能是将其写入$store,因为你的getter从中获取它),都可以在setter中完成。

如果通过表单提交将其写回到存储器中,则不需要使用v-model,只需设置:value即可。

如果您想要一个中间状态,在这种状态下,它会被保存在某个地方,但在表单提交之前不会覆盖$store 中的源代码,则需要创建此类数据项。


2
您能否提供一个正确创建setter的示例? - chovy
2
这篇文章中有一个示例,还有另一个在这个答案链接中。 - Roy J

67

应该像这样。

在您的组件

computed: {
        ...mapGetters({
                nameFromStore: 'name'
            }),
        name: {
           get(){
             return this.nameFromStore
           },
           set(newName){
             return newName
           } 
        }
    }

在你的商店

export const store = new Vuex.Store({
         state:{
             name : "Stackoverflow"
         },
         getters: {
                 name: (state) => {
                     return state.name;
                 }
         }
}

1
抱歉打扰您的旧回答,但为什么在这种情况下要使用getter?为什么不从mapState返回this.nameFromStore呢?显然它同样有效。 - Jake
2
@Jake 对于这个例子,你说的是对的。但是当你想要操作存储在 store 中的数据时,你可以在 getter 内部进行操作,但如果直接使用 this.nameFromStore,则无法操作数据。 - OhhhThatVarun

9

对我来说,这是一次变革。

this.name = response.data;

计算返回的结果;

this.$store.state.name = response.data;

这对我也起作用。- 将数据分配给另一个变量,然后将其作为参数添加到存储函数中。 - Tatyana Molchanova

2
我在使用...mapState(['sampleVariable'])store中获取值时,遇到了错误。我在<script>中使用了this.sampleVariable,在<template>中使用了sampleVariable。为了解决这个问题,我在data()中返回this,将其分配给一个单独的变量,并在整个component中重复使用新创建的变量,如下所示:
data() {
  return {
    newVariable: this.$store.state.sampleVariable,
  }
}

然后,我将组件中的引用从sampleVariable更改为newVariable,错误就消失了。


0

我遇到了完全相同的错误

计算属性“callRingtatus”被赋值但没有setter

这是根据我的情况编写的示例代码

computed: {

callRingtatus(){
            return this.$store.getters['chat/callState']===2
      }

}

我将上面的代码改为以下方式
computed: {

callRingtatus(){
       return this.$store.state.chat.callState===2
    }
}


从computed hook中获取vuex store状态的值,而不是使用getter。

0
这是因为你的计算属性还没有使用setter方法,而你正在尝试为其属性设置一个新的值。
你现有的计算属性。
computed: {
  fullName: function() {
    return this.firstName + " " + this.lastName
  }
}

然后你以某种方式为其计算属性赋值:
this.fullName = "new value"

这将产生错误 -> Vuex - 计算属性"fullName"被赋值,但它没有setter 所以你必须为你的计算属性设置setter和getter
computed: {
  fullName: {
    // getter
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set: function (newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}

你的回答可以通过提供更多的支持性信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的回答是否正确。你可以在帮助中心找到关于如何撰写好的回答的更多信息。 - undefined
1
@ImanShafiei 好的,我刚刚修改了它 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接