代码:https://github.com/jsongo/wx-gesture-lockjavascript
这个手势解锁的demo使用了https://github.com/lvming6816077/H5lock 这个项目的算法和主逻辑,整合到微信小程序来,修改了不少地方的语法来适配小程序,去掉了window、document等函数,同时也添加了新的机制来解耦界面的操做和第三方库,这个下面会介绍到。java
不过惋惜的是,这个demo也只能在开发工具上玩玩,到真机上测试的时候,手指一滑动,页面会跟着滚动,手势无法使用。git
下面咱们从这个例子中,来分析两个能够学习的点。es6
一、引入第三方库github
咱们上面提到的H5lock这个库,是个大神写的、专给H5用的一个功能。咱们对它进行了一翻修改,把它引入到小程序上来了。算法
这里讨论下如何把第三方js库引入到小程序来,分如下几个步骤:json
(1)模块化小程序
小程序代码中,只能经过module.exports来导出的模块才能被引用,因此第一步,咱们要对代码进行第一个改造,作exports导出:微信小程序
module.exports = { ... }
若是要在被引入的时候,执行一些操做,能够用如下两种方式:api
//// mylib.js module.exports = (function() { // 这里写上你要执行的代码 … return xxx; //返回你要导出的方法,若是多个就写成一个map })(); … //// 其它文件中这么引用和执行: let MyLib = require('mylib.js'); let lib = Mylib(); lib.xxx(); // 执行
或es6中的class:
//// mylib.js module.exports = class { constructor() { // // 这里写上你要执行的代码 } // 其它方法 xxx() { ... } } … //// 其它文件中这么引用和执行: let MyLib = require('mylib.js'); let lib = new Mylib(); // 用new来生成类的对象 lib.xxx(); // 执行
(2)对第三方库中的一些函数进行改造
小程序不支持如下几个函数或api:
window document frames self location navigator localStorage history caches screen alert confirm prompt XMLHttpRequest WebSocket |
跟以上相关的代码一个个搜索出来,并想办法替换掉。
最多见的通常是document操做,第三方库主要是用它来引用dom,并对它进行设置或修改。这个能够经过下面第2点会讲的解耦技巧来巧妙地绕过。其它的就靠开发者本身去想了,这里没办法一一列出全部的状况。
本文的demo用的是class的方式来改造了第三方库。
二、一种解耦的方式
在小程序开发的时候,若是一个页面的js写得太长,甚至超过了上千行,那你就要考虑把这个文件分拆成几个。或者你写的逻辑代码,能够几个页面共用,那么你也是要把代码从这个页面的js里拆出来的。
这里就引出了一个比较显明的问题:在其它文件中,要修改页面上的数据,又不能耦合性太大,由于你的这段逻辑代码,在页面A中会引用到,在页面B中也会引用到,这样总不能把setData操做放到这个共用的文件里吧。
那有什么办法能够解耦呢?
这个时候,可能你会想到普通页面开发时,用到的trigger机制,惋惜这个只能在dom上绑定。也或许你用过http://statejs.org/ 这个库,经过状态机的变化来触发某些特定的操做,这个方法很是巧妙,没接触过这个库的开发者,建议学习一下。
不过咱们还不须要再引入一个库,这里,咱们来写个简单的。简单到只有几行代码。
代码在这里:https://github.com/jsongo/wx-gesture-lock/blob/master/lib/event.js
module.exports = function(app) { app && (app.trigger = function(eventType, data) { var pages = getCurrentPages(), curPage = pages[pages.length-1], methodName = 'on' + eventType.charAt(0).toUpperCase() + eventType.substr(1), callback = curPage[methodName]; callback && callback.call(curPage, data); }); };
如何使用这个库?分析一下大概的过程,其实很是简单,就是给app添加一个trigger方法,当它被调用的时候,去查找当前页面是否在onXXX方法,有的话就调用。这个方法名,是经过eventType这个参数变形而成的,如app.trigger('textChange') ,则这里会去查找页面中是否有onTextChange方法。因此其实这个解耦方法,本质上,是定义了一种规范。
首页在app.js里引入,并在onLaunch里调用:
var event = require('lib/event.js'); App({ onLaunch: function () { event(this); // 在onLaunch里调用,传入的this就是app自己 }, globalData:{ } });
而后在共用的抽离出来的文件中,在须要用到setData的地方,写成以下形式:
app.trigger('titleChanged', '请解锁');
接着在页面的js代码里,添加对这个trigger的响应:
Page({ … onTitleChanged: function(newTitle) { // 文字变化的事件,自定义 this.setData({ title: newTitle }); } ... });
这三步作完就ok了。
拉了个小程序的微信群,对这方面有兴趣的朋友能够加进来交流技术问题。