App下載

Vue 組件生命周期

猿友 2021-02-18 20:32:06 瀏覽數(shù) (13677)
反饋

1. 組件的生命周期的四個(gè)階段

組件的生命周期分為四個(gè)階段:
- create(創(chuàng)建)
- mount(掛載)
- update(更新)
- destroy(銷(xiāo)毀)

2. 生命周期鉤子函數(shù)

2.1 鉤子函數(shù)定義

  • 先看看官方的解釋?zhuān)?nbsp;   每個(gè) Vue 實(shí)例在被創(chuàng)建時(shí)都要經(jīng)過(guò)一系列的初始化過(guò)程——例如,需要設(shè)置數(shù)據(jù)監(jiān)聽(tīng)、編譯模板、將實(shí)例掛載到 DOM 并在數(shù)據(jù)變化時(shí)更新 DOM 等。同時(shí)在這個(gè)過(guò)程中也會(huì)運(yùn)行一些叫做生命周期鉤子的函數(shù),這給了用戶在不同階段添加自己的代碼的機(jī)會(huì)。
  • 鉤子函數(shù)到底是個(gè)啥意思呢?    組件在加載的過(guò)程中,加載到某個(gè)階段時(shí),自動(dòng)觸發(fā)的函數(shù)

2.2 鉤子函數(shù)理解與實(shí)例

鉤子函數(shù)有哪些?怎么用?

結(jié)合圖來(lái)看~~~下圖展示了組件的生命周期的過(guò)程:(下面會(huì)詳細(xì)解釋每個(gè))

無(wú)標(biāo)題

1. beforeCreate 在實(shí)例初始化之后,數(shù)據(jù)觀測(cè)(data observer) 和 event/watcher 事件配置之前被調(diào)用;如果在 beforeCreate 函數(shù)里面去訪問(wèn) data 數(shù)據(jù)對(duì)象,是訪問(wèn)不到的

<body>
  <div id="app">
    <input type="text" v-model="msg">
  </div>
  <script>
    new Vue({
      el:"#app",
      data:{
        msg:'123'
      },
      watch:{
        msg:function(){
          console.log("我變了");
        }
      },
      beforeCreate(){
        console.log("創(chuàng)建組件data對(duì)象之前自動(dòng)觸發(fā)~~~");
        console.log("beforeCreate",this.msg);
      }
    })
  </script>
</body>

結(jié)果:在 beforeCreate 函數(shù)中無(wú)法得到 msg 的值
在這里插入圖片描述
2. created

  • 在執(zhí)行 created 函數(shù)前,已經(jīng)有了數(shù)據(jù)對(duì)象 data,以及完成了事件的初始化,但$el 屬性目前不可見(jiàn);
  • 在 created 函數(shù)里面可以使用數(shù)據(jù),也可以更改數(shù)據(jù);
  • 調(diào)用 Vue 方法,可以獲取原本 HTML 上的直接加載出來(lái)的 DOM,但是無(wú)法獲取到通過(guò)掛載模板生成的 DOM(例如:v-for循環(huán)遍歷 Vue.list 生成 li)
<body>
  <div id="app">
    <input type="text" v-model="msg">
  </div>
  <script>
    new Vue({
      el:"#app",
      data:{
        msg:'123'
      },
      watch:{
        msg:function(){
          console.log("我變了");
        }
      },
      beforeCreate(){
        console.log("創(chuàng)建組件data對(duì)象之前自動(dòng)觸發(fā)~~~");
        console.log("beforeCreated",this.msg);

      },
      created:function(){
        console.log("創(chuàng)建組件data對(duì)象之后自動(dòng)觸發(fā)~~~");
        this.msg=100000;
        console.log("created",this.msg);   
        console.log("li數(shù)量:",document.getElementsByTagName("li").length);
        console.log("p數(shù)量:",document.getElementsByTagName("p").length); 
      }
    })
  </script>

結(jié)果:在 created 函數(shù)中我們成功的拿到了、更改了 msg 的值。并且數(shù)據(jù)被更改后出發(fā)了watch 屬性中的方法。 而且可以獲取原本HTML 上的直接加載出來(lái)的 DOM(p 元素),但是無(wú)法獲取到通過(guò)掛載模板生成的 DOM(例如:v-for 循環(huán)遍歷 Vue.list 生成 li 元素)在這里插入圖片描述

注意:create階段還沒(méi)有創(chuàng)建虛擬dom

3.beforeMount

  • 在掛載開(kāi)始之前被調(diào)用,相關(guān)的(渲染函數(shù))模板首次被調(diào)用。$el 屬性可見(jiàn)。但此時(shí)在 beforeMount 函數(shù)中依然無(wú)法無(wú)法獲取到通過(guò)掛載模板生成的DOM(例如:v-for 循環(huán)遍歷 Vue.list 生成 li 元素)
  • 在此函數(shù)之前都沒(méi)有建立虛擬dom
beforeMount:function(){
        console.log(this.$el);
        console.log("li數(shù)量:",document.getElementsByTagName("li").length);
      }

結(jié)果:

screenshot-20210218-194134

4.mounted

  • 執(zhí)行完 beforeMount 函數(shù)后,$e l elel 被新創(chuàng)建的 vm.$el 替換,并掛載到實(shí)例上去之后調(diào)用該鉤子函數(shù)。
  • 這里才能獲取初始數(shù)據(jù)list渲染出來(lái)的li
  • 掛載后我們已經(jīng)可以看見(jiàn)網(wǎng)頁(yè)內(nèi)容了,只不過(guò)還未操作
mounted:function(){
        console.log(this.$el);
        console.log("li數(shù)量:",document.getElementsByTagName("li").length);
      }

結(jié)果:同樣的代碼,放在 beforeMount 和 mounted 函數(shù)中結(jié)果完全不一樣

在這里插入圖片描述

在 update 階段,虛擬 dom 監(jiān)聽(tīng)數(shù)據(jù)變化,隨時(shí)更新 dom

5. beforeUpdate 當(dāng)數(shù)據(jù)發(fā)生變化的時(shí)候,beforeUpdate 這個(gè)鉤子函數(shù)才會(huì)執(zhí)行 

6. updated 虛擬 dom 重新渲染后執(zhí)行

7.beforeDestroy 實(shí)例銷(xiāo)毀之前調(diào)用。在這一步,實(shí)例仍然完全可用 

8.destroyedVue 實(shí)例銷(xiāo)毀后調(diào)用。調(diào)用后,Vue 實(shí)例指示的所有東西都會(huì)解綁定,所有的事件監(jiān)聽(tīng)器會(huì)被移除,所有的子實(shí)例也會(huì)被銷(xiāo)毀。

<body>
  <div id="app">
    <input type="text" v-model="msg">
    <ul>
      <li v-for="(elem,index) of list" :key="index">{{elem}}</li>
    </ul>
    <p>p1</p>
    <p>p2</p>
    <p>p3</p>
    <h1>數(shù)量:{{count}}</h1>
  </div>
  <script>
    new Vue({
      el:"#app",
      data:{
        msg:'123',
        list:['a','b','c'],
        count:0
      },
      watch:{
        msg:function(){
          console.log("我變了");
        }
      },
      beforeCreate(){
        console.log("創(chuàng)建組件data對(duì)象之前自動(dòng)觸發(fā)~~~");
        console.log("beforeCreated",this.msg);

      },
      created:function(){
        console.log("創(chuàng)建組件data對(duì)象之后自動(dòng)觸發(fā)~~~");
        this.msg=100000;
        console.log("created",this.msg); 
        console.log("li數(shù)量:",document.getElementsByTagName("li").length);
        console.log("p數(shù)量:",document.getElementsByTagName("p").length);  
      },
      beforeMount:function(){
        console.log(this.$el);
        console.log("li數(shù)量:",document.getElementsByTagName("li").length);
      },
      mounted:function(){
        console.log(this.$el);
        console.log("li數(shù)量:",document.getElementsByTagName("li").length);
        setInterval(()=>{
          this.count++;
        },1000)
      },
      beforeUpdate(){
        console.log("更新組件的data變量前自動(dòng)觸發(fā)~~~")
      },
      updated(){
        console.log("更新組件的data變量后自動(dòng)觸發(fā)~~~");
        if(this.count>3){
          this.$destroy();
        }
      },
      beforeDestroy(){
        console.log("銷(xiāo)毀當(dāng)前組件前自動(dòng)觸發(fā)~~~")
      },
      destroyed(){
        console.log("銷(xiāo)毀組件后自動(dòng)觸發(fā)~~~");
      }
    })
  </script>
</body>

結(jié)果:

screenshot-20210218-194001

組件的生命周期就是這樣啦~


2 人點(diǎn)贊