飴屋

Vue.js/ライフサイクル

初期データをいじりたい

const app = Vue.createApp({
  data() {
    return {
      rows: [
        { id: 1, name: 'Taro', age: 5, country: 'Japan' },
        { id: 2, name: 'Jiro', age: 3, country: 'Japan' },
        { id: 3, name: 'John', age: 15, country: 'U.K.' },
        { id: 4, name: 'Michael', age: 8, country: 'U.S.A.' },
        { id: 5, name: 'Martín', age: 24, country: 'Spain' },
        { id: 6, name: 'Miguel', age: 5, country: 'Mexico' },
      ],
      japaneseAdultAge: 18
    }
  }
});
app.mount('#list');

例によってデータを詰めたVueのAppを用意しました。このrowsの部分はよそのシステムやデータベースが出力したJSON的なものだったりして、事前に手を加えられません(という仮定)。ここで名前と年齢と国籍のデータに加えて「成人しているかどうか」という情報を事前に追加しておきたくなりました。japaneseAdultAgeというデータがついているので、必要になったらその都度計算すれば成人した日本人かどうかは判別できそうです。でも、頻繁に必要になってくる項目なので、あらかじめ成人してるかどうか計算しておいてあげると、計算量を減らせそうです。

const app = Vue.createApp({
  data() {
    return {
      rows: this.attachAdult([ { id: 1, name: 'Taro', age: 5, country: 'Japan' }, ... ],
      japaneseAdultAge: 18
    }
  }
  methods: {
    attachAdult(rows) {
      rows.forEach( r => {
        if (r.country == 'Japan') {
          r.adult = r.age >= this.japaneseAdultAge ? 'Adult' : 'Child'; // Error!
        } else {
          r.adult = 'Unkhown';
        }
      }
    }
  }
});
app.mount('#list');

最初methodsに成人判別処理を書いて、手を加えたものをdataに突っ込んだらいいのかなと思ったのですが、メソッドの途中でjapaneseAdultAgeを参照しようとしたら、エラーがでました。そうかcreateAppが済んでないので、thisにデータがまだ詰まってないのか。

ライフサイクル

ここでcreateApp中にattachAdultメソッドで成型するのを諦めてみました。といっても、computed部でその都度成型するのは無駄が多すぎます。そこでライフサイクルというアイディアを導入してみました。

ライフサイクル表

beforeCreate
初期化時に実行される
created
初期化後に実行される
beforeMount
マウント時に実行される
mounted
マウント後に実行される
beforeUpdate
DOMツリー更新前に実行される
updated
DOMツリー更新後に実行される
beforeUnmount
アンマウント前に実行される
unmounted
アンマウント後に実行される
errorCaptured
エラーをキャプチャーしたときに実行される
renderTracked
リアクティブな依存関係が追加されたときに実行される
renderTriggered
レンダリングされるときに実行される
activated
コンポーネントがDOMに追加されたときに実行される
serverPrefetch
サーバーサイドのレンダリング前に実行される

後半、正しく理解していないものもありますがVueのコンポーネントやアプリが生まれて死ぬまでに起きるイベントに応じてトリガーされる関数を設定できるようです。
今回はVue.createAppでdate部が揃ったあと実行したいのでcreatedイベントがよさそうです。

const app = Vue.createApp({
  data() { .. },
  methods: { .. },
  created() {
    this.rows.forEach( r => {
      if (r.country == 'Japan') {
        r.adult = r.age >= this.japaneseAdultAge ? 'Adult' : 'Child'; // OK!
      } else {
        r.adult = 'Unkhown';
      }
    }
  }
});
app.mount('#list');

data, computed, methods などに並べてら合いライフタイムイベント名の関数を描くだけでよいようです。
これで事前にデータを整形できました!

Vue.js記事一覧