前言
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