這段時間折騰了乙個vue的日期選擇的元件,為了達成我一貫的使用舒服優先原則,我決定使用directive
來實現,但是通過這個實現有乙個難點就是我如何把時間選擇的元件插入到dom中,所以問題來了,我是不是又要看vue的原始碼?
vue2.0即將到來,改了一大堆,fragment沒了,所以vue社群中為數不多的元件又有一批不能在2.0中使用,vue的官方外掛程式也是毀得只剩vuex相容,所以在我正在折騰我的元件的時候看到這個訊息我是崩潰的。。。但沒辦法,還是得繼續。希望2.0出來之後官方能完善一下文件,1.0中太多東西根本沒在文件裡提到,比如fragment,比如vue的util方法,這給第三方元件以及外掛程式開發者帶來了無數的瑪法,你只能去看原始碼了,費時費力,剛研究透又來個大更新,我真的想哭/(ㄒoㄒ)/~~
----------回歸正題--------
vue的核心就是他的vue class,component到最終其實也就是乙個vue的例項,包含了一些component獨有的屬性而已,我們來看看這個class做了什麼:
function vue (options)
恩,他呼叫了_init
,而在_init
裡面就是初始化了一大堆屬性,這些不重要,最重要的是最下面他有這麼一句**:
if (options.el)
這個el是我們在呼叫new vue()
時傳入的,即這個vue物件的掛載點,好了,我們找到辦法去動態得把乙個vue的例項掛載到dom裡面了,於是就有了如下**:
const vm = new vue(
})vm.$mount(document.body)
愉快得開啟頁面,等等,為什麼整個頁面上就剩下我是天才這句非常正確的話呢?哦~原來$mount
預設是替換整個整個元素的,呵呵噠
那麼我們要如何把節點插入到body裡面呢?這裡有很多辦法,比如你直接呼叫$mount()
不傳任何引數,這個時候他不會執行插入操作,然後你把他編譯過的節點(也就是vm.$el
)拿出來手動通過dom操作來進行插入,當然我們肯定不能用這麼low的方法o(∩_∩)o~,繼續擼原始碼,很快我們找到了這麼乙個檔案:
// instance/api/dom.js
vue.prototype.$before = function(target, cb, withtransition)
是的,vue的例項自帶一些dom操作的幫助,那麼我們隨便選乙個用就是了,不細說
使用這種方式動態插入的節點會有乙個問題,那就是$el
並不是我們真正想要的節點,而是乙個注釋節點,這是為啥?還是看原始碼,我們跟著$mount
進去看看他做了什麼:
vue.prototype.$mount = function (el)
el = query(el)
if (!el)
this._compile(el)
this._initdomhooks()
if (indoc(this.$el)) else
return this
}
顯然我們的el是沒有的,那麼這裡的el就變成了乙個div
,然後進行了_compile
,再繼續:
// 原始碼太長不貼了
// 檔案位置:instance/internal/lifecycle.js
這裡面他做了乙個el = transclude(el, options)
,以及this._initelement(el)
,我們重點看一下this._initelement(el)
:
vue.prototype._initelement = function (el)
this._fragment = el
} else
this.$el.__vue__ = this
this._callhook('beforecompile')
}
我們發現這裡的el以及不是之前我們可親的div
了,那麼他是什麼呢?我們倒回去看transclude
:
...
if (options)
if (options.template)
}...
我們是有template的,所以執行了transcludetemplate
:
function transcludetemplate (el, options)
// there are many cases where the instance must
// become a fragment instance: basically anything that
// can create more than 1 root nodes.
if (
// multi-children template
frag.childnodes.length > 1 ||
// non-element template
replacer.nodetype !== 1 ||
// single nested component
tag === 'component' ||
resolveasset(options, 'components', tag) ||
hasbindattr(replacer, 'is') ||
// element directive
resolveasset(options, 'elementdirectives', tag) ||
// for block
replacer.hasattribute('v-for') ||
// if block
replacer.hasattribute('v-if')
) else
} else
} else
}
這邊生成了乙個fragment
,好吧,我們最終還是回到了這裡。。。因為這邊返回的是乙個fragment
,所以會執行如下**:
if (el instanceof documentfragment)
然後回到剛才的_initelement
裡面,this.$el = this._fragmentstart = el.firstchild
,額,好吧。。。我表示無力吐槽
那麼回到我們剛才的問題,想要讓$el
正確,只需要在new vue()
的時候傳入replace: false
就行了,但是外面就多包了一層div
,怎麼樣都不覺得完美
到這裡我們基本了解了初始化乙個vue物件時的一些方法的執行順序,以及乙個元件如何從字串模板最終到乙個節點的過程,講得比較粗糙,建議有興趣的各位還是自行去看源**吧~
TinyG 韌體原始碼分析之二
2.2 主要後台子任務任務之間的關聯 controller hsm函式中包含多個後台子任務函式,其中 command dispatch實現從串列埠接收各種文字格式指令,配置引數,解析g碼指令產生運動控制指令並寫入mb mpbufferpool t型別 的快取,mp plan hold callbac...
Vue原始碼分析
在開始原始碼分析工作之前,我們在當前篇章做好相應的準備工作,以便更好地展開分析。將原始碼fork到自己的github倉庫中 git clone 自己的github vue 位址 dist 打包之後的結果 examples 示例 src compiler 編譯相關 core vue 核心庫 compo...
STL原始碼分析之二 迭代器
stl原始碼分析之二 迭代器 1.traits程式設計技巧 traits程式設計技法大量運用在 stl實現品中,它利用 內嵌型別 的程式設計技巧與編譯器的 template 引數推導功能,增強 c 未能提供的關於型別認證方面的能力,彌補 c 不為強型別語言的遺憾,例 template struct ...