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がトリガーされたことが判明