【Vue2.0ソースコード学習】ライフサイクル - 破壊フェーズ(destroy)

1 はじめに

次に、ライフ サイクル プロセスの最後の段階である破壊段階が始まります。公式ドキュメントに記載されているライフサイクル フローチャートから、 vm.$destroy メソッドが呼び出されると、 Vue インスタンスが破棄フェーズに入ることがわかります。このフェーズの主なジョブは、 現在Vue インスタンスを親インスタンスから削除し、現在のインスタンスのすべての依存関係追跡をキャンセルし、インスタンス上のすべてのイベント リスナーを削除することです。言い換えれば、この段階が完了すると、現在のインスタンスのライフプロセス全体が完了し、最終的には「消滅」します。 Vue

画像

この記事では、破壊段階でどのような作業が行われるかを分析します。

2. 破壊段階の分析

前述したように、インスタンスの $destroy メソッドが呼び出されると、現在のインスタンスは破棄フェーズに入ります。したがって、分析と破棄のフェーズでは、$destroy メソッドの内部実装を分析します。このメソッドの定義は、次のようにソース コードの src/core/instance.lifecycle.js にあります。

Vue.prototype.$destroy = function () {
    
    
  const vm: Component = this
  if (vm._isBeingDestroyed) {
    
    
    return
  }
  callHook(vm, 'beforeDestroy')
  vm._isBeingDestroyed = true
  // remove self from parent
  const parent = vm.$parent
  if (parent && !parent._isBeingDestroyed && !vm.$options.abstract) {
    
    
    remove(parent.$children, vm)
  }
  // teardown watchers
  if (vm._watcher) {
    
    
    vm._watcher.teardown()
  }
  let i = vm._watchers.length
  while (i--) {
    
    
    vm._watchers[i].teardown()
  }
  // remove reference from data ob
  // frozen object may not have observer.
  if (vm._data.__ob__) {
    
    
    vm._data.__ob__.vmCount--
  }
  // call the last hook...
  vm._isDestroyed = true
  // invoke destroy hooks on current rendered tree
  vm.__patch__(vm._vnode, null)
  // fire destroyed hook
  callHook(vm, 'destroyed')
  // turn off all instance listeners.
  vm.$off()
  // remove __vue__ reference
  if (vm.$el) {
    
    
    vm.$el.__vue__ = null
  }
  // release circular reference (##6759)
  if (vm.$vnode) {
    
    
    vm.$vnode.parent = null
  }
}

ご覧のとおり、上記のコードでは、まず現在のインスタンスの _isBeingDestroyed 属性が true であるかどうかを判断します。この属性は、現在のインスタンスは in 状態が破棄されている場合、 true の場合は、 return 関数を直接終了して、破棄ロジックが繰り返し実行されるのを防ぎます。次のように:

const vm: Component = this
if (vm._isBeingDestroyed) {
    
    
  return
}

次に、ライフ サイクル フック関数をトリガーしますbeforeDestroy。このフック関数の呼び出しは、現在のインスタンスの破棄の正式な開始を示します。次のように:

callHook(vm, 'beforeDestroy')

次に、現在のインスタンスを破棄する実際のロジックに入ります。

まず、次のように、現在のVueインスタンスを親インスタンスから削除する必要があります。

const parent = vm.$parent
if (parent && !parent._isBeingDestroyed && !vm.$options.abstract) {
    
    
  remove(parent.$children, vm)
}

上記のコードは次のことを意味します。現在のインスタンスに親インスタンスがあり、その親インスタンスが破棄されておらず、抽象コンポーネントではない場合、現在のインスタンスは親インスタンスから削除されます。< a i=1> 属性から削除します。つまり、親インスタンスの子インスタンスのリストから自分自身を削除します。 $children

親インスタンスの子インスタンスのリストから自分自身を削除した後、自分自身の依存関係の追跡とイベント リスニングの削除を開始します。

インスタンスに対する依存関係は 2 つの部分で構成されていることがわかっています。1 つは、インスタンス自体が他のデータに依存しており、インスタンス自体を他のデータの依存関係リストから削除する必要があるということです。もう 1 つは、インスタンス内のデータの他のデータへの依存 (ユーザーが $watch を使用して依存関係を作成する場合)、インスタンス内のデータは他のデータの依存関係リストからも削除する必要があります。したがって、依存関係を削除する場合は、依存関係の両方の部分を削除する必要があります。次のように:

// teardown watchers
if (vm._watcher) {
    
    
  vm._watcher.teardown()
}
let i = vm._watchers.length
while (i--) {
    
    
  vm._watchers[i].teardown()
}

上記のコードでは、まずvm._watcher.teardown()を実行して、他のデータの依存関係リストからインスタンス自体を削除します。teardownこのメソッドの機能は次のとおりです。すべての依存関係を削除します。 Dep リストから自分自身を削除します。前回の記事で initState 関数を紹介したとき、インスタンス内のデータの他のデータに対する依存関係はすべて _watchers 属性に保存されることがわかりました。したがって、 _watchers を走査し、各 watcher に対して teardown メソッドを呼び出して削除するだけです。インスタンス内のデータが他のデータに与える影響。

次に、インスタンス内の応答データへの参照を削除し、現在のインスタンスに _isDestroyed 属性を追加して、現在のインスタンスが破棄されたことを示し、インスタンスの に設定されます:VNodeツリーは次のようにnull

if (vm._data.__ob__) {
    
    
  vm._data.__ob__.vmCount--
}
vm._isDestroyed = true
vm.__patch__(vm._vnode, null)

次に、次のようにライフ サイクル フック関数をトリガーしますdestroyed

callHook(vm, 'destroyed')

最後に、インスタンスのvm.$off メソッド (このメソッドについては、後でインスタンス メソッドを紹介するときに詳しく説明します) を呼び出して、インスタンス上のすべてのイベント リスナーを削除します。次のように:

vm.$off()

最後に、関連する属性への参照をいくつか削除します。この時点で、現在のインスタンスは破棄されます。

3. まとめ

この記事では、ライフサイクル プロセスの最終段階である破壊段階について紹介します。

インスタンスの vm.$destory メソッドが呼び出されると、インスタンスは破棄フェーズに入ることがわかっています。このフェーズで行われる主な作業は、現在の Vue インスタンスが親インスタンスから削除され、現在のインスタンスのすべての依存関係の追跡がキャンセルされ、インスタンスのすべてのイベント リスナーが削除されます。そして、行われた作業はソース コードに対して 1 行ずつ分析されました。

おすすめ

転載: blog.csdn.net/weixin_46862327/article/details/133632171
おすすめ