# ライフサイクルフック

Note

すべてのライフライクルフックは、自動的にその this コンテキストをインスタンスに束縛するため、データ、算出プロパティ、およびメソッドにアクセスできます。これはつまり、ライフサイクルメソッドの定義にアロー関数を使ってはいけない ということです(例: created: () => this.fetchTodos())。その理由は、アロー関数が親のコンテキストを束縛するためで、this が期待した通りのコンポーネントインスタンスをにならず、this.fetchTodos は undefined になるからです。

# beforeCreate

  • 型: Function

  • 詳細:

    インスタンスが初期化された直後、データの監視とイベント/ウォッチャの設定前に、同期的に呼び出されます。

  • 参照: ライフサイクルダイアグラム

# created

  • 型: Function

  • 詳細:

    インスタンスが作成された後に、同期的に呼び出されます。この段階では、インスタンスはオプションの処理を終えています。つまり、次のものが設定されています: データの監視、算出プロパティ、メソッド、ウォッチ/イベントのコールバック。しかし、マウントのフェーズは始まっていないので、$el プロパティはまだ利用できません。

  • 参照: ライフサイクルダイアグラム

# beforeMount

  • 型: Function

  • 詳細:

    マウントがはじまる直前に呼び出されます: render 関数が初めて呼び出されるところです。

    このフックはサーバサイドレンダリングで呼び出されません。

  • 参照: ライフサイクルダイアグラム

# mounted

  • 型: Function

  • 詳細:

    インスタンスがマウントされた後に呼び出され、app.mount に渡された要素は、その新しく作成された vm.$el で置き換えられます。ルートインスタンスがドキュメントの中の要素にマウントされた場合、mounted が呼び出されたときに、vm.$el もドキュメントに配置されます。

    mounted は、すべての子コンポーネントもマウントされていることを 保証しない ことに注意してください。ビュー全体がレンダリングされるまで待ちたい場合は、mounted の代わりに vm.$nextTick を使うことができます:

    mounted() {
      this.$nextTick(function () {
        // ビュー全体がレンダリングされた後にのみ
        // 実行されるコード
      })
    }
    
    1
    2
    3
    4
    5
    6

    このフックはサーバサイドレンダリングで呼び出されません。

  • 参照: ライフサイクルダイアグラム

# beforeUpdate

  • 型: Function

  • 詳細:

    データが変更されるとき、DOM に patch (Virtual DOM の処理プロセス)される前に呼び出されます。これは例えば、手動で追加されたイベントリスナを削除するといった、更新前に既存の DOM にアクセスするのに適しています。

    このフックはサーバサイドレンダリングで呼び出されません。初期レンダリングのみ実行されるためです。

  • 参照: ライフサイクルダイアグラム

# updated

  • 型: Function

  • 詳細:

    データの変更後に仮想 DOM が再レンダリングされ、patch が適用された後に呼び出されます。

    このフックが呼び出されたときには、コンポーネントの DOM は更新されているので、ここで DOM に依存した操作を行うことができます。しかしほとんどの場合、フックの中で状態を変更することは避けるべきです。状態を変更するためには、通常代わりに 算出プロパティウォッチャ を使うほうがよいでしょう。

    updated は、すべての子コンポーネントが再レンダリングされたことを保証するものでは ありません。ビュー全体が再レンダリングされるまで待ちたいなら、vm.$nextTickupdated の中で使うことができます:

    updated() {
      this.$nextTick(function () {
        // ビュー全体が再レンダリングされた後にのみ
        // 実行されるコード
      })
    }
    
    1
    2
    3
    4
    5
    6

    このフックはサーバサイドレンダリングで呼び出されません。

  • 参照: ライフサイクルダイアグラム

# activated

  • 型: Function

  • 詳細:

    kept-alive コンポーネント(keep-alive が内部で保持する子コンポーネント)がアクティブになったときに呼び出されます。

    このフックはサーバサイドレンダリングで呼び出されません。

  • 参照:

# deactivated

  • 型: Function

  • 詳細:

    kept-alive コンポーネント(keep-alive が内部で保持する子コンポーネント)が非アクティブになったときに呼び出されます。

    このフックはサーバサイドレンダリングで呼び出されません。

  • 参照:

# beforeUnmount

  • 型: Function

  • 詳細:

    コンポーネントインスタンスがアンマウントされる直前に呼び出されます。この段階ではインスタンスはまだ完全に機能しています。

    このフックはサーバサイドレンダリングで呼び出されません。

  • 参照: ライフサイクルダイアグラム

# unmounted

  • 型: Function

  • 詳細:

    コンポーネントインスタンスがアンマウントされた後に呼び出されます。このフックが呼び出されたときには、コンポーネントインスタンスのすべてのディレクティブはバインド解除され、すべてのイベントリスナは削除され、すべての子コンポーネントインスタンスもアンマウントされています。

    このフックはサーバサイドレンダリングで呼び出されません。

  • 参照: ライフサイクルダイアグラム

# errorCaptured

  • 型: (err: Error, instance: Component, info: string) => ?boolean

  • 詳細:

    任意の子孫コンポーネントからエラーが捕捉されたときに呼び出されます。このフックは 3 つの引数を受け取ります: エラーと、エラーを引き起こしたコンポーネントインスタンスと、エラーが捕捉された箇所の情報を含む文字列です。このフックは更にエラーが伝播するのを防ぐために、false を返すことができます。

    TIP

    このフックでコンポーネントの状態を変更することができます。しかし、テンプレートや Render 関数でエラーが捕捉されたときに、他のコンテンツを手短に迂回させるような条件分岐を用意することが重要です。そうでなければ、コンポーネントは無限のレンダリングループに陥ってしまいます。

    エラー伝播のルール

    • デフォルトでは、グローバルの config.errorHandler が定義されている場合、すべてのエラーが送信されます。そのため、これらのエラーを単一の場所でアナリティクスサービスに報告することができます。

    • もし複数の errorCaptured フックがコンポーネントの継承チェーンや親チェーンに存在する場合、それらすべては同じエラーで呼び出されます。

    • もし errorCaptured フック自身がエラーを投げると、このエラーと元のキャプチャされたエラーの両方がグローバルの config.errorHandler に送られます。

    • errorCaptured フックは、エラーがさらに伝播するのを防ぐために false を返すことができます。これは本質的に「このエラーは処理済みなので、無視する必要がある」と言うことです。このエラーについて、追加の errorCaptured フックや、グローバルの config.errorHandler が呼び出されることを防ぎます。

# renderTracked

  • 型: (e: DebuggerEvent) => void

  • 詳細:

    仮想 DOM の再レンダリングが追跡されたときに呼び出されます。このフックは引数として debugger event を受け取ります。このイベントは、どの操作がコンポーネントを追跡したのか、その操作のターゲットオブジェクトとキーを教えてくれます。

  • 使用方法:

    <div id="app">
      <button v-on:click="addToCart">Add to cart</button>
      <p>Cart({{ cart }})</p>
    </div>
    
    1
    2
    3
    4
    const app = createApp({
      data() {
        return {
          cart: 0
        }
      },
      renderTracked({ key, target, type }) {
        console.log({ key, target, type })
        /* これはコンポーネントの初回レンダリングに記録されます:
        {
          key: "cart",
          target: {
            cart: 0
          },
          type: "get"
        }
        */
      },
      methods: {
        addToCart() {
          this.cart += 1
        }
      }
    })
    
    app.mount('#app')
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26

# renderTriggered

  • 型: (e: DebuggerEvent) => void

  • 詳細:

    仮想 DOM の再レンダリングが実行されたときに呼び出されます。renderTracked と同様に、引数として debugger event を受け取ります。このイベントは、どの操作が再レンダリングのきっかけとなったか、その操作のターゲットオブジェクトとキーを教えてくれます。

  • 使用方法:

    <div id="app">
      <button v-on:click="addToCart">Add to cart</button>
      <p>Cart({{ cart }})</p>
    </div>
    
    1
    2
    3
    4
    const app = createApp({
      data() {
        return {
          cart: 0
        }
      },
      renderTriggered({ key, target, type }) {
        console.log({ key, target, type })
      },
      methods: {
        addToCart() {
          this.cart += 1
          /* これにより renderTriggered を呼び出します
            {
              key: "cart",
              target: {
                cart: 1
              },
              type: "set"
            }
          */
        }
      }
    })
    
    app.mount('#app')
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26