MVVM是Model-View-ViewModel的簡寫。微軟的WPF帶來了新的技術體驗。本文主要和大家分享vue實作小結之mvvm學習,希望能幫助大家。
1 mvvm 學習
mvvm類別框架的實作原理不複雜,大致如下:
實際上,directive的處理邏輯不一定是對view進行操作,例如回報。但是,在mv的思想下,建議對view的操作都集中在directive裡實現
#從最核心上看,mv思想只是一個觀察者模式的具體應用於延展而已1.2 核心技術點1.2.1 模板分析模板分析是比較基礎的,凡是和view相關的基本都會涉及模板,這是原始資料,這裡的關鍵點是模板來源的問題,實際上,它應該可以是任何字串這裡暗示了框架需要一個模板解析器,不管這個解析器複雜還是簡單,它都處於一個模式:【輸入–> 模板引擎–> 輸出】於是,mvvm的模板解析器特點如下:
輸入應該足夠靈活,從來源上來說,模板可以是someDomHere.html(),也可以是動態輸入,那就更有可適用性;從內容上來說,如果引擎可以辨識更高階的語法,那就更有功能性
輸出應該足夠收斂,收斂的意思是有限且規則,像mvvm框架,最後出來的只是directive和filter,具體的處理都集中在這兩個概念中,僅擴展這兩個概念,即可對系統進行擴展
1.2.2 變動監測
#2 3 ##4#5678910##11 <span class="comment">//方式1 vs. 方式2</span> <span class="comment">//方式1:</span> vm.<span class="variable">$set</span>(aaa, <span class="number">1</span>); <span class="comment">//会触发变动逻辑</span> vm._data.aaa = <span class="number">2</span>; <span class="comment">//不会触发变动逻辑,不过这不是框架希望的操作,可以被hack</span> vm.<span class="variable">$get</span>(aaa); <span class="comment">//2</span> <span class="comment">//方式2:</span> vm.aaa = <span class="number">1</span>; <span class="comment">//一定会触发变动逻辑</span> vm._data.aaa = <span class="number">2</span>; <span class="comment">//也可以找到内部的data进行修改,但是没用</span> vm.aaa; <span class="comment">//1</span> |
1.2.3 小結與延伸對一類複雜並且常見的問題進行分析,解耦,抽象,在實踐的過程中獲得廣泛的認可,那就形成了一種模式,mvvm也是一種模式,它不一定叫mvvm模式,這也不是筆者能決定的 對於這個模式的核心,筆者理解如下:系統根據配置得到了對某些資料來源的某些處理規則,當資料來源變動時就會引發對應的處理規則。模式的擴展是雙向性,這由系統實作來決定,當符合某些規則的時候,可以對資料來源進行更新。 我們跳脫view的概念禁錮,聯想實現一個監控系統,其實這個模式非常適合用在監控系統上面。 一般的監控系統的處理邏輯是:由收集來源對監控資料進行收集整理,然後儲存到資料庫中,監控系統即時監控資料來源,繪製即時的圖線(回饋),當資料來源當發生了符合某些規則的變動時,就會觸發對應的動作,例如警報。 如何實現這個系統,讓系統有更高的擴充性?參考mvvm模式,可以這樣: 收集系統獨立於監控系統,各不相同,暫且不論。監控系統透過某些設定檔取得需要監控的資料來源與對應的處理邏輯規則,當資料來源變更時觸發對應的處理。 依照mvvm模式,進行一些抽象。
對應前端的mvvm框架,模板就是配置文件,directive就是處理規則,data對應資料來源。
2 vue實作vue介紹就不用了,太多資源了。這裡講述vue實踐過程中的一些收穫 2.1 組織結構
2.2 Vue扩展vue的扩展非常方便,与vue相关的资源都放置在src/common/vue/下面,比如coms(组件),directive,filter src/common/vue/vue.ext.js是对vue进行全局公共的扩展,对于所有页面共有的扩展放在这个文件下面,内容如下: 可以看到,扩展vue库本身有4个扩展点:
对于页面单独需要的扩展,集中在src/pages/pageName/vue.ext.js里面,形式与全局的vue.ext.js一样 在实例化Vue的过程中也有许多可以扩展与优化的地方,在实践过程中只是应用了mixin功能,其他的可以慢慢深入 mixin的作用是在实例化Vue的时候混入一些功能,它可以混入许多特性,格式与实例化Vue时用到的option格式一样,比如index页面的mixin.js的内容如下: 这个mixin混入了两个方法,多个Vue实例共享的options可以放置到mixin中,从而避免了代码重,比如在实例化Vue的时候这样使用mixin: 可以看到mixin是个数组,因此可以同时使用多个mixin 实际上这里的mixin主要不是为了避免代码重复(实践的时候只是这样用),mixin是一种模式,一个mixin内聚了实现一项功能的方法/属性集合,在定义/生成实例的时候,通过混入mixin就可以让该实例拥有某项功能,归根结底是组合vs继承问题的产物 2.3 vue组件插入问题2.3.1 首屏对于首屏的vue组件,直接把模板放在主页面中即可,初始化的时候只需要把el参数传入,Vue就会用el的html作为模板来初始化Vue实例: 这里需要注意的是在模板中不能使用{{}},否则在还没初始化之前,页面会显示奇怪的东西,比如:
2.3.2 非首屏对于非首屏的组件,使用vue的方式和原始方式差不多,先生成节点,然后append,譬如: el参数可以接收query string,也可以直接是一个dom节点,如果是dom节点则直接编译dom的内容。如果dom节点不在文档树中,则利用vueObj.$appendTo方法将vue实例的根节点插入到文档树中 上面这种方式是在页面中没有组件的【坑】的情况下使用的,如果页面为组件留了【坑】,比如:
那么,我们可以这样初始化vue实例: 利用template参数传入模板,并指定el,那么vue实例在初始化之后就会自动把内容插入到el中
2.4 自定义 directive在vue中自定义directive是非常简单明了的,要自定义一个directive,可以注册3个钩子函数:
下面简单介绍一个自定义directive——lazyload:
自訂filter也很簡單,只是定義一個處理函數而已,這裡就不多介紹了 2.5 實踐過程中的痛點與小技巧2.5.1 沒有事件代理用習慣了事件代理,突然沒有了會有點不習慣,但是回頭想想,事件代理真的很重要嗎?還是說我們只是習慣了事件代理而已? 透過vue註冊相同的事件並不費事。另一個問題,只要事件不多,大約不超過50,100,也不至於耗掉很大的內存,因此有時候還真不需要事件代理。如果真的需要,也只是實作一個contain方法而已 2.5.2 沒有if-else的奇怪最初看到下面的程式碼真的會覺得很奇怪
#2.5.3 單值雖然vue有語法解析器,可以在directive的值中使用表達式,但是當出現一個複雜的表達式時,會污染模板,讓程式碼可讀性變得很差,又或者,表達式完成不了這個任務的時候。 因此,在mvvm實踐的過程中,深深發現,利用單值(最多只用一個?:表達式)來寫模板會讓程式碼變得很清晰,更加可讀,增加程式碼的可維護性,而且這也更符合mvvm的核心思想:f(state) = view 有些函式庫連語法解析器都沒有,例如q,但也能很好的工作。 那麼,複雜的操作放在哪裡呢?
2.5.4 替代$(document).on用jquery/zepto的時候,習慣了用$(document).on來充當一個全局的事件代理,在使用vue的時候,需要拋棄zepto,因此需要解決這個問題 因為vue實例本身就有event功能,因此這裡解決的辦法是建立一個全域的空vue對象,把它當作全域的事件代理:
3 總結 雖然,最後在付出產出比權衡中放棄了對現有專案的vue改造,但這並不妨礙我們研究mvvm類別框架 mvvm模式還是值得我們去深入學習的,而在實踐中,我們也能學習到許多 用一種不一樣的思想和思維去開發的體驗也會令我們在看待問題,處理問題的道路上有所收穫。 相關推薦: |
以上是vue實踐小結之mvvm學習的詳細內容。更多資訊請關注PHP中文網其他相關文章!