序章

ライフサイクルフックは、使用しているライブラリが舞台裏でどのように機能するかを知るための窓です。 ライフサイクルフックを使用すると、コンポーネントがいつ作成、DOMに追加、更新、または破棄されたかを知ることができます。

この記事では、Vue.jsでのフックの作成、マウント、更新、破棄について紹介します。

前提条件

このチュートリアルを実行するには、次のものが必要です。

  • Vue.jsに精通していること。 詳細については、Vue.jsシリーズを使用してWebサイトを開発する方法をお読みください。

作成フックを理解する(初期化)

作成フックは、コンポーネントで実行される最初のフックです。 コンポーネントがDOMに追加される前に、アクションを実行できます。 他のフックとは異なり、作成フックもサーバー側のレンダリング中に実行されます。

クライアントレンダリングとサーバーレンダリングの両方でコンポーネントに設定する必要がある場合は、作成フックを使用します。

作成フック内のDOMまたはターゲットマウント要素(this.$el)にアクセスすることはできません。

beforeCreate

beforeCreateフックは、コンポーネントの初期化時に実行されます-dataはリアクティブにされておらず、eventsはまだ設定されていません。

ExampleComponent.vue
<script>
export default {
  beforeCreate() {
    console.log('At this point, events and lifecycle have been initialized.')
  }
}
</script>

この例では、beforeCreateフックが実行されると、このスニペットは次のメッセージをログに記録します。

Output
At this point, events and lifecycle have been initialized.

created

createdフックは、テンプレートと仮想DOMがマウントまたはレンダリングされる前に実行されます。アクティブなリアクティブdataおよびeventsにアクセスできます。

ExampleComponent.vue
<template>
  <div ref="example-element">{{ propertyComputed }}</div>
</template>

<script>
export default {
  data() {
    return {
      property: 'Example property.'
    }
  },

  computed: {
    propertyComputed() {
      return this.property
    }
  },

  created() {
    console.log('At this point, this.property is now reactive and propertyComputed will update.')
    this.property = 'Example property updated.'
  }
}
</script>

この例では、スニペットはpropertyExample propertyとして保存します。 createdフックを実行すると、次のメッセージがログに記録されます。

Output
At this point, this.property is now reactive and propertyComputed will update.

そして、propertyExample property updatedに変更されます。

ライフサイクルの後半では、{{ propertyComputed }}Example propertyではなくExample property updatedとして表示されます。

このステップでは、作成フックのいくつかの例を確認し、ライフサイクルの次の部分であるフックの取り付けに進む準備ができています。

取り付けフックについて(DOM挿入)

取り付けフックは、多くの場合、最もよく使用されるフックです。 これらを使用すると、最初のレンダリングの直前と直後にコンポーネントにアクセスできます。 ただし、サーバー側のレンダリング中は実行されません。

最初のレンダリングの直前または直後にコンポーネントのDOMにアクセスまたは変更する必要がある場合は、取り付けフックを使用します。

初期化時にコンポーネントのデータをフェッチする必要がある場合は、マウントフックを使用しないでください。

注:代わりにcreated(またはkeep-aliveコンポーネントの場合はcreatedおよびactivated)を使用してください。 特に、サーバー側のレンダリング中にそのデータが必要な場合。

beforeMount

beforeMountフックは、最初のレンダリングが行われる直前、およびテンプレートまたはレンダリング関数がコンパイルされた後に実行されます。

ExampleComponent.vue
<script>
export default {
  beforeMount() {
    console.log(`At this point, vm.$el has not been created yet.`)
  }
}
</script>

この例では、beforeMountフックが実行されると、このスニペットは次のメッセージをログに記録します。

Output
At this point, vm.$el has not been created yet.

mounted

mountedフックでは、リアクティブコンポーネント、テンプレート、およびレンダリングされたDOMに(this.$elを介して)完全にアクセスできます。

mountedを使用してDOMを変更します。特に、Vue以外のライブラリを統合する場合は次のようになります。

ExampleComponent.vue
<template>
  <div ref="example-element">Example component.</div>
</template>

<script>
export default {
  mounted() {
    console.log(`At this point, vm.$el has been created and el has been replaced.`);
    console.log(this.$el.textContent) // Example component.
  }
}
</script>

この例では、mountedフックが実行されると、このスニペットは次のメッセージをログに記録します。

Output
At this point, vm.$el has been created and el has been replaced.

また、Example content.this.$el.textContent)のメッセージが記録されます。

このセクションでは、フックを取り付けるためのユースケースについて説明しました。 次のステップでは、更新フックを使用するいくつかの例を確認します。

フックの更新について理解する(差分と再レンダリング)

更新フックは、コンポーネントで使用されているリアクティブプロパティが変更された場合、または他の何かによってコンポーネントが再レンダリングされた場合に呼び出されます。 これらを使用すると、コンポーネントのwatch-compute-renderサイクルに接続できます。

コンポーネントがいつ再レンダリングされるかを知る必要がある場合は、おそらくデバッグやプロファイリングのために、更新フックを使用します。

コンポーネントのリアクティブプロパティがいつ変更されるかを知る必要がある場合は、更新フックを使用しないでください。 代わりに、計算されたプロパティまたはウォッチャーを使用してください。

beforeUpdate

beforeUpdateフックは、コンポーネントのデータが変更され、更新サイクルが開始された後、DOMにパッチが適用されて再レンダリングされる直前に実行されます。

コンポーネントをレンダリングする前に、コンポーネント上のリアクティブデータの新しい状態を取得する必要がある場合は、beforeUpdateを使用します。

ExampleComponent.vue
<template>
  <div ref="example-element">{{counter}}</div>
</template>

<script>
export default {
  data() {
    return {
      counter: 0
    }
  },

  created() {
    setInterval(() => {
      this.counter++
    }, 1000)
  },

  beforeUpdate() {
    console.log(`At this point, Virtual DOM has not re-rendered or patched yet.`)
    // Logs the counter value every second, before the DOM updates.
    console.log(this.counter)
  }
}
</script>

まず、このスニペットはcounter0として保存します。 createdフックを実行すると、1000ミリ秒ごとにcounterが増分します。 beforeUpdateフックが実行されると、このスニペットはメッセージをログに記録します。

Output
At this point, Virtual DOM has not re-rendered or patched yet.

また、counterの番号も記録されます。

updated

updatedフックは、コンポーネントのデータが変更され、DOMが再レンダリングされた後に実行されます。

プロパティの変更後にDOMにアクセスする必要がある場合は、updatedを使用します。

ExampleComponent.vue
<template>
  <div ref="example-element">{{counter}}</div>
</template>

<script>
export default {
  data() {
    return {
      counter: 0
    }
  },

  created() {
    setInterval(() => {
      this.counter++
    }, 1000)
  },

  updated() {
    console.log(`At this point, Virtual DOM has re-rendered and patched.`)
    // Fired every second, should always be true
    console.log(+this.$refs['example-element'].textContent === this.counter)
  }
}
</script>

まず、このスニペットはcounter0として保存します。 createdフックを実行すると、1000ミリ秒ごとにcounterが増分します。 updatedフックが実行されると、このスニペットはメッセージをログに記録します。

Output
At this point, Virtual DOM has re-rendered and patched.

また、レンダリングされた値と現在の値が等しいため、ブール値trueがログに記録されます。

更新フックの使用について説明したので、破棄フックについて学習する準備が整いました。

破壊フックを理解する(分解)

破棄フックを使用すると、コンポーネントが破棄されたときに、クリーンアップや分析の送信などのアクションを実行できます。 コンポーネントが分解されてDOMから削除されたときに起動します。

beforeDestroy

beforeDestroyはティアダウンの直前に発生します。 コンポーネントは引き続き完全に機能します。

イベントまたはリアクティブサブスクリプションをクリーンアップする必要がある場合は、beforeDestroyを使用します。

ExampleComponent.vue
<script>
export default {
  data() {
    return {
      exampleLeakyProperty: 'This represents a property that will leak memory if not cleaned up.'
    }
  },

  beforeDestroy() {
    console.log(`At this point, watchers, child components, and event listeners have not been teared down yet.`)
    // Perform the teardown procedure for exampleLeakyProperty.
    // (In this case, effectively nothing)
    this.exampleLeakyProperty = null
    delete this.exampleLeakyProperty
  }
}
</script>

このスニペットは最初にexampleLeakyPropertyを保存します。 beforeDestroyフックが実行されると、このスニペットはメッセージをログに記録します。

Output
At this point, watchers, child components, and event listeners have not been torn down yet.

そして、exampleLeakyPropertyが削除されます。

destroyed

destroyedフックに到達するまでに、コンポーネントには実質的に何も残っていません。 それに付けられていたものはすべて破壊されました。

直前のクリーンアップを実行する必要がある場合、またはコンポーネントが破壊されたことをリモートサーバーに通知する必要がある場合は、destroyedを使用します。

ExampleComponent.vue
<script>
import ExampleAnalyticsService from './example-analytics-service'

export default {
  destroyed() {
    console.log(`At this point, watchers, child components, and event listeners have been torn down.`)
    console.log(this)
    ExampleAnalyticsService.informService('Component destroyed.')
  }
}
</script>

まず、このスニペットはExampleAnalyticsServiceをインポートします。 beforeDestroyフックが実行されると、このスニペットはメッセージをログに記録します。

Output
At this point, watchers, child components, and event listeners have been torn down.

コンポーネントの残りはコンソールに記録され、ExampleAnalyticsServiceにメッセージComponent destroyed.が渡されます。

これで、Vue.jsライフサイクルフックの一般的なレビューが完了しました。

その他のフック

他に2つのフック、activateddeactivatedがあります。 これらはkeep-aliveコンポーネント用であり、この記事の範囲外のトピックです。

<keep-alive></keep-alive>タグでラップされたコンポーネントがオンまたはオフに切り替えられたときに検出できると言えば十分です。 これらを使用して、コンポーネントのデータをフェッチしたり、状態の変化を処理したりできます。コンポーネントを完全に再構築しなくても、createdおよびbeforeDestroyとして効果的に動作します。

結論

この記事では、Vue.jsインスタンスライフサイクルで利用できるさまざまなライフサイクルフックを紹介しました。 作成フック、取り付けフック、更新フック、および破棄フックのさまざまなユースケースを検討しました。

Vue.jsの詳細については、Vue.jsトピックページで演習とプログラミングプロジェクトを確認してください。