前言
Framework7 作為移動端的開發框架的優良之處已經無需多言。現在已經有了 React 和 Vue 版本,之前在項目中用過 F7 + vue 的開發方式,無論是效率還是產出都近乎完美。有時間的話可以單獨寫篇文章詳細介紹 Framework7,並與其它框架做對比。
插件的問題
對於 Framework7 插件的開發我就不多言了,官方文檔很詳細。Framework7 的插件開發確實很簡單,但有些需要特殊對待的問題,我想通過索引插件這個例子簡單說說我的解決方法。
索引列表在移動端算是比較常見的需求,我在工作中也遇到了這個需求,框架選用的是 Framework7,所以就直接用這個現成的插件了。插件代碼如下:
Framework7.prototype.plugins.indexedlist = function (app, params) { var $ = window.Dom7; function initIndexedList(page) { var eventsTarget = $(page.container).find('.list-index'); if (eventsTarget.length === 0) return; var pageContent = $(page.container).find('.page-content'); ... } return { hooks: { pageInit: initIndexedList, } }; };
初始化 Framework7:
var myApp = new Framework7({ modalTitle: 'My App', pushState: true, ... });
Framework7 的插件都是在 F7 初始化之后立即執行,所以動態生成的數據就有問題了。雖然官方文檔提供了很多鈎子,但都不太合適。整個列表應該是獲取接口數據之后動態生成的,所以為了保證先載入數據再執行 Framework7,我最初想到的方法就是等到頁面所有數據都請求完成之后再初始化 Framework7,不過這種方式稍微有些不友好。
$.when(ajax1,ajax2,ajax3).done(function(res1,res2,res3){ new Framework7({ ... }); });
插件改造
最后的辦法只能是修改插件,最終嘗試了很長時間才找到辦法。初始化 F7 時可以給插件傳遞參數,如下:
var myApp = new Framework7({ modalTitle: 'My App', pushState: true, /* Here comes your plugin parameters that will be passed to your plugin in case of parameter name is the same as plugin name: */ myPlugin: { foo: 'bar' } });
這樣的話我們可以在插件函數執行之前加一個判斷:
Framework7.prototype.plugins.indexedlist = function (app, params) { var $ = window.Dom7; // the plugin will not initialize automaticly if (!params.init) return; function initIndexedList(page) { var eventsTarget = $(page.container).find('.list-index'); if (eventsTarget.length === 0) return; var pageContent = $(page.container).find('.page-content'); ...
} return { hooks: { pageInit: initIndexedList, } }; };
其次插件的鈎子函數也要刪除,簡單說一下,插件的返回值是一個鈎子函數,表示頁面加載完成立即執行initIndexedList()
函數,其參數是一個 page
對象,其中 page.container
就表示 .page
元素。刪除鈎子函數之后我們可以通過 params
參數來傳遞 container
,這樣反而可以增加插件的靈活性。
Framework7.prototype.plugins.indexedlist = function (app, params) { var $ = window.Dom7; // the plugin will not initialize automaticly if (!params.init) return; function initIndexedList(page) { var eventsTarget = $(page.container).find('.list-index'); if (eventsTarget.length === 0) return; var pageContent = $(page.container).find('.page-content'); ... } initIndexedList(params); };
插件修改后的調用方式,初始化 F7 時可以將插件的 init
設為 false
var indexedlist = new Framework7({ indexedlist:{ init:true, container:'.page' } });
這樣就可以在動態獲取數據之后的回調函數中調用插件了。
Github: https://github.com/nzbin/Framework7-Indexed-List-plugin