【Vue原理】Filters - 源碼版

寫文章不容易,點個讚唄兄弟 專一 Vue 源碼分享,文章分爲白話版和 源碼版,白話版助於理解工做原理,源碼版助於瞭解內部詳情,讓咱們一塊兒學習吧 研究基於 Vue版本 【2.5.17】ide

若是你以爲排版難看,請點擊 下面連接 或者 拉到 下面關注公衆號也能夠吧函數

【Vue原理】Filters - 源碼版學習

嗨,又到週末啦,又能夠睡懶覺了,冬天睡懶覺真蘇胡,可是我明天要無名加班this

image

好吧,今天咱們 解讀 filter 的工做原理(話題轉得真是生硬),filter 其實實現也是很是簡單的,因此這裏直接出源碼版了 十分鐘就能大概瞭解這個 filter 了吧 好吧,今天的研究,咱們仍然要帶着問題去學習prototype

一、頁面的 filter 解析成什麼 二、設置的 filter 如何被調用code

<br> <br>blog


場景設置

下面的講解會如下面例子 做爲講解模板token

這裏有一個過濾器 all,用來過濾 parentName作用域

<div>{{parentName|all }}</div>
new Vue({    
    el:document.getElementsByTagName("div")[0],
    data(){        
        return {            
            parentName:111
        }
    },    
    filters:{
        all(){  return "我是過濾器" }
    }
})

<br> <br>get


頁面的 filter 解析成什麼

首先,上面的例子會被解析成下面的渲染函數

(function() {      
    with(this) {            
        return _c('div',[                
            _v(_s(_f("all")(parentName)))            
        ])      
    }
}

這段代碼繼續解釋下

一、_c 是渲染組件的函數,這裏會渲染出根組件

二、這是匿名自執行函數,後面渲染的時候調用,會 綁定當前實例爲做用域

三、with 的做用是,綁定大括號內代碼的 變量訪問做用域,因此裏面的全部變量都會從 實例上獲取

而後,你能夠看到 ' parentName | all ' 被解析成 _f('all')( parentName )

怎麼解析的?

簡單說就是,當匹配到 | 這個符號,就知道你用過濾器,而後就解析成 _f 去獲取對應過濾器 並調用,這個過程不贅述

_f 是什麼?

_f 是獲取具體過濾器的函數

一、_f 會在Vue 初始化的時候,註冊到 Vue 的原型上

// 已簡化
function installRenderHelpers(target) {
      target._s = toString;
      target._f = resolveFilter;
}
installRenderHelpers(Vue.prototype);

所在在 上面的 渲染函數 with 綁定當前實例vm爲做用域 以後,_f 從vm 獲取,成了這樣 vm._f

二、_f 是 resolveFilter,一個能夠獲取 具體filter 的函數

使用 _f("all") 就能獲取到 all 這個過濾器,resolveFilter 下面會說

怎麼獲取下面繼續.......

image

設置的 filter 如何被調用

由上面能夠看到,_f 是 resolveFilter 賦值的,下面是 resolveFilter 源碼

// 已簡化

function resolveFilter(id) {    
    return resolveAsset(
        this.$options, 'filters', id, true
    ) || identity
}

this.options 會拿到當前組件的全部選項

你問我爲何?

根據上一個問題知道

一、_f 會使用 實例去調用 ,vm._f 類等 vm.resolveFilter

二、因此,resolveFilter 的 執行上下文 this 是 vm

三、因此,this.$options 就是 實例的 options 啦

接着,調用 resolveAsset ,目的就是拿到 組件選項中的 具體 filter

傳入 當前組件的選項 ,指定要其選項 filters ,指定具體 filter 名

function resolveAsset( 
    options, type, id, warnMissing
) {      

    // g:拿到  filters 選項
    var assets = options[type];      

    // g:返回 調用的 filter
    return assets[id]
}

_f("all") 流程 就成了下面這樣

image

一、拿到 組件選項 中的 filters

二、而後再從 filters 中,拿到 all 這個filter

三、執行返回的 all 過濾函數時,傳入須要過濾的值 parentName

四、獲得 返回了 過濾後的值

image

因此,當渲染函數解析的時候,碰到使用過濾器的地方,按流程拿到過濾值後,就能夠渲染到頁面上了

_f("all")(parentName)) 就會變成 "我是過濾器" 放到 渲染函數中,最後,就是渲染到頁面了

image

<br> <br>


總結

fitler 其實就是從組件選項 filters 獲取你設置的某個filter,並調用,而後使用你函數執行的返回值渲染 太簡單了,總結跟沒總結同樣.......

image

相關文章
相關標籤/搜索