Vue.jsのComputed property ~ was assigned to but it has no setterのエラー解決方法

thumnail
2019-12-02

Vue.jsを書いているとき次のエラーが検証ツールのconsoleに出力された。

Computed property "hoge" was assigned to but it has no setter

このエラーが出た時の解決方法を備忘録としてこの記事に残しておく。

Computed property "hoge" was assigned to but it has no setterのエラー原因

setterが定義されていない

これはエラー文を直訳すればすぐにわかる。算出プロパティにsetterというメソッドが定義されていないことが原因だ。ただVue.jsに慣れていない開発者はそもそもsetterメソッドが何かわからないかもしれない。

setterとは何か

算出プロパティが持つメソッド

setterは算出プロパティが持つメソッドの一部である。算出プロパティ(computed)は次のメソッドを持つ。

・getter
・setter

まずgetterには算出プロパティが返す値を記述する。算出プロパティを定義するとき、必ずしもsetterを定義しなければいけないわけではない。次のコードは算出プロパティを定義したときにsetterを定義しない場合のコードである。

<template>
  <div>
    <input v-model="hoge" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      value: 'hellow',
    };
  },
  computed: {
    hoge() {
      console.log('getter called');
      return this.value;
    },
  },
};
</script>

input要素に対して、v-modelを通じてhogeを渡している。この場合hogeのgetterが返すhellowがinputに出力される。ここでinput要素に対して適当な値を入力すると次のエラーが出力される。

[Vue warn]: Computed property "hoge" was assigned to but it has no setter.

まさに今回の議題のエラー文である。ではsetterを算出プロパティに付与してみる。

<template>
  <div>
    <input v-model="hoge" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      value: 'hellow',
    };
  },
  computed: {
    hoge: {
      get() {
        console.log('getter called');
        return this.value;
      },
      set(value) {
        console.log('setter called', value);
      },
    },
  },
};
</script>

そして先ほどと同様にinputに値を入力すると、検証ツールのconsoleにエラーは表示されず、setterメソッド内で定義したconsole.logの中身「setter called setterをセット」が出力される。これはどういうことかというと、算出プロパティの値が書きかえられるイベントが発生したときに呼ばれるメソッドがsetterなのだ。Vue.jsの仕様で、算出プロパティの値を更新する処理を書く時はsetterを定義しなければいけないというルールがある。

setterで値を更新する

算出プロパティの値を更新するためにはgetterの戻り値を更新する必要がある。setterには算出プロパティの値、getterで返す変数を書き換える処理を書く。一般的にはイベントを受け取り、そのイベントから渡された値を使って更新するといったパターンが多い。次のコードをみて欲しい。

<template>
  <div>
    <input v-model="hoge" />
    {{ hoge }}
  </div>
</template>

<script>
export default {
  data() {
    return {
      value: 'hellow',
    };
  },
  computed: {
    hoge: {
      get() {
        console.log('getter called');
        return this.value;
      },
      set(value) {
        console.log('setter called', value);
        this.value = value;
      },
    },
  },
};
</script>

input要素に値を入力することで、setterに値が渡され、setter内でthis.valueを更新することで算出プロパティの値が更新されていることがわかる。

profile

KATUO

web developer

六本木で月間利用者数数千万のサービスを運営するミドルベンチャーでWeb系エンジニアをやってます。フロントエンドはVue.js/Nuxt.js,サーバーサイドはGolang, クラウドはAWS, GCPを良く扱います。お仕事・イベント等の依頼はContactのフォームからお願いします。

KATUBLO

Copyright since 2018 KATUO All Rights Reserved.