1. 程式人生 > >【Vue原理】Render

【Vue原理】Render

寫文章不容易,點個讚唄兄弟

專注 Vue 原始碼分享,文章分為白話版和 原始碼版,白話版助於理解工作原理,原始碼版助於瞭解內部詳情,讓我們一起學習吧

研究基於 Vue版本 【2.5.17】

如果你覺得排版難看,請點選 下面連結 或者 拉到 下面關注公眾號也可以吧

【Vue原理】Render - 原始碼版 之 靜態 Render

上一篇我們講了 render 函式,而 Vue 為了更新時速度快一些,加入了一個 staticRender

沒錯,就是 靜態 render,看過前面文章的人,應該知道什麼是 靜態 render

靜態 render 就是用於渲染哪些不會變化的節點

大家可以先看看,Vue 是怎麼判斷某個節點是否是靜態節點

Compile 之 optimize 標記靜態節點

好,下面開始我們的正文,想了想,我們還是以幾個問題開始吧

1、靜態 render 是什麼樣子的

2、靜態 render 是怎麼生成和 儲存

3、靜態 render 怎麼執行


什麼是 靜態Render

靜態 render 其實跟 render 是一樣的,都是執行得到 Vnode

只是靜態 render,沒有繫結動態資料而已,也就是說不會變化

比如說,一個簡單 render 是這樣的

公眾號

綁定了動態資料,需要從例項去獲取

_c('div',[_v(_s(aa))])

而靜態 render 是這樣的

公眾號

沒有動態資料,這個靜態render 的執行結果是永遠不會變的

_c('div',[_c('span',[_v("1")])])

生成儲存靜態Render

靜態 render 是在 generate 階段生成的,生成的方式和 render 是一樣的

比如在一個模板中,有很多個靜態 根節點,像這樣

公眾號

首先,Vue 會在遍歷模板的時候,發現 span 和 strong 本身以及其子節點都是靜態的

那麼就會給 span 和 strong 節點本身設定一個屬性 staticRoot,表示他們是靜態根節點

然後這兩個靜態根節點就會生成自己專屬的 靜態 render

如何標記靜態根節點的具體可以看 Compile 之 optimize 標記靜態節點

怎麼把靜態根節點生成 render 的可以看 Compile 之 generate 節點拼接 中 genStatic 的部分

如果你有一直看我的Vue 筆記的話,你應該這裡是會有點印象的

之後

靜態 render 生成之後是需要儲存的,那麼儲存在哪裡呢?

儲存在一個數組中,名叫 staticRenderFns,就是直接push 進去

當然了,此時的 push 進去的 靜態 render 還是字串,並沒有變成函式

以上面的模板為例,這裡的 staticRenderFns 就是這樣,包含了兩個字串

staticRenderFns  = [
    "_c('span',[_c('b',[_v("1")])])",    

    "_c('strong',[_c('b',[_v("1")])])"

]

但是在後面會逐個遍歷變成可執行的函式

staticRenderFns = staticRenderFns.map(code => {    

    return new Function(code)

});

那麼 這個 staticRenderFns 又是什麼啊?

每個 Vue 例項都有一個獨立的 staticRenderFns,用來儲存例項本身的靜態 render

staticRenderFns 的位置是

vm.$options.staticRenderFns

公眾號


執行靜態Render

靜態 render 需要配合 render 使用,怎麼說

看個例子

公眾號

這個模板的 render 函式是

_c('div',[ 
    _m(0), 
    _v(_s(a), 
    _m(1) 
])

_m(0) , _m(1) 就是執行的就是 靜態 render 函式,然後返回 Vnode

於是 render 也可以完成 vnode 樹的構建了

那麼 _m 是什麼呢?

在 Vue 初始化時,給Vue的原型便註冊了這個函式,也就是說每個例項都繼承到 _m

function installRenderHelpers(target) {
    target._m = renderStatic;
}



installRenderHelpers(Vue.prototype);

再來看 renderStatic

function renderStatic(index) {    



    var cached = this._staticTrees || (this._staticTrees = []);    

    var tree = cached[index];  

     

    // 如果快取存在,就直接返回
    if (tree) return tree    



    // 這裡是執行 render 的地方

    tree = cached[index] =

        this.$options.staticRenderFns[index].call(

            this, null, this 

        );

   

    // 只是標記靜態 和 節點id 而已
    markStatic(tree, "__static__" + index, false);    



    return tree

}

這個函式做的事情可以分為幾件

1、執行靜態render

2、快取靜態render 結果

3、標記 靜態 render 執行得到的 Vnode

我們來一個個說

1 執行靜態render

上面我們說過了,靜態render 儲存在 陣列 staticRenderFns

所以這個函式接收一個索引值,表示要執行陣列內哪個靜態render

取出靜態render 後,執行並繫結 Vue 例項為上下文物件

然後得到 Vnode

2 快取靜態render 結果

這一步就是要把上一步得到的 Vnode 快取起來

那麼快取在哪裡呢?

_staticTrees

這是一個數組,每個例項都會有一個獨立的 _staticTrees,用來存在自身的靜態 render 執行得到的 Vnode

看一下上個模板中例項儲存的 _staticTrees

公眾號

3 標記 靜態 render 執行得到的 Vnode

我們已經執行靜態render得到了 Vnode,這一步目的是標記

標記什麼呢

1、新增標誌位 isStatic

2、新增 Vnode 唯一id

renderStatic 中我們看到標記的時候,呼叫了 markStatic 方法,現在就來看看

function markStatic(
    tree, key

) {    



    if (Array.isArray(tree)) {        



        for (var i = 0; i < tree.length; i++) {            



            if ( tree[i] && typeof tree[i] !== 'string') {                



                var node  = tree[i]


                node.isStatic = true;
                node.key = key + "_" + i;
            }
        }
    }
    else {

        tree.isStatic = true;
        tree.key = key
    }
}

為什麼新增標誌位 isStatic?

前面我們新增的所有靜態標誌位都是針對 模板生成的 ast

這裡我們是給 Vnode 新增 isStatic,這才能完成Vue的目的

Vue 目的就是效能優化,在頁面改變時,能儘量少的更新節點

於是在頁面變化時,當 Vue 檢測到該 Vnode.isStatic = true,便不會比較這部分內容

從而減少比對時間

Vnode 唯一id

每個靜態根Vnode 都會存在的一個屬性

公眾號

我也沒想到 靜態Vnode 的 key 有什麼作用,畢竟不需要比較,也許是易於區分??

最後

靜態 render 我們就講完了,是不是很簡單,在沒看原始碼之前,我以為很難

現在看完,發現也簡單的,不過我也是看了幾個月的。。。。

鑑於本人能力有限,難免會有疏漏錯誤的地方,請大家多多包涵,如果有任何描述不當的地方,歡迎後臺聯絡本人,有重謝

相關推薦

Vue原理Render

寫文章不容易,點個讚唄兄弟 專注 Vue 原始碼分享,文章分為白話版和 原始碼版,白話版助於理解工作原理,原始碼版助於瞭解內部詳

Vue原理Watch

如果你覺得排版難看,請點選 下面連結 或者 拉到 下面關注公眾號也可以吧 【Vue原理】Watch - 原始碼版 今天繼續探索 Watch 原始碼,廢話不多說了 帶著我的幾個疑問開始 1、什麼時候初始化 2、怎麼確定監聽哪些值 3、深度監聽怎麼回事 4、怎麼觸發我的函式 這些問題的答案會摻

Vue原理Props

如果你覺得排版難看,請點選 下面連結 或者 拉到 下面關注公眾號也可以吧 【Vue原理】Props - 原始碼版 今天記錄 Props 原始碼流程,哎,這東西,就算是研究過了,也真是會隨著時間慢慢忘記的。 幸好我做了詳細的文章,忘記了什麼的,回憶起來必然是很快的。 好的,回到正題,Props 請你

Vue原理Mixins

如果你覺得排版難看,請點選 下面連結 或者 拉到 下面關注公眾號也可以吧 【Vue原理】Mixins - 原始碼版 今天探索的是 mixins 的原始碼,mixins 根據不同的選項型別會做不同的處理 篇幅會有些長,你知道的,有很多種選項型別的嘛,但不是很難。只是涉及原始碼難免會有些煩, 不過這篇文

Vue原理依賴更新

如果你覺得排版難看,請點選 下面連結 或者 拉到 下面關注公眾號也可以吧 【Vue原理】依賴更新 - 原始碼版 如果對依賴收集完全沒有概念的同學,可以先看我這篇白話版 響應式原理 - 白話版 我們已經講過了 依賴收集 【Vue原理】依賴收集 - 原始碼版之基本資料型別 【Vue

Vue原理VNode

如果你覺得排版難看,請點選 下面連結 或者 拉到 下面關注公眾號也可以吧 【Vue原理】VNode - 原始碼版 今天就來探索 VNode 的原始碼,VNode 是 Vue2 渲染機制中很重要的一部分,是深入Vue 必須瞭解的部分 我們以4個問題來開始我們的探索 1、vnode 是什麼及其作用

Vue原理Event

如果你覺得排版難看,請點選 下面連結 或者 拉到 下面關注公眾號也可以吧 【Vue原理】Event - 原始碼版 之 自定義事件 Vue 的自定義事件很簡單,就是使用 觀察者模式 進行事件的監聽和分發 Vue 封裝的這個觀察者模式,可以說是很完善了,這個可以獨立抽取出來的在其他專案中使用的程式碼,

Vue原理NextTick

寫文章不容易,點個讚唄兄弟 專注 Vue 原始碼分享,文章分為白話版和 原始碼版,白話版助於理解工作原理,原始碼版助於瞭解內部詳

Vue原理Diff

寫文章不容易,點個讚唄兄弟 <br> <br> 專注 Vue 原始碼分享,文章分為白話版和 原始碼版,

vue.js入門

emp 寫到 logs 組件 images href one mooc 渲染 慕課網視頻學習筆記:http://www.imooc.com/learn/694 1.將html、js、css寫到一個後綴名.vue的文件中,區分這三種類型是通過<template>、

底層原理四位計算機的原理及其實現

一點 led燈 waiting lean div rm2 src and nvt 你是否想過,計算機為什麽會加減乘除?或者更直接一點,計算機的原理到底是什麽? Waitingforfriday有一篇詳細的教程,講解了如何自己動手,制作一臺四位計算機。從中可以看到,二進制、數

計算機原理程序執行過程

進程 cnblogs div 空間 時間片 chat 內存管理 tro alt 本章主要介紹程序執行過程中操作系統、CPU都幹了什麽 運行前 程序在運行前,只是在硬盤上待著,此時就是一堆二進制代碼而已,沒有任何作用。 程序只有進入了內存才能運行,但是要進入內存,則需要服從操

計算機原理CPU部分.md

工作 信號 通過 臃腫 流水線 處理 2.6 操作 ade 本文由CPU阿甘改編而得,主要講的是系統啟動和程序執行時CPU做的工作。 CPU的構成 中央處理器(CPU,Central Processing Unit)由運算器、控制器、Cache等。 控制器:主要是對指令進

Django 第二篇render、redirect和方向生產URL

規則 app nbsp 場景 http 設計 配置 建立 get 一、知識點回顧 1、MTV模型   model:模型,和數據庫相關的   template:模板,存放html文件,模板語法(目的是將變量如何巧妙的嵌入到HTML頁面中)。   views:視圖函數 另加u

組成原理第一章 計算機系統概述

表示 運算 傳遞 intro 指令 掌握 周期 style 主存 重點掌握:MAR和MDR的含義,主存容量大小、CPU執行時間的計算,性能指標CPI、MIPS、主頻等等。 1. 存儲單元:CPU訪問存儲器的基本單位,每個單元有一個地址。通常是字節大小的整數倍。 2. CPU

編譯原理c++實現自下而上語法分析器

不可 acm times style size PC -i 表達式 鏈接 寫在前面:本博客為本人原創,嚴禁任何形式的轉載!本博客只允許放在博客園(.cnblogs.com),如果您在其他網站看到這篇博文,請通過下面這個唯一的合法鏈接轉到原文! 本博客全網唯一合法URL:ht

計數原理UVA11538 Chess Queen

put typename return col nbsp 題意 putchar cst putc 傳送門 Description   給你一個n*m的棋盤,在棋盤上放置一黑一白兩個皇後,求兩個皇後能夠互相攻擊的方案個數 Input   多組數據,每組數據包括:

MongoDB 復制集 第 二 部 之選舉原理

command primary red and 優先權 mongo mongodb 主機 set 目錄: 1·復制與選舉的原理與驗證2·oplog 日誌調整3·配置復制集的優先級4·部署認證的復制5·總結 復制與選舉的原理: 上一篇文章搭建了多臺實例,部署成復制集,

Memcached 主主復制 + Keepalived 高可用架構附上原理

ima pki nag ali event 主服務器 figure tel outer 目錄: 1·Memcached 主主復制概念2·Memcached 高可用的實現3·案例部署4·總結 Memcached 主主復制概念 (1)主主復制概念: Memcached

Windows原理非同步IO-_APC(非同步過程呼叫)

// 同步IO的缺點是, 在讀寫檔案時, 如果檔案太大, 或者讀寫的時間太長, 就會在讀寫函式中 // 阻塞住. // 非同步IO解決了這個問題, 非同步IO讀寫檔案時, 檔案再大也不會阻塞住 // 但是非同步IO要完成這樣的特性是有一點付出的 // 非同步讀寫檔案後, 需要通過一些方式