摘要:模版如下我是選項模板為我是選項模板對應我是選項模板為對應的為下把等方法掛載到原型上這樣就是執行就是執行就是執行在下標簽關于這個節點的值,包括等子節點實例對象創建對象關于這個節點的值,包括等子節點文本內容真實的節點創建這個的上下文下面分別
模版如下
我是選項模板3
{{number}}
{{message}}
111122345
options.render為
function anonymous( ) { with(this){ return _c( "div", [_c("h1",{staticStyle:{"color":"red"}},[_v("我是選項模板3")]) ,_v(" "),_c("p",[_v(_s(number))]), _v(" "), _c("p",[_v(_s(message))]), _v(" "), _m(0)] ) } }
對應
我是選項模板3
{{number}}
{{message}}
options.staticRenderFns為 [0]
function anonymous() { with(this){ return _c("div",[ _c("div",[_v(" 1 "), _c("div",[_v("11")]),_v(" "), _c("div",[_v("12")]) ]),_v(" "), _c("div",[_v("2")]),_v(" "), _c("div",[_v("3")]),_v(" "), _c("div",[_v("4")]),_v(" "), _c("div",[_v("5")]) ]) } }
對應的template為
111122345
render-helpers 下 index.js
export function installRenderHelpers (target) { target._o = markOnce target._n = toNumber target._s = toString target._l = renderList target._t = renderSlot target._q = looseEqual target._i = looseIndexOf target._m = renderStatic target._f = resolveFilter target._k = checkKeyCodes target._b = bindObjectProps target._v = createTextVNode target._e = createEmptyVNode target._u = resolveScopedSlots target._g = bindObjectListeners }
render.js
function renderMixin (Vue) { //把_v,_m等方法掛載到vue原型上 installRenderHelpers(Vue.prototype) } function initRender (vm) { vm._c = (a, b, c, d) => createElement(vm, a, b, c, d, false) }
這樣this._c就是執行createElement
this._m就是執行renderStatic
_v就是執行createTextVNode
在vdom下create-element.js
tag // 標簽 data // 關于這個節點的data值,包括attrs,style,hook等 children // 子vdom節點 context // vue實例對象 function _createElement(context,tag,data,children,normalizationType) { vnode = new VNode( tag, data, children, undefined, undefined, context ) return vnode }
創建vdom對象
vnode
class VNode { constructor ( tag, data, // 關于這個節點的data值,包括attrs,style,hook等 children, // 子vdom節點 text, // 文本內容 elm, // 真實的dom節點 context, // 創建這個vdom的上下文 componentOptions, asyncFactory ) { this.tag = tag this.data = data this.children = children this.text = text this.elm = elm this.ns = undefined this.context = context this.fnContext = undefined this.fnOptions = undefined this.fnScopeId = undefined this.key = data && data.key this.componentOptions = componentOptions this.componentInstance = undefined this.parent = undefined this.raw = false this.isStatic = false this.isRootInsert = true this.isComment = false this.isCloned = false this.isOnce = false this.asyncFactory = asyncFactory this.asyncMeta = undefined this.isAsyncPlaceholder = false } }
下面dom分別依次執行,先渲染里面然后再渲染外層
1. [_c("h1",{staticStyle:{"color":"red"}},[_v("我是選項模板3")])我是選項模板3
2._c("p",[_v(_s(number))]{{number}}
3._c("p",[_v(_s(message))]){{message}}
4._m(0)是緩存渲染數 function anonymous() { with(this){ return _c("div",[ _c("div",[_v(" 1 "), _c("div",[_v("11")]),_v(" "), _c("div",[_v("12")]) ]),_v(" "), _c("div",[_v("2")]),_v(" "), _c("div",[_v("3")]),_v(" "), _c("div",[_v("4")]),_v(" "), _c("div",[_v("5")]) ]) } } vdom順序依次為 (1)11(2)12(3)1(4)11122(5)3(6)4(7)5(8)(9)111122345我是選項模板3
{{number}}
{{message}}
111122345
最后一次執行最外面的
render-static.js給m[0]靜態樹做了緩存處理
renderStatic ( index, isInFor ) { //緩存處理 const cached = this._staticTrees || (this._staticTrees = []) // staticRenderFns被執行 tree = cached[index] = this.$options.staticRenderFns[index].call( this._renderProxy, // 代理可以理解為vue實例對象,多了一些提示處理 null, this // for render fns generated for functional component templates ) markStatic(tree, `__static__${index}`, false) return tree } function markStatic ( tree, key, isOnce ) { function markStaticNode (node, key, isOnce) { node.isStatic = true //靜態樹為true node.key = key // `__static__${index}` 標志 node.isOnce = isOnce // 是否是v-once } markStaticNode(node, key, isOnce) }
然后又重新執行
function anonymous( ) { with(this){return _c("div",[_c("div",[_v(" 1 "),_c("div",[_v("11")]),_v(" "),_c("div",[_v("12")])]),_v(" "),_c("div",[_v("2")]),_v(" "),_c("div",[_v("3")]),_v(" "),_c("div",[_v("4")]),_v(" "),_c("div",[_v("5")])])} }
打印render()結果
靜態樹有了isStatic和key值
補充個小問題 render函數里number 還是變量是什么時候變成數字的
因為function有個with(this){}改變了作用域,當this.render()執行時候,那么this就是指得vue, $options.data 已經通過defineProperty代理到了vue下,訪問this.data就是訪問$options.data 所以number就是數字啦
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/97393.html
摘要:今年的月日,的版本正式發布了,其中核心代碼都進行了重寫,于是就專門花時間,對的源碼進行了學習。本篇文章就是源碼學習的總結。實現了并且將靜態子樹進行了提取,減少界面重繪時的對比。的最新源碼可以去獲得。 Vue2.0介紹 從去年9月份了解到Vue后,就被他簡潔的API所吸引。1.0版本正式發布后,就在業務中開始使用,將原先jQuery的功能逐步的進行遷移。 今年的10月1日,Vue的2...
摘要:圖在中應用三數據渲染過程數據綁定實現邏輯本節正式分析從到數據渲染到頁面的過程,在中定義了一個的構造函數。一、概述 vue已是目前國內前端web端三分天下之一,也是工作中主要技術棧之一。在日常使用中知其然也好奇著所以然,因此嘗試閱讀vue源碼并進行總結。本文旨在梳理初始化頁面時data中的數據是如何渲染到頁面上的。本文將帶著這個疑問一點點追究vue的思路。總體來說vue模版渲染大致流程如圖1所...
摘要:首先在里調用函數把獲取相應傳遞過去里在原型上定義方法對瀏覽器的怪癖做兼容布爾值。對瀏覽器的怪癖做兼容布爾值。 首先在init.js里調用$mount函數把el #app獲取相應dom傳遞過去 Vue.prototype._init = function (options) { ... if (vm.$options.el) { vm.$mount(vm.$opt...
摘要:接下來我們分析下是如何調用的,這就涉及到了經典的機制此處先簡單介紹,下一篇會有較詳細的分析。 Vue demo 先給出vue簡單的使用demo,通過創建一個Vue的實例,將被替換成template模版中的內容,a,b的值也會被換成data屬性的值 var vm = new Vue({ el: #app, template: ` {{a}} {{b}} ...
摘要:下面用具體代碼進行分析。匹配不到那么就是開始標簽,調用函數解析。如這里的轉化為加上是為了的下一步轉為函數,本文中暫時不會用到。再把轉化后的內容進。 什么是AST 在Vue的mount過程中,template會被編譯成AST語法樹,AST是指抽象語法樹(abstract syntax tree或者縮寫為AST),或者語法樹(syntax tree),是源代碼的抽象語法結構的樹狀表現形式。...
閱讀 3529·2021-11-18 10:02
閱讀 3103·2019-08-29 18:34
閱讀 3389·2019-08-29 17:00
閱讀 420·2019-08-29 12:35
閱讀 748·2019-08-28 18:22
閱讀 1910·2019-08-26 13:58
閱讀 1660·2019-08-26 10:39
閱讀 2668·2019-08-26 10:11