父子元件的生命週期執行流程是怎麼樣的呢?

語言: CN / TW / HK

在vue中有一道面試必問題,那就是vue的生命週期。

月薪5K的回答:

beforeCreate=>created=>beforeMount=>mounted=> beforeUpdate=>updated=>beforeDestroy=>destroyed

有點經驗的能勉強扯扯keep-alive的兩個生命週期:

activated和deactivated

正文:

我們都知道vue是元件化開發思想,下面來丟擲我們日常開發中最常見的一個業務場景,比如一個編輯功能如下圖:有兩個元件,父元件巢狀子元件,在子元件裡面有一個下拉選擇框,我們在父元件裡面調後端介面獲取資料,傳給子元件,渲染到頁面。你是怎麼做的呢?

image.png

一、錯誤寫法:

在父元件的Created,獲取資料賦值給data物件,然後通過prop的方式傳給子元件,子元件在Created裡面接收處理資料,渲染到頁面。

對於元件通訊,要補課的同學可以看看我這篇文章。

元件通訊的8種方式,你搞清楚了嗎?

下面我們來演示這種錯誤寫法:

父元件:

image.png

子元件:

image.png

子元件資料:

image.png

在子元件的ceated裡面處理父元件傳過來的資料:

image.png

頁面效果:

image.png

頁面顯示了列舉值5對應的城市:廈門。

很多人是不是在想:咦~東東吖,你不是說這是錯誤寫法嗎?這不就是我們想要的效果嗎?我平時也是這樣寫的,沒有問題呀!!!

別急,我們是不是漏了什麼呢???我剛剛說的是從後端獲取資料,從後端獲取資料我們的資料會受到網路等因素的影響,那代表什麼?那代表會有非同步產生。

我們用settimeout來模擬非同步請求。

image.png

這個時候我們會發現,我們的頁面是沒有選中的,平時大家這樣寫,是會有bug的,因為我們的資料會受到網路等因素制約,當後端返回的資料比較快時,我們可能在頁面正常展示了資料,但當後端返回的資料較慢時,我們的頁面就不能正常地展示資料,就會出現bug,而且這種bug不是必現的,有的同學就會覺得很詭異。對了,這裡除了網路因素,元件被v-show控制時,元件沒有被銷燬,只會在第一次走created這個生命週期,比如你點選多條資料的編輯按鈕,還可能出現上一條的資料。我們需要編輯的時候把上一次的值置空,再獲取對應的值賦值

那怎麼解決呢?我們都是知道初次渲染,單元件的生命週期是:

beforeCreate=>created=>beforeMount=>mounted

那父子元件他們的生命週期又是怎麼樣的呢?

少廢話,控制檯:

image.png

我們發現父子元件的生命週期執行流程:父元件執行了前三個生命週期:beforeCreate=>created=>beforeMounted,然後等子元件執行完四個生命週期:beforeCreate=>created=>beforeMount=>mounted,父元件再執行了mountedued

父元件先執行了Created這個生命週期,然後等子元件執行了Created,最後再掛載的,按道理我們在父元件的Created裡面通過props傳值,在子元件的Created裡面處理資料是沒問題的,但是你有沒有想過,我們的生命週期不會等我們的非同步請求呀,尤雨溪對vue做效能設計的時候可沒那麼傻。

對了,尤雨溪懂個錘子vue(滑稽)!來人,給我把尤雨溪摁住!!!前兩天聽他直播講vue3的生態,最近一兩個月他就要強制更新vue的官網到vue3了。

_-1916587870_IMG_20211023_114401_1634960644000_xg.jpg

迴歸正題:

我們在父元件的Created裡面模擬一個非同步請求:

image.png

在父子元件裡面的created裡面列印這個列舉值值,開啟控制檯檢視結果:

image.png

我們發現無論父元件還是子元件,我們都不能獲取到我們的列舉值6

要想在子元件獲取到這個列舉值6,渲染到頁面上,我們應該怎麼做呢?

二、野雞寫法:

這時候,有的同學就會想到,我們只要在子元件裡面獲取到這個值,就能解決這個bug,那我們能不能利用v-if重新構建vue例項呢?從而打斷我們的父子元件原本的生命週期執行流程。當value存在的時候再渲染這個子元件

image.png

我們開啟控制檯檢視結果,發現父子元件的生命週期執行流程被v-if阻斷了,變成了兩個單元件的生命週期,先執行了父元件,當value這個值存在的時候,再建立vue例項,執行子元件的生命週期,並在子元件成功獲取到了這個列舉值6

image.png

頁面效果:

image.png

這個時候頁面確實展示了我們想要的效果,但是這個子元件是獲取到值了,才渲染的,也就是說,他獲取到值了,整個子元件1秒後才閃現展示到我們的頁面的(自行想象),我不能說你這種寫法錯誤,只能這種寫法真的野雞。

野雞???

啥是野雞? 懂的都懂,不懂的請輸入以下詞條自行類比:

image.png

三、家雞寫法:

用watch監聽屬性值,監聽到值後,再處理資料。

image.png

開啟控制檯,我們是發現我們是能在watch裡面監聽到這個列舉值6的。

image.png

頁面效果:"美麗,這個問題解決了"。

image.png

最後補充一點:我們這裡是監聽的一個屬性,當我們監聽的是一個物件,還需要利用deep深度監聽,並通過immediate立即渲染。這裡我就不再演示了,同學們自己試一試哦(其實是因為我懶,不想寫示例了,哈哈哈)

image.png

總結:

對於一些配置資料,比如我們需要傳入一個屬性,來控制disabled,這種可以直接在元件上賦值,類似於第一種Created裡面直接賦值,不過在元件上直接賦值程式碼更加簡潔。但對於非同步資料,我們必須用watch來監聽賦值,如果監聽的是物件,還需要設定深度監聽和立即渲染兩個屬性。

最後:還有什麼寫法,歡迎在評論區留言哦!