Vuex-已将计算属性“名称”分配给但没有设置器


108

我有一个带有表单验证的组件。这是一个多步骤结帐表格。下面的代码是第一步。我想验证用户是否输入了一些文本,将其名称存储在全局状态下,然后发送至下一步。我正在使用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.

如何将名称字段中的值绑定到全局状态?我希望此设置保持不变,以便即使用户返回上一步(单击“下一步”后),他们也将看到他们在此步骤中输入的名称


1
除了Roy J的答案外,似乎v-for在没有设置器的计算机上使用时也会抛出此警告。
jsiegal

Answers:


192

如果要进行v-model计算,则需要使用setter。您想要在更新程序中执行的操作与更新后的值(可能是将其写入$store,考虑到您的吸气剂从中获取的值)有关。

如果将其写回商店是通过表单提交完成的,那么您不希望这样做v-model,而只需要设置即可:value

如果您想要一个中间状态,该状态保存在某个地方,但是在$store直到表单提交之前都不会覆盖源,则需要创建这样的数据项。


37
:value结束v-model。谢谢!
康纳·里奇 Connor Leech)

4
谢谢...也修正了我的[vue警告]。我有一个导航抽屉,该抽屉需要(只读)true / false值,但是我已经在其中放置了一个v模型。
GA

26

应该是这样

在您的组件中

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
很抱歉恢复了您的旧答案,但是为什么在这种情况下使用吸气剂?为什么不从mapState返回this.nameFromStore?显然,它的效果也一样。
杰克

@杰克对于这个给定的例子,你说的是正确的。但是,当您要操作存储中的已保存数据时,可以在getter中进行操作,但是如果this.nameFromStore直接使用,则无法操作数据。
OhhhThatVarun

1
感谢您的澄清:)
Jake

@Jake没问题!
OhhhThatVarun


0

我只想提及为什么会出现此警告,每当我们创建计算值时,默认情况下它都是吸气剂,因此我们明确需要为计算属性定义setter,

如VueJs,Computer Setter的文档中所述

您的计算属性将如下所示

   name: {
       get: function () {
          return yourName
       },
       set: function (newName) {
          return yourNewName
       }

更合适的方法是您利用mapState来从商店中获取名称,并使用其他选项在商店中定义getter并使用mapGetters从商店中提取名称的,

重要信息:要从商店获取计算数据时,将使用商店中的吸气剂,然后在那时,您需要在获取器中定义逻辑以获取计算数据

吸气剂的例子

getters = {
  isLoggedIn (state) {
    return !!state?.activeUser?.id
  }
}

此getter检查您的活动用户状态,如果LoggedIn返回true,否则返回false,

稍后在整个应用程序中,我们mapGetters将提取该isLoggedIn属性并根据该属性添加检查

希望有人找到完整的帮助:)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.