web-dev-qa-db-ja.com

vue.jsのストアから取得された計算済みプロパティのセッター

store.jsから値を取得する2つのチェックボックスを作成し、フォームを介してバックエンドに送信します。

<label>Notify me 
    <input type="checkbox" v-model="notification" value="notification" />       
</label>

<label>Email me 
    <input type="checkbox" v-model="email" value="email" />     
</label>

計算されたプロパティとして値を取得します。

computed: {
  BASE_URL () {
    return this.$store.state.BASE_URL;  
  }, 
  notification () {
    return this.$store.state.notification; 
  },

  email () {
    return this.$store.state.email; 
  }
}

問題は、チェックボックスをオンにしてもストアの値が変更されないことです。それに加えて、次のようなコンソールでこの警告が表示されます。

vue.esm.js?65d7:479 [Vue warn]: Computed property "notification" was assigned to but it has no setter.

Vue.jsドキュメントの 説明 のように、計算されたプロパティでセッターを定義できることは知っていますが、特定の場合のように、設定する複数の値がある場合にそれを行う方法はわかりません。

これを修正するためにあなたの助けに感謝します。

8
Karlom

Vuexの状態を変更するには、ミューテーションが必要です。

setNotification状態を変更するための突然変異notificationがある場合、コンポーネントのプロパティを次のように構成できます。

computed: {
    notification: {
        get() { return this.$store.state.notification; },
        set(value) { this.$store.commit('setNotification', value); },
    },
},

これで、通常どおりv-model="notification"を使用してバインドできます。

詳細については、ドキュメントの フォーム処理 を参照してください。


これはプロジェクトで頻繁に行うことなので、計算されたプロパティを生成するヘルパー関数を作成しました。

function mapStateTwoWay(...args) {
    const result = {};

    if (args.length === 1) {
        for (const prop of Object.keys(args[0])) {
            result[prop] = {
                get() { return this.$store.state[prop]; },
                set(value) { this.$store.commit(args[0][prop], value); },
            };
        }
    } else {
        for (const prop of Object.keys(args[1])) {
            result[prop] = {
                get() { return this.$store.state[args[0]][prop]; },
                set(value) { this.$store.commit(args[0] + '/' + args[1][prop], value); },
            };
        }
    }

    return result;
}

次のように使用します。

computed: {
    ...mapStateTwoWay({
        notifications: 'setNotifications',
        email: 'setEmail',
    }),

    // Namespaced
    ...mapStateTwoWay('namespace', {
        notifications: 'setNotifications',
        email: 'setEmail',
    }),
}
17
Decade Moon