vue生命周期

来源:http://www.cnblogs.com/emma0118/archive/2017/04/03/6660004.html
-Advertisement-
Play Games

vue所有功能的實現都是圍繞其生命周期進行的,在生命周期的不同階段調用對應的鉤子函數可以實現組件數據管理和DOM渲染兩大重要功能。學習實例的生命周期,能幫助我們理解vue實例的運行機制,更好地利用鉤子函數完成我們的業務代碼。 1、即將創建:對應的鉤子函數為beforeCreate。此階段為實例初始化 ...


vue所有功能的實現都是圍繞其生命周期進行的,在生命周期的不同階段調用對應的鉤子函數可以實現組件數據管理和DOM渲染兩大重要功能。學習實例的生命周期,能幫助我們理解vue實例的運行機制,更好地利用鉤子函數完成我們的業務代碼。

1、即將創建:對應的鉤子函數為beforeCreate。此階段為實例初始化之後,此時的數據觀察和事件機制都未形成。

<template>
    <div class="router-page-wrap" style="background: #fc595d;">
        this is usercenter
        <input type="text" v-model="message" ref="input">
        {{message}}
    </div>
</template>
<script>
    var common = require('common');
    module.exports = {
        data : function() {
            return {
                message : 'not update'
            }
        },
        beforeCreate : function () {
            console.log('this is beforeCreate :', this.message, this.$refs.input);
        }
    }
</script>

得到的結果是:



此時,實例中的data和el都是undefined。因此,在beforeCreate鉤子函數中不能使用data中的數據,也不能獲得DOM節點。


 

 

2、創建完畢:對應的鉤子函數為created。在這個階段vue實例已經創建,我們在同樣列印一下data和DOM元素。

上面代碼的基礎上我們添加created鉤子函數:

得到的結果是什麼呢??

 此時,我們能夠讀取到數據data的值,但是DOM還沒有生成,所以和DOM相關的屬性還不存在,自然也就不能獲取DOM元素。在Vue2的源碼中也是這樣描述的:

首先,運行new Vue()的時候,會進入代碼src/core/instance/index.js的Vue構造方法中,並執行this._init()方法。在_init中,會對各個功能進行初始化,並執行beforeCreatecreated兩個生命周期方法。核心代碼如下:

initLifecycle(vm)
initEvents(vm)
callHook(vm, 'beforeCreate')
initState(vm)
callHook(vm, 'created')
initRender(vm)

可以看到,到當執行鉤子函數created時,complier還沒有將template解析成render方法,DOM自然不能獲取

 


 

 3、即將掛載:對應的鉤子函數是beforemount。在上個階段我們知道DOM還沒生成,相關屬性還是undefined,那麼此階段為即將掛載,將發生什麼呢?

增加一下代碼:

 列印一下,我們得到:

結果好像和上一個階段並沒有什麼區別......弄的我好失落....那到底beforeMount這個階段的意義是什麼呢?難道這是vue給我設的一個坑??等等~,先別跳!!讓我們問問源(zu)碼(zong)(︶.̮︶✽)

if (vm.$options.el) {
  vm.$mount(vm.$options.el)
}

在vue2的源碼中在講述mount這一重要步驟時進行了一個關鍵的判斷,就是判斷vue的掛載節點是否存在!!那麼,掛載節點時如何存在了的呢?這一定就是在beforeMount這一階段完成的!讓我們馬上上代碼實驗一下剛纔的斷言。在這裡換一種創建vue的方式。

現在我們知道vue實例和DOM其實是分開的兩個概念,然而,vue實例的必須和DOM相關聯並改變DOM才能完成它的使命。這就需要將Vue掛載到DOM上。因此,vue提供了一個el參數來確定掛載的DOM節點。當我們根據vue構造函數new出一個Vue時,只要設定了這個el元素,那麼這個新的Vue一切操作將只對這個el及其子元素有效。

這時我們將得到列印的結果如下:

可以看到,這裡數據name的值還沒被渲染到DOM中,然而通過id已經能夠取得dom的根節點了,這個節點即掛載節點。

走到這裡,beforeMount的意義已經逐漸清晰了。在這一階段,我們雖然依然得不到具體的DOM元素,但vue掛載的根節點已經創建,下麵vue對DOM的操作將圍繞這個el繼續進行。在這個階段vue成功獲得了DOM王國國王--根元素el的信任,之後vue通過掌控“數據驅動”這台國家機器獲得了對DOM王國的絕對統治權,“挾天子以令諸侯”,vue的所有命令都將在對DOM每個元素的控制中得到精確執行。

beforeMount這個階段是過渡性的,一般一個項目只能用到一兩次,但它卻是意義非凡的!!在它之後vue將執行mount函數,帶有vue屬性的DOM及vue數據將全部被呈現,$refs將可以在DOM中使用並獲取元素。最重要的是,之後我們將迎來輝煌的mounted階段。beforeMount這個過程在Vue2的源碼中是這樣描述的:

可以看出,$mount函數的操作都基於beforeMount階段獲取的根元素el。($mount函數將根據el,template,render屬性調用render方法,即我們平時說的compile過程。compile會把我們寫的vue語言編譯成render(JSX),這一步一般都是構建工具幫我們完成的啦,啦啦啦~)。

根據源碼,_render方法執行完之後,會執行_mount方法,在這個過程中會首先new出形成一個watcher對象,會運行傳入的一個_render方法主要就是運行之前compile的render方法,形成vNode節點,也就是大名鼎鼎的虛擬DOM。拿到vNode後,傳入vm._update()方法,進行DOM更新。(watcher和下麵將講到的update涉及到虛擬DOM原理,會在以後的文章中結合vue詳細說明,感覺自己挖了一個坑~~)


 

4、渲染完畢:對應的鉤子函數是mounted。mounted是平時我們使用最多的函數了,一般我們的非同步請求都寫在這裡。在這個階段,數據和DOM都已被渲染出來。

繼續增加代碼:

列印一下:

“千呼萬喚始出來”,我們終於得到了想要的結果!!

不過,這並不是最終的結果。(◐ˍ◑),因為更新即將到來~


 

 

5、即將更新渲染:對應的鉤子函數是beforeUpdate。vue遵循數據驅動DOM的原則,當我們修改vue實例的data時,vue會自動幫我們更新視圖。那麼當我們調用beforeMount函數時,會發生什麼呢?

為了說明數據變化對DOM的影響,我首先更新代碼,增加了一個method方法。到目前為止,代碼如下:

<template>
    <div class="router-page-wrap" style="background: #fc595d;">
        this is usercenter
        <input type="text" v-model="message" ref="input" id="input">
        <em ref="em">{{message}}</em>
        <button v-touch:tap="messageChange">changeMessage</button>
    </div>
</template>
<script>
    var common = require('common');
    module.exports = {
        data : function() {
            return {
                message : '我的博客園'
            }
        },
        methods : {
            messageChange : function () {
                this.message = 'emma的博客園'
            }
        },
        beforeCreate : function () {
            console.log('this is beforeCreate :', this.message, this.$refs.input);
        },
        created : function () {
            console.log('this is created :')
            console.log('message :' , this.message);
            console.log('DOM element:', this.$refs.input);
        },
        beforeMount : function () {
            console.log('this is beforeMount :')
            console.log('message :' , this.message);
            console.log('DOM element:', this.$refs.input);
        },
        mounted : function () {
            console.log('this is mounted :')
            console.log('message :' , this.message);
            console.log('DOM element:', this.$refs.input);
        },
        beforeUpdate : function () {
            console.log('=即將更新渲染=');
            let name = this.$refs.em.innerHTML;
            console.log('name:'+name);
        }
    }
</script>

運行之後:

 

可以看到,beforeUpdate函數在數據更新後並沒立即更新數據,但是DOM中的數據已經改變,這是Vue雙向數據綁定的作用,以後也會講到,哇塞,又一個坑~~


 

6、更新渲染後:對應的鉤子函數是updated。為了不使看到同-函數在不能階段的效果,我註釋掉beforeUpdate函數,添加update函數並綁定了剛纔的click事件。

我們得到預料中的結果:

現在DOM終於和我們更改過的內容同步了!


 

 

7、銷毀之前:對應的鉤子函數是beforeDestroy。到上一步vue已經成功的通過數據驅動DOM更新,當我們不在需要vue操縱DOM時,就需要銷毀Vue,也就是清除vue實例與DOM的關聯,調用destroy方法可以銷毀當前組件。在銷毀前,會觸發beforeDestroy鉤子函數。

8、銷毀之後:對應的鉤子函數是destroyed。在銷毀後,會觸發destroyed鉤子函數。

我們通過調用destroy函數觀察vue實例銷毀前後vue和DOM的變化。增加代碼如下:

調用destroy前,我們改變name,在視圖隨之改變,beforeDestroy獲取的DOM和我們更新後的結果一致。

調用destroy後,我們改變name,視圖不會改變,destroyed也不會獲取到DOM信息了。

銷毀之前,修改name的值,可以成功修改視圖顯示的內容為更新後的內容,調用實例的$destroy( )方法之後,vue實例與DOM的關係解綁,vue數據的任何變化都不會使DOM更新,說明實例成功被銷毀了~~


 

 

vue的生命周期的思想貫穿在組件開發的始終,通過熟悉其生命周期調用不同的鉤子函數,我們可以準確地控制數據流和其對DOM的影響;vue生命周期的思想是Vnode和MVVM的生動體現和繼承,以後我將繼續學習相關的知識,在一個更高的高度學習vue,我會在學習中繼續和大家不斷分享學習的點滴感悟,更希望獲得大家對我的文章積極提出問題和建議,我們共同討論,共同進步~~

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 什麼是模板引擎 模板引擎是為了使用戶界面與業務數據(內容)分離而產生的,它可以生成特定格式的文檔,用於網站的模板引擎就會生成一個標準的HTML文檔.其本質是利用正則表達式,替換模板當中預先定義好的標簽. 常用模板引擎 "ArtTemplate" "BaiduTemplate" "velocity.j ...
  • 什麼是ajax Ajax(Asynchronous JavaScript and XML),是一種可以向伺服器請求額外的數據並且無需刷新頁面的技術,ajax的出現帶來了更好的用戶體驗. Ajax的核心就是XMLHttpRequest(XHR)對象.XHR為向伺服器發送請求和解析伺服器響應提供了流暢的 ...
  • 簡介:講解webpack如何實現模塊編程,以及為什麼我們需要打包,壓縮js文件,實現sass/less編譯以及JSX等模版的轉換(版本控制),然後用實例說明如何用webpack實現SPA和MPA(單頁面應用程式和多頁面應用程式,包含詳細圖解)(在以後的文章中還將介紹如何實現js壓縮和sass/les... ...
  • 最近項目上有一個需求是:根據一張圖片的拍攝時間獲取到這個時間前二後三的一個五秒鐘的視頻信息,通過查找相關資料寫了一個方法拿來記錄分享一下。 //指定時間減2秒function reduceTwoS(dateStr){//dateStr格式為yyyy-mm-dd hh:mm:ss var dt=new ...
  • 問題 註冊安卓硬體返回按鈕事件是必須的,因為用戶不小心點擊了返回按鈕就退出app體驗很不好,所以有幾種方法: 1.實現按返回鍵最小化應用(最小化應用需要裝 插件,使用 )。 2.要麼請求用戶確認(添加一個Confirmation Alerts)。 3.按一下提示,按兩下退出(加一個方法用toast提 ...
  • npm使用方法和命令 "官網" , "文檔" 顯示配置信息 更詳細 顯示幫助信息,建議多查看 display full usage info ; l is long 顯示某個命令的幫助信息 修改npm全局安裝目錄 修改npm cache目錄 把新的npm路徑修改到系統環境變數中,才可生效 設置npm ...
  • 前面的話 使用git commit -am是不是就可以完全不使用git add命令呢?不是 理論 要瞭解git commit -m與git commit -am的區別,首先要明白它們的定義 字面解釋的話,git commit -m用於提交暫存區的文件,git commit -am用於提交跟蹤過的文件 ...
  • 這兩天清明放假,剛剛琢磨把JAVA8、TOMCAT、ECLIPS裝好,幸好現在網路發達,遇到問題可以問度娘,好不容易配置好,寫了一個小程式,一運行還說Tomcat埠被占用,試了改寫tomcat安裝目錄conf下的server.xml中的埠,沒有成功,原因不詳。最後用了下麵的方法好使。 啟動Tom ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...