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、setterなしでComputedを使用すると、この警告もスローされるようです。
jsiegal 2018

回答:


191

v-model計算に行く場合は、setterが必要です。更新された値を使って何をしたいのか(おそらく、それを$storeゲッターがプルするものであることを考慮して、に書き込んでください)、セッターで行います。

フォームの送信を介してストアに書き戻す場合はv-model、設定したくないだけです:value

どこかに保存されているが、$storeフォームが送信されるまでソースを上書きしない中間状態にしたい場合は、そのようなデータ項目を作成する必要があります。


37
:value以上v-model。ありがとうございました!
コナーリーチ2017

4
ありがとう...私の[vue warn]も修正しました。(読み取り専用)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
あなたの古い答えを復活させて申し訳ありませんが、なぜこの場合ゲッターを使うのですか?なぜthis.nameFromStoreをmapStateから返さないのですか?それは明らかに同様に機能します。
ジェイク

@Jakeこの例では、あなたの言っていることが正しいです。しかし、ストアに保存されたデータを操作したい場合は、getter内で行うことができますが、this.nameFromStore直接使用する場合はデータを操作できません。
OhhhThatVarun

1
説明をありがとう:)
ジェイク

@ジェイク問題ありません!
OhhhThatVarun

3

私にとってそれは変わりました。

this.name = response.data;

計算されたものに戻ります;

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

0

この警告が表示される理由を述べておきたいのですが、計算された値を作成するときは常にデフォルトでゲッターであり、計算されたプロパティのセッターを明示的に定義する必要があります。

VueJ、Computed Setterのドキュメントで言及されているとおり

計算されたプロパティは次のようになります

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

より適切な方法はmapState、ストアから名前を取得するために利用し、ストアでゲッターを定義し、ストアmapGettersから名前を抽出するために使用する他のオプションです。

知っておくべき重要なこと:ストアからゲッターを使用して、ストアから計算データを取得します。そのとき、計算データを取得するゲッターにロジックを定義します。

ゲッターの例

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

このゲッターはアクティブユーザーの状態をチェックし、loggedInの場合はtrueを、loggedInでない場合はfalseを返します。

アプリケーション全体の後半で、mapGettersこのisLoggedInプロパティを抽出し、それに応じてチェックを追加するために使用します

誰かがこの助けをいっぱい見つけてくれることを願っています:)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.