国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

【Vue原理】Compile - 源碼版 之 從新建實例到 compile結(jié)束的主要流程

CODING / 1235人閱讀

摘要:頁面這個實例,按理就需要解析兩次,但是有緩存之后就不會理清思路也就是說,其實內(nèi)核就是不過是經(jīng)過了兩波包裝的第一波包裝在中的內(nèi)部函數(shù)中內(nèi)部函數(shù)的作用是合并公共和自定義,但是相關(guān)代碼已經(jīng)省略,另一個就是執(zhí)行第二波包裝在中,目的是進(jìn)行緩存

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


專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧
研究基于 Vue版本 【2.5.17】

如果你覺得排版難看,請點擊 下面鏈接 或者 拉到 下面關(guān)注公眾號也可以吧

【Vue原理】Compile - 源碼版 之 從新建實例到 compile結(jié)束的主要流程

Compile 的內(nèi)容十分之多,今天先來個熱身,先不研究 compile 內(nèi)部編譯細(xì)節(jié),而是記錄一下

從新建實例開始,到結(jié)束 compile ,其中的大致外部流程,不涉及 compile 的內(nèi)部流程

或者說,我們要研究 compile 這個函數(shù)是怎么生成的

注意,如果你沒有準(zhǔn)備好,請不要閱讀這篇文章

注意哦,會很繞,別暈了

好的,正文開始

首先,當(dāng)我們通過 Vue 新建一個實例的時候會調(diào)用Vue

所以從 Vue 函數(shù)入手

function Vue(){    

    // .....

    vm.$mount(vm.$options.el);
}

然后內(nèi)部的其他處理都可以忽視,直接定位到 vm.$mount,就是從這里開始去編譯的

繼續(xù)去查找這個函數(shù)

Vue.prototype.$mount = function(el) {    



    var options = this.$options;

   

    if (!options.render) {  

     

        var tpl= options.template;  

   

        // 獲取模板字符串
        if (tpl) {    

                // 根據(jù)傳入的選擇器找到元素,然后拿到該元素內(nèi)的模板

                //  本來有很多種獲取方式,但是為了簡單,我們簡化為一種,知道意思就可以了

            tpl = document.querySelector(tpl).innerHTML;
        }    

     

        if (tpl) {  

            // 生成 render 函數(shù)保存

            var ref = compileToFunctions(tpl, {},this);  

          

            // 每一個組件,都有自己的 render

            options.render = ref.render
            options.staticRenderFns =ref.staticRenderFns;
        }
    }      



    // 執(zhí)行上面生成的 render,生成DOM,掛載DOM,這里忽略不討論
    return mount.call(this, el)
};

compile 的主要作用就是,根據(jù) template 模板,生成 render 函數(shù)

那么到這里,整個流程就走完了,因為 render 已經(jīng)在這里生成了

我們觀察到

在上面這個函數(shù)中,主要就做了三件事

1 獲取 template 模板

根據(jù)你傳入的參數(shù),來各種獲取 template 模板

這里應(yīng)該都看得懂了,根據(jù)DOM,或者根據(jù)選擇器

2 生成 render

通過 compileToFunctions ,傳入 template

就可以生成 render 和 staticRenderFns

看著是挺簡單哦,就一個 compileToFunctions,但是我告訴你,這個函數(shù)的誕生可不是這么容易的,兜兜轉(zhuǎn)轉(zhuǎn),十分曲折,相當(dāng)?shù)们蹚?fù)雜,沒錯,這就是我們下面研究的重點

但是這流程其實好像也沒有什么幫助?但是如果你閱讀源碼的話,或許可以對你理清源碼有些許幫助吧

再一次佩服 尤大的腦回路

3 保存 render

保存在 vm.$options 上,用于在后面調(diào)用

下面就來說 compileToFunctions 的誕生史

注意,很繞很繞,做好心理準(zhǔn)備

首先我定位到 compileToFunctions,看到下面這段代碼

var ref$1 = createCompiler();



// compileToFunctions 會返回 render 函數(shù) 以及 staticRenderFns

var compileToFunctions = ref$1.compileToFunctions;

于是我知道

compileToFunctions 是 createCompiler 執(zhí)行返回的!!

那么繼續(xù)定位 createCompiler

createCompiler
var createCompiler = createCompilerCreator(  



    function baseCompile(template, options) {    

    

        var ast = parse(template.trim(), options);    

    

        if (options.optimize !== false) {

            optimize(ast, options);
        }    

   

        var code = generate(ast, options);  

     

        return {            

            ast: ast,            

            render: code.render,            

            staticRenderFns: code.staticRenderFns

        }
    }
);

臥槽,又來一個函數(shù),別暈啊兄弟


不過,注意注意,這里是重點,非常重

首先明確兩點

1、createCompiler 是 createCompilerCreator 生成的

2、給 createCompilerCreator 傳了一個函數(shù) baseCompile

baseCompile

這個 baseCompile 就是 生成 render 的大佬

看到里面包含了 渲染三巨頭,【parse,optimize,generate】

但是今天不是講這個的,這三個東西,每個內(nèi)容都十分巨大

這里先跳過,反正 baseCompile 很重要,會在后面被調(diào)用到,得先記著

然后,沒錯,我們又遇到了一個 函數(shù) createCompilerCreator ,定位它!

createCompilerCreator
function createCompilerCreator(baseCompile) {    



    return function () {

       

        // 作用是合并選項,并且調(diào)用 baseCompile
        function compile(template) {  

         

            // baseCompile 就是 上一步傳入的,這里執(zhí)行得到 {ast,render,statickRenderFn}

            var compiled = baseCompile(template);            

            return compiled

        }        

        return {          



            // compile 執(zhí)行會返回 baseCompile 返回的 字符串 render

            compile: compile,      

     

            // 為了創(chuàng)建一層 緩存閉包,并且閉包保存 compile

            // 得到一個函數(shù),這個函數(shù)是 把 render 字符串包在 函數(shù) 中
            compileToFunctions: createCompileToFunctionFn(compile)
        }
    }
}

這個函數(shù)執(zhí)行過后,會返回一個函數(shù)

很明顯,返回的函數(shù)就 直接賦值 給了上面講的的 createCompiler

我們看下這個返回給 createCompiler 的函數(shù)里面都干了什么?

生成一個函數(shù) compile

內(nèi)部存在一個函數(shù) compile,這個函數(shù)主要作用是

調(diào)用 baseCompile,把 baseCompile 執(zhí)行結(jié)果 return 出去

baseCompile 之前我們強(qiáng)調(diào)過的,就是那個生成 render 的大佬

忘記的,可以回頭看看,執(zhí)行完畢會返回

{ render,staticRenderFns }

返回 compileToFunctions 和 compile

其實 返回的這兩個函數(shù)的作用大致都是一樣的

都是為了執(zhí)行上面那個 內(nèi)部 compile

但是為什么分出一個 compileToFunctions 呢?

還記得開篇我們的 compileToFunctions 嗎

就是那個在 vm.$mount 里我們要探索的東西啊

就是他這個吊毛,生成的 render 和 staticRenderFns

再看看那個 內(nèi)部 compile,可以看到他執(zhí)行完就是返回

{ render, staticRenderFns }

你看,內(nèi)部 compile 就是 【vm.$mount 執(zhí)行的 compileToFunctions】 啊

為什么 compileToFunctions 沒有直接賦值為 compile 呢!!

因為要做模板緩存??!

可以看到,沒有直接讓 compileToFunctions = 內(nèi)部compile

而是把 內(nèi)部 compile 傳給了 createCompileToFunctionFn

沒錯 createCompileToFunctionFn 就是做緩存的

為了避免每個實例都被編譯很多次,所以做緩存,編譯一次之后就直接取緩存

createCompileToFunctionFn

來看看內(nèi)部的源碼,緩存的代碼已經(jīng)標(biāo)紅

function createCompileToFunctionFn(compile) {    



    // 作為緩存,防止每次都重新編譯

    // template 字符串 為 key , 值是 render 和 staticRenderFns
    var cache = Object.create(null);    



    return function compileToFunctions(template, options, vm) {        

        var key = template;        



        // 有緩存的時候直接取出緩存中的結(jié)果即可

        if (cache[key]) return cache[key]  

     

        // compile 是 createCompileCreator 傳入的compile

        var compiled = compile(template, options);        

        var res = {            



            // compiled.render 是字符串,需要轉(zhuǎn)成函數(shù)

            render : new Function(compiled.render)
            staticRenderFns : compiled.staticRenderFns.map(function(code) {                

                return  new Function(code, fnGenErrors)

            });
        };        



        return (cache[key] = res)

    }
}

額外:render 字符串變成可執(zhí)行函數(shù)

var res = {    

    render: new Function(compiled.render) ,    

    staticRenderFns: compiled.staticRenderFns.map(function(code) {        

        return new Function(code, fnGenErrors)

    });
};

這段代碼把 render 字符串可執(zhí)行函數(shù),因為render生成的形態(tài)是一個字符串,如果后期要調(diào)用運(yùn)行,比如轉(zhuǎn)成函數(shù)

所以這里使用了 new Function() 轉(zhuǎn)化成函數(shù)

同理,staticRenderFns 也一樣,只不過他是數(shù)組,需要遍歷,逐個轉(zhuǎn)化成函數(shù)

他的緩存是怎么做的

使用一個 cache 閉包變量

template 為 key

生成的 render 作為 value

當(dāng)實例第一次渲染解析,就會被存到 cache 中

當(dāng)實例第二次渲染解析,那么就會從 cache 中直接獲取

什么時候?qū)嵗龝馕龅诙危?/p>

比如 頁面A到頁面B,頁面B又轉(zhuǎn)到頁面A。

頁面A 這個實例,按理就需要解析兩次,但是有緩存之后就不會

理清思路

也就是說,compileToFunctions 其實內(nèi)核就是 baseCompile!

不過 compileToFunctions 是經(jīng)過了 兩波包裝的 baseCompile

第一波包裝在 createCompilerCreator 中的 內(nèi)部 compile 函數(shù)中

內(nèi)部函數(shù)的作用是

合并公共options和 自定義options ,但是相關(guān)代碼已經(jīng)省略,

另一個就是執(zhí)行 baseCompile

第二波包裝在 createCompileToFunctions 中,目的是進(jìn)行 緩存

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/106565.html

相關(guān)文章

  • Vue原理Compile - 源碼 Parse 標(biāo)簽解析

    摘要:當(dāng)字符串開頭是時,可以匹配匹配尾標(biāo)簽。從結(jié)尾,找到所在位置批量閉合。 寫文章不容易,點個贊唄兄弟 專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5.17】 如果你覺得排版難看,請點擊 下面鏈接 或者 拉到 下面關(guān)注公眾號也可以吧 【Vue原理】Compile - 源碼版 之 標(biāo)簽解析...

    loostudy 評論0 收藏0
  • Vue原理Compile - 源碼 Parse 主要流程

    寫文章不容易,點個贊唄兄弟 專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5.17】 如果你覺得排版難看,請點擊 下面鏈接 或者 拉到 下面關(guān)注公眾號也可以吧 【Vue原理】Compile - 源碼版 之 Parse 主要流程 本文難度較繁瑣,需要耐心觀看,如果你對 compile 源碼暫時...

    Forest10 評論0 收藏0
  • Vue原理Compile - 源碼 optimize 標(biāo)記靜態(tài)節(jié)點

    摘要:一旦我們檢測到這些子樹,我們可以把它們變成常數(shù),這樣我們就不需要了在每次重新渲染時為它們創(chuàng)建新的節(jié)點在修補(bǔ)過程中完全跳過它們。否則,吊裝費(fèi)用將會增加好處大于好處,最好總是保持新鮮。 寫文章不容易,點個贊唄兄弟 專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5.17】 如果你覺得排版難看,...

    Soarkey 評論0 收藏0
  • Vue原理Compile - 源碼 generate 節(jié)點拼接

    摘要:還原的難度就在于變成模板了,因為其他的什么等是原封不動的哈哈,可是直接照抄最后鑒于本人能力有限,難免會有疏漏錯誤的地方,請大家多多包涵,如果有任何描述不當(dāng)?shù)牡胤?,歡迎后臺聯(lián)系本人,有重謝 寫文章不容易,點個贊唄兄弟 專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5.17】 如果你覺得排版...

    macg0406 評論0 收藏0
  • Vue原理Compile - 白話

    摘要:寫文章不容易,點個贊唄兄弟專注源碼分享,文章分為白話版和源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于版本如果你覺得排版難看,請點擊下面鏈接或者拉到下面關(guān)注公眾號也可以吧原理白話版終于到了要講白話的時候了 寫文章不容易,點個贊唄兄弟 專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究...

    dingding199389 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<