Vue コンポーネントに渡された props の更新時に data を書き換える

備忘録。

Vue.js でコンポーネントの props が更新された時に何かしらの処理を実行する方法について。

以下のようなコンポーネントを考える。

Vue.component('foo', {
  props: ['x'],
  created() {
    this.y = useX(this.x)
  }
})

foo はプロパティとして x を受け取り、作成時に useX では何かしらの API 呼出しなどを行い、その結果を y に入れている。

これだと後から x が変更された時に y の更新ができない。そこで beforeUpdate フックでも同じ処理を追加して、プロパティ更新時にも useX を呼び出すことを保証できるように見える。

  beforeUpdate() {
    this.y = useX(this.x)
  }

しかし、これは無限ループに陥ることになる。y の更新が新たな beforeUpdate の発火につながっている模様。

解決方法

まず watch を使って x の更新のみをフックするという手がある。

  watch: {
    x() {
      this.y = useX(this.x)
    }
  }

単純な計算で useX の実行タイミングの制約が緩いのであれば y は算出プロパティにしてもいいかもしれない。

  computed: {
    y() {
      useX(this.x)
    }
  }

あるいは、もしコンポーネント間で x を複雑に引き回しているなら、Vuex での管理を検討してもいい。