ライフサイクル関数の親子コンポーネント 16 フックの実行順序

Outlook フィード:

1. 親子コンポーネントのペアがある

2. 親コンポーネントと子コンポーネントの両方に 8 つのフック関数があります

3. 実行シーケンスとロジックを観察します。

まず結論から言いますが、プロセスを確認したい場合は、以下を読み続けてください。

結論は:

ページが最初にレンダリングされるとき:

        1. まず、親コンポーネントのbeforeCreate、created、beforeMountの3 つのフックをトリガーします。

        2.サブコンポーネントのbeforeCreate、created、beforeMount、mountの4 つのフックをトリガーします。

        3. 最後に、マウント後に親コンポーネントのマウントされたフックをトリガーします。

ページが更新されると、次のようになります。

1. beforeUpdate と updated の2 つのフックが        サブコンポーネントの更新の前後にトリガーされます。

ページが破壊された場合:

        1. サブコンポーネントが破壊される

                BeforeUpdate と、自身の破棄をトリガーする前後の2 つのフックを更新しました

        2. 親コンポーネントが子コンポーネントを破棄する場合

                まず、親コンポーネントの beforeUpdate フックをトリガーします。

                次に、サブコンポーネントの破棄の前後にbeforeDestroyフック破棄されたフックをトリガーします。

                最後に、親コンポーネントの更新されたフックがトリガーされます。

知識ポイント:

        1.フックの作成前       

                この時点では、データ el はまだデータを初期化しておらず  、メソッドもまだ登場していません

        2.フックの作成       

                この時、data内のデータ項目は取得できますが、実際のDOMはありません。this.$dataでもデータを取得でき、メソッドも登場します。

        3.マウントフック前

                この時点で、テンプレートはメモリ内にレンダリングされていますが、まだページにはレンダリングされていません。

        4.取り付けられたフック

                この時点で、メモリ内にレンダリングされたテンプレートをブラウザに置き換えます。

        5. beforeUpdate フック       

                仮想 DOM が再レンダリングされてパッチが適用される前に呼び出されます。ここでデータを変更しても再レンダリングはトリガーされません  

        6.フックの更新        

                仮想 DOM が再レンダリングされ、パッチが適用された後に呼び出されます。この時点ではデータを変更しないでください。変更しないと、常にトリガーされます。

beforeUpdate と updated の 2 つのライフ サイクルが無限ループに入る

        7. beforeDestroyフック

                この時点で、インスタンスは破棄フェーズに入る準備ができており、データ メソッドの命令は引き続き通常どおり使用できます。

        8.破壊されたフック

                この時点で、インスタンスは破棄されており、データ メソッドの命令は使用できません。

注意点:

        グローバル変数のライフサイクル: live: ページの読み込み時 die: ページが閉じた時

        ローカル変数のライフサイクル: life: 関数が呼び出されるとき、death: 関数が呼び出されるとき

リファレンスコード(vue)

父:

<template>
  <div>
    <h1>hello</h1>
    <MySon/>
    
  </div>
</template>

<script>

import MySon from './MySon.vue'
export default {
  components:{
    MySon
  },
   beforeCreate () {
    // 1. 创建前
    console.log("beforeCreate --- 实例初始化前  父")
    console.log(this.msg) // undefined
  },
  created () {
    // 2. 创建后=> 发送ajax请求
    console.log("created ---  实例初始化后   父")
    console.log(this.msg) // "我是变量"
  },
  beforeMount () {
    // 3. 挂载前
    console.log("beforeMount --- vue的虚拟DOM, 挂载到真实的网页之前  父")
    console.log(document.getElementById("myUl")) // null
    // console.log(document.getElementById("myUl").children[1].innerHTML) // 报错
  },
  mounted () {
    // 4. 挂载后=> 操作dom
    console.log("mounted --- vue的虚拟DOM, 挂载到真实的网页上   父")
    // console.log(document.getElementById("myUl").children[1].innerHTML)
    console.log(document.querySelector('#myUl').children[1].innerText)
  },
  beforeUpdate () {
    // 5. 更新前
    console.log("beforeUpdate --- 数据更新, 页面更新前   父")
    // 比如点击新增数组元素, vue会触发此生命周期函数, 但是此时页面并未更新, 所以获取不到新增的li标签
    // console.log(document.getElementById("myUl").children[4].innerHTML) // 报错
  },
  updated () {
    // 6. 更新后
    console.log("updated --- 数据更新, 页面更新后   父")
    console.log(document.getElementById("myUl").children[4].innerHTML)
  },
  beforeDestroy () {
    // 7. 销毁前
     // (清除定时器 / 解绑js定义的事件)
    console.log("beforeDestroy --- 实例销毁之前调用   父")
    
  },
  destroyed () {
    // 8. 销毁后
    // (清除定时器 / 解绑js定义的事件)
    console.log("destroyed --- 销毁完成   父")
  },
}
</script>

<style>

</style>

子:

<template>
  <div>
    <ul id="myUl">
      <li v-for="(item, ind) in arr" :key="ind">{
   
   { item }}</li>
    </ul>
    <button
      @click="arr.push(Math.random() * 10)"
    >
      增加一个元素
    </button>
  </div>
</template>

<script>
export default {
  data () {
    return {
      msg: "我是变量",
      arr: [1, 2, 3, 4],
      isShow: true,
    }
  },
  beforeCreate () {
    // 1. 创建前
    console.log("beforeCreate --- 实例初始化前")
    console.log(this.msg) // undefined
  },
  created () {
    // 2. 创建后=> 发送ajax请求
    console.log("created ---  实例初始化后")
    console.log(this.msg) // "我是变量"
    // this.time = setInterval(() => 
    //   console.log(new Date), 1000)
  },
  beforeMount () {
    // 3. 挂载前
    console.log("beforeMount --- vue的虚拟DOM, 挂载到真实的网页之前")
    console.log(document.getElementById("myUl")) // null
    // console.log(document.getElementById("myUl").children[1].innerHTML) // 报错
  },
  mounted () {
    // 4. 挂载后=> 操作dom
    console.log("mounted --- vue的虚拟DOM, 挂载到真实的网页上 ")
    // console.log(document.getElementById("myUl").children[1].innerHTML)
    console.log(document.querySelector('#myUl').children[1].innerText)
  },
  beforeUpdate () {
    // 5. 更新前
    console.log("beforeUpdate --- 数据更新, 页面更新前")
    // 比如点击新增数组元素, vue会触发此生命周期函数, 但是此时页面并未更新, 所以获取不到新增的li标签
    // console.log(document.getElementById("myUl").children[4].innerHTML) // 报错
  },
  updated () {
    // 6. 更新后
    console.log("updated --- 数据更新, 页面更新后")
    console.log(document.getElementById("myUl").children[4].innerHTML)
  },
  beforeDestroy () {
    // 7. 销毁前
     // (清除定时器 / 解绑js定义的事件)
    console.log("beforeDestroy --- 实例销毁之前调用")
    
  },
  destroyed () {
    // 8. 销毁后
    // (清除定时器 / 解绑js定义的事件)
    console.log("destroyed --- 销毁完成")
    // clearInterval(this.time)
  },
};
</script>

<style>
</style>

効果を直接確認する

 分析します:

1. ここから、 Web ページにマウントされる前にデータを取得できないことがわかります。

2. 親と子の実行順序。最初のレンダリングでは、親コンポーネントの beforeCreate、created、beforeMount が順にトリガーされ、次に子コンポーネントの beforeCreate、created、beforeMount、mount が順にトリガーされ、最後に親コンポーネントのマウントをトリガーします

ボタンをクリックしてページを更新し、フォローアップ効果を観察します。

分析します: 

1. ここでは、サブコンポーネントのbeforeUpdate フックと updatedフックがトリガーされていることがわかります。

2. この時点で、サブコンポーネントはデータを取得しています。

3. 親コンポーネントの更新フックがトリガーされない

質問:

        では、破壊フックはどのようにトリガーされるのでしょうか?

       文字通り破壊するという意味ですが、どうやって発動させるのでしょうか?

//在子组件的ul上添加  v-if="isShow"

<ul id="myUl" v-if="isShow">

//在子组件的data新增

isShow:true


//在父组件也进行相同操作

<MySon v-if="isShow"/>

data() {
    return {
      isShow:true
    }
  },

効果を直接確認する

1 つ目はサブコンポーネントを操作することです

自身の強制終了は、自身の beforeUpdate のみをトリガーできることがわかり、更新されました

 次に、親コンポーネントを操作します

 親コンポーネントのbeforeUpdate、子コンポーネントのbeforeDestroy、destroyが順番にトリガーされ、その後親コンポーネントのupdateがトリガーされたことが判明

おすすめ

転載: blog.csdn.net/swoly2894265391/article/details/124684429