成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

【教學(xué)向】150行代碼教你實(shí)現(xiàn)一個(gè)低配版的MVVM庫(kù)(1)- 原理篇

selfimpr / 581人閱讀

摘要:模塊則負(fù)責(zé)維護(hù),以及各個(gè)模塊間的調(diào)度思考題了解了的實(shí)現(xiàn)機(jī)制,你能否自己動(dòng)手也試著用百來(lái)行代碼實(shí)現(xiàn)一個(gè)庫(kù)呢好了本教程第一部分設(shè)計(jì)篇就寫到這里,具體請(qǐng)移步下一篇教學(xué)向行代碼教你實(shí)現(xiàn)一個(gè)低配版的庫(kù)代碼篇我會(huì)用給出一版實(shí)現(xiàn)。

適讀人群

本文適合對(duì)MVVM有一定了解(如有主流框架ng,vue等使用經(jīng)驗(yàn)配合本文服用則效果更佳),雖然會(huì)用這類框架,但是對(duì)框架底層核心實(shí)現(xiàn)又不太清楚,或者能說(shuō)出個(gè)所以然,但是讓他自己動(dòng)手寫又沒(méi)有頭緒的碼友。如果還沒(méi)聽(tīng)說(shuō)過(guò)MVVM,不妨先收藏著。。。

名詞定義

先給低配版的庫(kù)起一個(gè)響亮的名字,以便于開(kāi)展教學(xué),入鄉(xiāng)隨俗我們就叫ta -- SegmentFault.js 吧 (以下簡(jiǎn)稱sf.js

設(shè)置在DOM Element上的自定義屬性前綴統(tǒng)一以 sf- 開(kāi)頭 (如

為什么是低配版?
1. 沒(méi)有sf-repeat
2. 不支持select,checkbox,radio等控件的雙向綁定
3. 沒(méi)有sf-if
4. 很多都沒(méi)有

由于是教學(xué)向,力圖用最簡(jiǎn)短易讀的代碼來(lái)實(shí)現(xiàn)MVVM最主要最基本的功能,故砍掉了部分實(shí)現(xiàn)。

先看演示圖,圖中就是使用sf.js寫得DEMO

100多行的低配版不能要求太多,如果看不上低配版的庫(kù),請(qǐng)關(guān)閉本教程。

老生常談 什么是雙向綁定

首先明白一個(gè)概念,什么是雙向綁定?在說(shuō)雙向綁定之前,我們先說(shuō)說(shuō)單向顯示
單向顯示 說(shuō)白了就是view動(dòng)態(tài)地顯示變量。比如在ng或其它一些主流框架里類似這種寫法

    //scope.message= "segmentfault"; 
    

segmentfault

為什么說(shuō)是單向呢,因?yàn)槎际?viewModel上某個(gè)變量(message) -> view (h3)的一個(gè)過(guò)程,viewModel上的變量被view所呈現(xiàn)。

再來(lái)看看 逆向修改
前面說(shuō)了單向是viewMode->view的過(guò)程,那逆向就是 viewModel <- view的過(guò)程,換句話說(shuō)就是viewModel被view修改的過(guò)程。例如angular中

一旦用戶在input控件中輸入值,便會(huì)實(shí)時(shí)地改變viewModel中message這個(gè)變量的值。這是一個(gè)view -> viewModel 的過(guò)程。

所謂的雙向綁定就是一個(gè) viewMode ->(顯示) view ->(修改)viewModel 的過(guò)程。

雙向綁定 = 單向顯示 + 逆向修改
注意: 單向顯示可能發(fā)生在所有的類型DOM節(jié)點(diǎn)上,而逆向修改只可能發(fā)生在INPUT,SELECT,TEXTAREA等交互型控件上。

如果整明白什么是雙向綁定了,我們就來(lái)談?wù)勗O(shè)計(jì)思路,沒(méi)有整明白的同學(xué)請(qǐng)?jiān)匍喿x一遍.

單向顯示的設(shè)計(jì)思路(viewModel -> view)

先看看API的設(shè)計(jì)


要實(shí)現(xiàn)這個(gè)功能,我們的sf庫(kù)應(yīng)該需要哪幾步操作呢?(先自己想想,獨(dú)立思考下)

1. 注冊(cè)ViewModel,我們的庫(kù)需要知道哪些object是viewModel
2. 掃描整個(gè)DOM Tree找到有哪些DOM節(jié)點(diǎn)上被配置了sf-xxxx這個(gè)attribute
3. 紀(jì)錄這些被單向綁定的DOM節(jié)點(diǎn)和viewModel之間的映射關(guān)系
4. 使用DOM API, element.innerText = vm.prop, element.value = vm.prop, element.xxxx = vm.prop 來(lái)顯示數(shù)據(jù)
思考題1

Q:如果我們要單向綁定不是innerText,value 而是作為樣式的class,style呢?
A:沒(méi)錯(cuò),使用sf-class="vm.myClass" sf-style="vm.myStyle"就好了,其它原生屬性也以此類推
"sf-" + native attribute is good!

逆向修改的設(shè)計(jì)思路(viewModel <- view)

主流的一些mvvm框架上一般這么設(shè)計(jì)API,還是拿angular舉例子

這里我個(gè)人并不認(rèn)同這種xx-model的命名方式來(lái)作為雙向綁定的一種標(biāo)識(shí),比如angular的ng-model,或Vue的v-model,撇開(kāi)前綴不說(shuō),這個(gè)model很讓人困惑,我們知道input控件是本身就有value這個(gè)native的屬性的,這個(gè)屬性就是代表著input輸入和輸出的值,如果要給一個(gè)input進(jìn)行雙向綁定我們應(yīng)該很自然而然地使用一個(gè) *-value就可以了,完全沒(méi)有必要弄出一個(gè)新的attribute叫做*-model的,從而增加學(xué)習(xí)成本。

所以,我們就設(shè)計(jì)一個(gè)叫做sf-value的attribute來(lái)做API

拍腦袋想想,view要改變數(shù)據(jù)只可能發(fā)生在可以和用戶交互的一些html控件上,比如input家族(text, radio, checkbox), select, textarea上。 像h1~hn家族,這輩子是沒(méi)有機(jī)會(huì)的。

要實(shí)現(xiàn)view改寫viewModel,我們的庫(kù)應(yīng)該需要哪幾步操作呢?(也先自己想想,千萬(wàn)不要丟掉獨(dú)立思考能力)

1.掃描整個(gè)DOM Tree,找到哪些INPUT,SELECT,TEXTAREA節(jié)點(diǎn)上被配置了sf-value這個(gè)attribute
2.紀(jì)錄這些被雙向綁定的DOM節(jié)點(diǎn)和viewModel之間的映射關(guān)系
3.sf.js庫(kù)自動(dòng)給這個(gè)寫DOM加上onchange或者oninput的事件監(jiān)聽(tīng)
4.一旦監(jiān)聽(tīng)到change/input事件,立即獲取這個(gè)DOM的value值,把這個(gè)element.value賦給與之綁定的viewModel的變量上。
思考題2

Q:那么問(wèn)題來(lái)了,vm.message被input修改了,誰(shuí)去通知其它同樣綁定了vm.message的view呢?
A:請(qǐng)看下一段

同步機(jī)制

臟檢查大法 這三個(gè)字想必大家已經(jīng)如雷貫耳,我2年多前出去面試的時(shí)候被問(wèn)及最多的就是angular的臟檢查,什么是臟檢查?angular臟檢查的時(shí)機(jī)是什么?

臟檢查的原理就是,拷貝一份copy_viewModel在內(nèi)存中,一旦有用戶點(diǎn)擊,輸入操作,或ajax請(qǐng)求,setInterval,setTimeout等這些可能導(dǎo)致viewModel發(fā)生改變的行為,框架都會(huì)把copy_viewModel和最新的viewModel進(jìn)行深度比較,一旦發(fā)現(xiàn)有屬性(如vm.message)發(fā)生變化,則重新渲染與message綁定的DOM節(jié)點(diǎn)。

這也是為什么,一旦你沒(méi)有使用ng自帶的$http,$interval,$timeout,ng-click這些angular自己封裝的API去操作viewModel,angular都不會(huì)自動(dòng)去同步view,因?yàn)橐呀?jīng)超出他的管轄范圍了,你必須手動(dòng)調(diào)用apply函數(shù)去強(qiáng)制執(zhí)行一次臟檢查,以同步view。

setter大法
聽(tīng)說(shuō)VUE是使用的這種同步機(jī)制,其核心原理就是使用Object.defineProperty(obj, prop, descriptor)(不了解defineProperty的請(qǐng)戳)這個(gè)API,在setter中加點(diǎn)料,一旦有任何地方執(zhí)行 vm.message = "new value"語(yǔ)句,則setter都會(huì)被調(diào)用,由setter去觸發(fā)重新渲染view的邏輯。

相較這兩種同步機(jī)制,似乎setter更加輕便,性能更好。所以本文使用了setter的方式來(lái)實(shí)現(xiàn)同步機(jī)制(關(guān)鍵是實(shí)現(xiàn)setter機(jī)制使用的代碼較少)。

設(shè)計(jì)思路

給setter加點(diǎn)料

http://jsbin.com/gosigoh/edit...

總體設(shè)計(jì)圖

所以歸納來(lái)說(shuō)一個(gè)MVVM庫(kù)主要由3塊組成
MVVM庫(kù) = 單向顯示 + 逆向修改 + 同步機(jī)制
下圖為SegmentFault.js的實(shí)現(xiàn)機(jī)制
其中Renderer負(fù)責(zé)單向顯示和逆向修改,Watcher負(fù)責(zé)監(jiān)視viewModel為同步機(jī)制的核心模塊,
Scanner負(fù)責(zé)sf.js初始化時(shí)掃描DOM Tree生成view和viewModel的映射關(guān)系。
SegmentFault模塊則負(fù)責(zé)維護(hù)view-viewModel Map,以及各個(gè)模塊間的調(diào)度

思考題3

Q:了解了MVVM的實(shí)現(xiàn)機(jī)制,你能否自己動(dòng)手也試著用百來(lái)行代碼實(shí)現(xiàn)一個(gè)MVVM庫(kù)呢?

好了!本教程第一部分設(shè)計(jì)篇就寫到這里,具體coding請(qǐng)移步(下一篇 【教學(xué)向】150行代碼教你實(shí)現(xiàn)一個(gè)低配版的MVVM庫(kù)(2)- 代碼篇)
我會(huì)用Typescript給出一版實(shí)現(xiàn)。

寫在最后 這篇文章的目的

2年前寫了我受夠了angular的笨重,學(xué)習(xí)曲線陡峭等缺點(diǎn),自己一怒之下寫下一個(gè)輕量的MVVM庫(kù),給她起名叫【Ukulele.js】(跟我一起念『尤克里里.杰愛(ài)死』,當(dāng)然本文不是這個(gè)庫(kù)的安利文,請(qǐng)安心服用),一開(kāi)始寫這個(gè)庫(kù)出于好玩,后來(lái)也加入了越來(lái)越多的功能,諸如web component的支持,我漸漸發(fā)現(xiàn),其實(shí)要寫一個(gè)MVVM庫(kù)也并不是很難,難的是你有沒(méi)有決心敲下第一行代碼。后來(lái)我把她和【精通angularjs】一起寫在里簡(jiǎn)歷里,然后就去找工作了。面試的時(shí)候被問(wèn)及最多的問(wèn)題就是:"說(shuō)說(shuō)MVVM的實(shí)現(xiàn)機(jī)制"。

我今天寫下此文,1是希望有機(jī)會(huì)看到這篇文章的碼友能真正掌握MVVM的核心機(jī)制,2是鼓勵(lì)下大家能靜下心來(lái),自己動(dòng)手寫寫庫(kù),寫寫框架,有些你現(xiàn)在覺(jué)得蠻高大上的東西,你仔細(xì)一分析,動(dòng)動(dòng)腦,真的沒(méi)有那么高大上,普通的碼農(nóng)也能自己實(shí)現(xiàn)

相關(guān)閱讀

【教學(xué)向】150行代碼教你實(shí)現(xiàn)一個(gè)低配版的MVVM庫(kù)(1)- 原理篇
【教學(xué)向】150行代碼教你實(shí)現(xiàn)一個(gè)低配版的MVVM庫(kù)(2)- 代碼篇
【教學(xué)向】再加150行代碼教你實(shí)現(xiàn)一個(gè)低配版的web component庫(kù)(1) —設(shè)計(jì)篇
【教學(xué)向】再加150行代碼教你實(shí)現(xiàn)一個(gè)低配版的web component庫(kù)(2) —原理篇

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/87348.html

相關(guān)文章

  • 教學(xué)】再加150代碼教你實(shí)現(xiàn)一個(gè)低配版的web component庫(kù)1) —設(shè)計(jì)

    摘要:為的內(nèi)置一個(gè)方法,用法和原生的事件機(jī)制一毛一樣。 前言 上兩篇Mvvm教程的熱度超出我的預(yù)期,很多碼友留言表?yè)P(yáng)同時(shí)希望我繼續(xù)出下一篇教程,當(dāng)時(shí)我也半開(kāi)玩笑說(shuō)只要點(diǎn)贊超10就兌現(xiàn)承諾,沒(méi)想到還真破了10,所以就有了今天的文章。 準(zhǔn)備工作 熟讀 【教學(xué)向】150行代碼教你實(shí)現(xiàn)一個(gè)低配版的MVVM庫(kù)(1)- 原理篇【教學(xué)向】150行代碼教你實(shí)現(xiàn)一個(gè)低配版的MVVM庫(kù)(2)- 代碼篇 本篇是在...

    Clect 評(píng)論0 收藏0
  • 教學(xué)150代碼教你實(shí)現(xiàn)一個(gè)低配版的MVVM庫(kù)(2)- 代碼

    摘要:也放出地址,上面有完整工程以及在線演示地址相關(guān)閱讀教學(xué)向行代碼教你實(shí)現(xiàn)一個(gè)低配版的庫(kù)原理篇教學(xué)向行代碼教你實(shí)現(xiàn)一個(gè)低配版的庫(kù)代碼篇教學(xué)向再加行代碼教你實(shí)現(xiàn)一個(gè)低配版的庫(kù)設(shè)計(jì)篇教學(xué)向再加行代碼教你實(shí)現(xiàn)一個(gè)低配版的庫(kù)原理篇 書接上一篇: 150行代碼教你實(shí)現(xiàn)一個(gè)低配版的MVVM庫(kù)(1)- 原理篇 寫在前面 為了便于分模塊,和閱讀,我使用了Typescript來(lái)進(jìn)行coding,總行數(shù)是正好...

    loonggg 評(píng)論0 收藏0
  • 2017-08-29 前端日?qǐng)?bào)

    摘要:前端日?qǐng)?bào)精選瀏覽器兼容性問(wèn)題解決方案配置指南全新的模塊化框架,知乎專欄現(xiàn)學(xué)現(xiàn)賣中文教學(xué)向再加行代碼教你實(shí)現(xiàn)一個(gè)低配版的庫(kù)原理篇我把最美的青春都獻(xiàn)給了代碼技術(shù)周刊開(kāi)啟瀏覽器全屏模式如何進(jìn)行的操作掘金內(nèi)存分配與垃圾回收寫一 2017-08-29 前端日?qǐng)?bào) 精選 瀏覽器兼容性問(wèn)題解決方案AlloyTeam ESLint 配置指南全新的redux模塊化框架,redux-arena - 知乎專欄...

    atinosun 評(píng)論0 收藏0
  • 個(gè)人分享--web前端學(xué)習(xí)資源分享

    摘要:前言月份開(kāi)始出沒(méi)社區(qū),現(xiàn)在差不多月了,按照工作的說(shuō)法,就是差不多過(guò)了三個(gè)月的試用期,準(zhǔn)備轉(zhuǎn)正了一般來(lái)說(shuō),差不多到了轉(zhuǎn)正的時(shí)候,會(huì)進(jìn)行總結(jié)或者分享會(huì)議那么今天我就把看過(guò)的一些學(xué)習(xí)資源主要是博客,博文推薦分享給大家。 1.前言 6月份開(kāi)始出沒(méi)社區(qū),現(xiàn)在差不多9月了,按照工作的說(shuō)法,就是差不多過(guò)了三個(gè)月的試用期,準(zhǔn)備轉(zhuǎn)正了!一般來(lái)說(shuō),差不多到了轉(zhuǎn)正的時(shí)候,會(huì)進(jìn)行總結(jié)或者分享會(huì)議!那么今天我就...

    sherlock221 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<