欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入理解Vue父子組件生命周期執(zhí)行順序及鉤子函數(shù)

 更新時間:2018年08月12日 11:00:17   作者:余大彬  
本文通過實例代碼給大家介紹了Vue父子組件生命周期執(zhí)行順序及鉤子函數(shù)的相關知識,非常不錯,具有一定的參考借鑒價值,需要的朋友參考下吧

先附一張官網(wǎng)上的vue實例的生命周期圖,每個Vue實例在被創(chuàng)建的時候都需要經(jīng)過一系列的初始化過程,例如需要設置數(shù)據(jù)監(jiān)聽,編譯模板,將實例掛載到DOM并在數(shù)據(jù)變化時更新DOM等。同時在這個過程中也會運行一些叫做生命周期鉤子的函數(shù)(回調(diào)函數(shù)),這給了用戶在不同階段添加自己代碼的機會。

1、vue的生命周期圖

在vue實例的整個生命周期的各個階段,會提供不同的鉤子函數(shù)以供我們進行不同的操作。先列出vue官網(wǎng)上對各個鉤子函數(shù)的詳細解析。

生命周期鉤子

生命周期鉤子    

詳細
beforeCreate 在實例初始化之后,數(shù)據(jù)觀測(data observer) 和 event/watcher 事件配置之前被調(diào)用。
created 實例已經(jīng)創(chuàng)建完成之后被調(diào)用。在這一步,實例已完成以下的配置:數(shù)據(jù)觀測(data observer),屬性和方法的運算, watch/event 事件回調(diào)。然而,掛載階段還沒開始,$el 屬性目前不可見。
beforeMount 在掛載開始之前被調(diào)用:相關的 render 函數(shù)首次被調(diào)用。
mounted el 被新創(chuàng)建的 vm.$el 替換,并掛載到實例上去之后調(diào)用該鉤子。如果 root 實例掛載了一個文檔內(nèi)元素,當 mounted 被調(diào)用時 vm.$el 也在文檔內(nèi)。
beforeUpdate 數(shù)據(jù)更新時調(diào)用,發(fā)生在虛擬 DOM 重新渲染和打補丁之前。你可以在這個鉤子中進一步地更改狀態(tài),這不會觸發(fā)附加的重渲染過程。
updated 由于數(shù)據(jù)更改導致的虛擬 DOM 重新渲染和打補丁,在這之后會調(diào)用該鉤子。當這個鉤子被調(diào)用時,組件 DOM 已經(jīng)更新,所以你現(xiàn)在可以執(zhí)行依賴于 DOM 的操作。
activated keep-alive 組件激活時調(diào)用。
deactivated keep-alive 組件停用時調(diào)用。
beforeDestroy 實例銷毀之前調(diào)用。在這一步,實例仍然完全可用。
destroyed Vue 實例銷毀后調(diào)用。調(diào)用后,Vue 實例指示的所有東西都會解綁定,所有的事件監(jiān)聽器會被移除,所有的子實例也

實例銷毀后調(diào)用。調(diào)用后,Vue 實例指示的所有東西都會解綁定,所有的事件監(jiān)聽器會被移除,所有的子實例也會被銷毀。

2、實際操作

下面我們在實際的代碼執(zhí)行過程中理解父子組件生命周期創(chuàng)建過程以及鉤子函數(shù)執(zhí)行的實時狀態(tài)變化。

測試基于下面的代碼,引入vue.js文件后即可執(zhí)行。(打開頁面后,再按一次刷新會自動進入debugger狀態(tài))

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    
  </style>
</head>  
<body>
<div id="app">
  <p>{{message}}</p>
  <keep-alive>
    <my-components :msg="msg1" v-if="show"></my-components>
  </keep-alive>
</div>
</body>
<script src="../../node_modules/vue/dist/vue.js"></script>
<script>
  var child = {
    template: '<div>from child: {{childMsg}}</div>',
    props: ['msg'],
    data: function() {
      return {
        childMsg: 'child'
      }  
    },
    beforeCreate: function () {
      debugger;
    },
    created: function () {
      debugger;
    },
    beforeMount: function () {
      debugger;
    },
    mounted: function () {
      debugger;
    },
    deactivated: function(){
      alert("keepAlive停用");
    },
    activated: function () {
      console.log('component activated');
    },
    beforeDestroy: function () {
      console.group('beforeDestroy 銷毀前狀態(tài)===============》');
      var state = {
        'el': this.$el,
        'data': this.$data,
        'message': this.message
      }
      console.log(this.$el);
      console.log(state);
    },
    destroyed: function () {
      console.group('destroyed 銷毀完成狀態(tài)===============》');
      var state = {
        'el': this.$el,
        'data': this.$data,
        'message': this.message
      }
      console.log(this.$el);
      console.log(state);
    },
  };
  var vm = new Vue({
    el: '#app',
    data: {
        message: 'father',
        msg1: "hello",
        show: true
      },
    beforeCreate: function () {
      debugger;
    },
    created: function () {
      debugger;
    },
    beforeMount: function () {
      debugger;
    },
    mounted: function () {
      debugger;  
    },
    beforeUpdate: function () {
      alert("頁面視圖更新前");
      
    },
    updated: function () {
      alert("頁面視圖更新后");
    },
    beforeDestroy: function () {
      console.group('beforeDestroy 銷毀前狀態(tài)===============》');
      var state = {
        'el': this.$el,
        'data': this.$data,
        'message': this.message
      }
      console.log(this.$el);
      console.log(state);
    },
    destroyed: function () {
      console.group('destroyed 銷毀完成狀態(tài)===============》');
      var state = {
        'el': this.$el,
        'data': this.$data,
        'message': this.message
      }
      console.log(this.$el);
      console.log(state);
    },
    components: {
      'my-components': child
    }
  });
</script>
</html>

3.1、生命周期調(diào)試

首先我們創(chuàng)建了一個Vue實例vm,將其掛載到頁面中id為“app”的元素上。

3.1.1、根組件的beforeCreate階段

可以看出,在調(diào)用beforeCreate()函數(shù)時,只進行了一些必要的初始化操作(例如一些全局的配置和根實例的一些屬性初始化),此時data屬性為undefined,沒有可供操作的數(shù)據(jù)。

3.1.2、根組件的Created階段

調(diào)用Created()函數(shù),在這一步,實例已完成以下的配置:數(shù)據(jù)代理和動態(tài)數(shù)據(jù)綁定(data observer),屬性和方法的運算, watch/event 事件回調(diào)。然而,掛載階段還沒開始,$el 屬性目前不可見。

3.1.3、根組件的beforeMount階段

在調(diào)用boforeMount()函數(shù)前首先會判斷對象是否有el選項。如果有的話就繼續(xù)向下編譯,如果沒有el選項,則停止編譯,也就意味著停止了生命周期,直到在該vue實例上調(diào)用vm.$mount(el)

在這個例子中,我們有el元素,因此會調(diào)用boforeMount()函數(shù),此時已經(jīng)開始執(zhí)行模板解析函數(shù),但還沒有將$el元素掛載頁面,頁面視圖因此也未更新。在標紅處,還是 {{message}},這里就是應用的Virtual DOM(虛擬Dom)技術,先把坑占住了。到后面mounted掛載的時候再把值渲染進去。

3.1.4、子組件的beforeCreate、Created、beforeMount、Mounted階段

在父組件執(zhí)行beforeMount階段后,進入子組件的beforeCreate、Created、beforeMount階段,這些階段和父組件類似,按下不表。beforeMount階段后,執(zhí)行的是Mounted階段,該階段時子組件已經(jīng)掛載到父組件上,并且父組件隨之掛載到頁面中。

由下圖可以知道,在beforeMount階段之后、Mounted階段之前,數(shù)據(jù)已經(jīng)被加載到視圖上了,即$el元素被掛載到頁面時觸發(fā)了視圖的更新。

3.1.5、子組件的activated階段

我們發(fā)現(xiàn)在子父組件全部掛載到頁面之后被觸發(fā)。這是因為子組件my-components被<keep-alive> 包裹,隨$el的掛載被觸發(fā)。如果子組件沒有被<keep-alive>包裹,那么該階段將不會被觸發(fā)。

3.1.6、父組件的mounted階段

mounted執(zhí)行時:此時el已經(jīng)渲染完成并掛載到實例上。

至此,從Vue實例的初始化到將新的模板掛載到頁面上的階段已經(jīng)完成,退出debugger。下面我們來看一下deactivated、beforeUpdate、updated、beforeDestroy、destroyed鉤子函數(shù)。

3.2、deactivated、beforeUpdate、updated階段

由生命周期函數(shù)可知:當數(shù)據(jù)變化后、虛擬DOM渲染重新渲染頁面前會觸發(fā)beforeUpdate()函數(shù),此時視圖還未改變。當虛擬DOM渲染頁面視圖更新后會觸發(fā)updated()函數(shù)。

我們不妨改變vm.show = false,當修改這個屬性時,不僅會觸發(fā)beforeUpdate、updated函數(shù),還會觸發(fā)deactivated函數(shù)(因為keep-alive 組件停用時調(diào)用)。我們不妨想一下deactivated函數(shù)會在beforeUpdate后還是updated后調(diào)用。

我們在控制臺輸入vm.show = false。得到三者的調(diào)用順序分別為beforeUpdate、deactivated、updated。我們可以知道的是deactivated函數(shù)的觸發(fā)時間是在視圖更新時觸發(fā)。因為當視圖更新時才能知道keep-alive組件被停用了。

3.3、beforeDestroy和destroyed鉤子函數(shù)間的生命周期

現(xiàn)在我們對Vue實例進行銷毀,調(diào)用app.$destroy()方法即可將其銷毀,控制臺測試如下:

我們發(fā)現(xiàn)實例依然存在,但是此時變化已經(jīng)發(fā)生在了其他地方。

beforeDestroy鉤子函數(shù)在實例銷毀之前調(diào)用。在這一步,實例仍然完全可用。

destroyed鉤子函數(shù)在Vue 實例銷毀后調(diào)用。調(diào)用后,Vue 實例指示的所有東西都會解綁定,所有的事件監(jiān)聽器會被移除,所有的子實例也會被銷毀(也就是說子組件也會觸發(fā)相應的函數(shù))。這里的銷毀并不指代'抹去',而是表示'解綁'。

銷毀時beforeDestory函數(shù)的傳遞順序為由父到子,destory的傳遞順序為由子到父。

4、一些應用鉤子函數(shù)的想法在created鉤子中可以對data數(shù)據(jù)進行操作,這個時候可以進行ajax請求將返回的數(shù)據(jù)賦給data。

雖然updated函數(shù)會在數(shù)據(jù)變化時被觸發(fā),但卻不能準確的判斷是那個屬性值被改變,所以在實際情況中用computed或match函數(shù)來監(jiān)聽屬性的變化,并做一些其他的操作。在mounted鉤子對掛載的dom進行操作,此時,DOM已經(jīng)被渲染到頁面上。在使用vue-router時有時需要使用<keep-alive></keep-alive>來緩存組件狀態(tài),這個時候created鉤子就不會被重復調(diào)用了,如果我們的子組件需要在每次加載或切換狀態(tài)的時候進行某些操作,可以使用activated鉤子觸發(fā)。所有的生命周期鉤子自動綁定this上下文到實例中,所以不能使用箭頭函數(shù)來定義一個生命周期方法(例如created: () => this.fetchTodos())。這是導致this指向父級。

5、 小結

加載渲染過程

  父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted

子組件更新過程

  父beforeUpdate->子beforeUpdate->子updated->父updated

父組件更新過程

  父beforeUpdate->父updated

銷毀過程

  父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

總結

以上所述是小編給大家介紹的Vue父子組件生命周期執(zhí)行順序及鉤子函數(shù),希望對大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會及時回復大家的!

相關文章

  • vue中數(shù)組加Key方式

    vue中數(shù)組加Key方式

    這篇文章主要介紹了vue中數(shù)組加Key方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • vue 組件中添加樣式不生效的解決方法

    vue 組件中添加樣式不生效的解決方法

    這篇文章主要介紹了vue 組件中添加樣式不生效的解決方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07
  • vue前后端端口不一致的問題解決

    vue前后端端口不一致的問題解決

    本文主要介紹了vue前后端端口不一致的問題解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-10-10
  • Vue.sync修飾符與$emit(update:xxx)詳解

    Vue.sync修飾符與$emit(update:xxx)詳解

    這篇文章主要介紹了Vue.sync修飾符與$emit(update:xxx),實現(xiàn)思路非常簡單,文章介紹了.sync修飾符的作用和使用.sync修飾符的寫法,實現(xiàn)代碼簡單易懂對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-11-11
  • VUE3中h()函數(shù)和createVNode()函數(shù)的使用解讀

    VUE3中h()函數(shù)和createVNode()函數(shù)的使用解讀

    這篇文章主要介紹了VUE3中h()函數(shù)和createVNode()函數(shù)的使用解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • 如何使用vue開發(fā)公眾號網(wǎng)頁

    如何使用vue開發(fā)公眾號網(wǎng)頁

    因為項目需要,近期做了一個公眾號網(wǎng)頁開發(fā)。在此期間也踩了一些坑,解決這些坑之后,準備對這個項目進行復盤。記錄下項目從開發(fā)到上線所解決的問題,并對使用vue進行公眾號開發(fā)的步驟進行一個總結。方便以后有問題進行查閱。希望對你有所幫助
    2021-05-05
  • vue2.0實現(xiàn)選項卡導航效果

    vue2.0實現(xiàn)選項卡導航效果

    這篇文章主要為大家詳細介紹了vue2.0實現(xiàn)選項卡導航效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 深入探討Vue3中Composition API的使用方法

    深入探討Vue3中Composition API的使用方法

    Vue3的Composition API是一個全新的API,它允許開發(fā)人員將Vue組件中的邏輯封裝在單獨的功能性組合中,而不是依賴于Vue選項對象。這篇文章將深入探討Vue3的Composition API及其使用方法,需要的朋友可以參考下
    2023-07-07
  • ant-design-vue中設置Table每頁顯示的條目數(shù)量方式

    ant-design-vue中設置Table每頁顯示的條目數(shù)量方式

    這篇文章主要介紹了ant-design-vue中設置Table每頁顯示的條目數(shù)量方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • vue中利用prop進行父子通信時的注意事項總結

    vue中利用prop進行父子通信時的注意事項總結

    這篇文章主要給大家介紹了關于vue中利用prop進行父子通信時的注意事項,文中通過實例介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2022-01-01

最新評論