【如何實現backbone元件化開發】 第一篇:無元件所帶來的問題
元件化開發優勢
從2015以來前後端分離的模式被越來越多的公司所使用,隨著業務程式碼複雜度的上升,程式碼也維護成本也隨之上升。對於一個複雜的web應用,我們可以使用分而治之的方式來降低系統的複雜度,也就是標題中所說的元件化開發。元件化開發可以把系統分割多個子模組,每個模組完成單一的功能,不同模組可以相互組合、相互通訊,從而構建大型複雜應用。
Backbone中的元件化和其他流行的前端框架相比並不是很完善,例如在Vuejs中我們只需要引入一個vue單檔案元件就可以獲得元件的Dom、樣式、功能等。儘管Backbone沒有官方推薦的元件化方案,但是我們可以使用webpack打包技術,以及自己對Backbone物件進行封裝來實現類似於vue框架的元件化開發。
在下面的文章中我們一起,一步一步實現Backbone的元件化。
Backbone的元件化
Backbone是一個經典的MVC框架,但是本身並沒有提供很完善的元件機制。我在開發的過程中碰到以下三個問題。
1. 模組中的各部分過於分散,無法集中應用
在Backbone中如果需要一個模組的渲染和事件繫結,我們至少需要在頁面上呼叫model
和view
兩個類。如果這個元件需要使用一組model那就需要呼叫Collection
類。這已經涉及到三個物件的呼叫。
如果模組中字串模板的和css的引用,那麼一個功能模組就涉及到5個資源的應用。而且資源分散在html檔案、css檔案、js檔案中,這對於程式碼的模組化是極其不友好的。
2. 編譯模板的效率
Backbone通常使用字串模板來實現Dom結構,在官方提供的例項程式中,模板的編譯是在View物件的初始化過程中完成的。也就是說模板編譯是在瀏覽器首次載入View物件時完成的。程式碼貼上。
var AppView = Backbone.View.extend({
// Our template for the line of statistics at the bottom of the app.
statsTemplate: _.template($('#stats-template').html())
})
這會導致兩個問題,第一瀏覽器編譯模板檔案是需要時間的,這部分工作完全可以在程式碼打包時候完成。第二、所有的模板需要在頁面渲染之前完成編譯,如果模板數量大的話會影響首屏效能。
3. 沒有提供方便的模板巢狀組合的方案
如果要在backbone中實現元件巢狀(例如tab切換元件中巢狀多個自定義表單元件),那個tab元件的view和表單元件的view將耦合在一起。那個tab元件就失去了元件化的意義。來看看官方的例子。
var AppView = Backbone.View.extend({
render: function() {
// 這裡的Todos Model是子模板的Model,也就是AppView和子模版的model耦合
var done = Todos.done().length;
var remaining = Todos.remaining().length;
// 無關程式碼。。。
},
addOne: function(todo) {
// 這裡的TodoView是子模板的View,也就是AppView和子模版的View耦合
var view = new TodoView({model: todo});
this.$("#todo-list").append(view.render().el);
},
});
如何優化?
首先來定義我們做優化的目標。
- 首先希望做到元件的引用盡量簡化、集中。最好和Vue的單檔案元件類似。希望最終可以做到通過匯入一個js檔案就可以匯入元件的Dom模板、樣式、事件。這個改進可以通過webpack等打包工具完成,具體配置會在下一篇文章中展開。
- 接下來我們需要解決模板編譯效率的問題。通過使用underscore-template-loader載入模板檔案,我們在程式碼打包階段完成模板的編譯,具體配置會在下一篇文章中展開。
- 最後是要解決元件巢狀的問題。我們可以在Model和View物件的上層提供一個封裝物件,並對外提供的介面。這樣不同的元件可以通過統一的介面巢狀成複雜的元件。具體配置會在下一篇文章中展開。