初接觸vue,驚為天人,它的更新方式極為取巧,但也是人們保持路人的原因:似乎沒有一個嚴格的數學證明保證按它的方式能精確更新到DOM。不過腦子裡推演的似乎不會發生失敗,而且每次介面都能按預期更新的效果十分動人——這似乎是目前mvvm中最快最準確的更新方式。
試用過幾回,不滿的地方,vue是一個框架,必須、最好按它的方式來編碼,xml與jscss混編,使用.vue檔案。雖然後來放開可以使用template字串。以及它內聚成字典的寫法,xml語法都是我不習慣的地方,我只想用純粹的js語言來程式設計。經過一翻網路搜尋,勉強明白了依賴更新的實現方式,便嘗試著自己去實現一個框架。
沒接觸vue之前,我製作了一個叫jsdom的小模組,使用其中一個叫parseElement的函式,接受一個巢狀的字典/陣列作引數。因為js的字典/陣列宣告跟json一樣樹狀巢狀,而且更加靈活(key不必雙引號,value可以是函式),而html/xml也是樹狀的,便可以模擬html/xml,不用像模板引擎或jquery一樣拼湊xml字串,內部遞迴呼叫DOM元素的建立修改方法,也就很好地避免了注入攻擊。而且傳統的各種介面程式設計使用各種xml,訪問屬性呼叫方法又在原始碼檔案,這種分離很不方便,因此在這種巢狀的Object/Array中內建函式,至少減少了程式碼,明確了呼叫。字典中如果有id,將字典解析生成的元素節點放置進me.k這個字典裡,用來修改DOM元素,也可以實現區域性模組化(jsdom原始碼也在附的開原始碼中,可進入檢視)。而且在js這種完整的語言下,也可以對區域性片段像模板引擎一樣輕鬆重複。效能,我是沒考慮的,但至少安全是保證了的,因為已經快到超過人的感知,而且相信用純粹一種語言,肯定比幾種語言混編效能高。
//簡單示例
jsdom.parseElement({
type:"div",
attr:{
a:1,
b:2
},
style:{
color:"red",
"background-color":"green"
},
children:[
{
type:"div",
id:"a"
},
{
type:"button",
text:"點選",
action:{
click:function(e){
console.log(e);
}
}
}
]
},me);
但jsdom.parseElement使用要回寫DOM,使用DOM的API修改元素屬性,這很麻煩,這也是各家mvvm建立的原因。如果attr節點,或style節點下的value不是字串或數字,而是函式,就能動態更新這些屬性,這就是我理想中的mvvm方式。如今有vue依賴更新這種技術的存在,我覺得找到了可能。
實現mve的過程中,我發現元件的watch需要在銷燬時回收,於是不得不改變mve的呼叫方式,和jsdom.parseElement不同。具體可以參見開原始碼中的示例。
後來越來越覺得js很煩人(即使已經比各面嚮物件語言方便多了;我一直使用其函式式的部分lambda的部分而不使用其原型式的部分),逗號很多很容易寫錯,函式宣告很煩,字串必須包含在引號中難免前後空格,字典沒有預設順序。。。。為了優化js的寫法,我去研究lisp,然後有了我的另一個開源專案S-Lisp這套語法方案,越深入思考越發現這套方案的威力強大,甚至C++版實現的S-Lisp可以通過引用計數精確回收記憶體,因此順帶推薦。同時mve下有一個js實現的S-Lisp,及這個S-Lisp實現的mve,然而只是部分實現,children的repeat還未實現。歡迎大家關注,希望能夠幫助到大家,同時也希望大家如果有什麼好的改進,不要吝惜分享出來,共同進步。