labrador 命令
labrador init 初始化项目命令
注意此命令会初始化当前的目录为项目目录。
labrador build 构建当前项目
Usage: labrador build [options] Options: -h, --help output usage information -V, --version output the version number -c, --catch 在载入时自动catch所有JS脚本的错误 -t, --test 运行测试脚本 -d, --debug DEBUG模式 -m, --minify 压缩代码 -f, --force 强制构建,不使用缓存
labrador watch 监测文件变化
Usage: labrador watch [options] Options: -h, --help output usage information -V, --version output the version number -c, --catch 在载入时自动catch所有JS脚本的错误 -t, --test 运行测试脚本 -d, --debug DEBUG模式
labrador 库
labrador 库对全局的 wx 变量进行了封装,将大部分 wx 对象中的方法进行了Promise支持, 除了以 on* 开头或以 *Sync结尾的方法。在如下代码中使用 labrador 库。
import wx from 'labrador';console.log(wx.version);wx.app; // 和全局的 getApp() 函数效果一样,代码风格不建议粗暴地访问全局对象和方法wx.Component; // Labrador 自定义组件基类wx.List; // Labrador 自定义组件列表类wx.PropTypes; // Labrador 数据类型校验器集合wx.login; // 封装后的微信登录接口wx.getStorage; // 封装后的读取缓存接口
我们建议不要再使用 wx.getStorageSync() 等同步阻塞方法,而在 async 函数中使用 await wx.getStorage() 异步非阻塞方法提高性能,除非遇到特殊情况。
app.js
src/app.js 示例代码如下:
import wx from 'labrador';import {sleep} from './utils/util';export default class { globalData = { userInfo: null }; async onLaunch() { //调用API从本地缓存中获取数据 let res = await wx.getStorage({ key: 'logs' }); let logs = res.data || []; logs.unshift(Date.now()); await wx.setStorage({ key: 'logs', data: logs }); this.timer(); } async timer() { while (true) { console.log('hello'); await sleep(10000); } } async getUserInfo() { if (this.globalData.userInfo) { return this.globalData.userInfo; } await wx.login(); let res = await wx.getUserInfo(); this.globalData.userInfo = res.userInfo; return res.userInfo; } }
代码中全部使用ES6/7标准语法。代码不必声明 use strict ,因为在编译时,所有代码都会强制使用严格模式。
代码中并未调用全局的 App() 方法,而是使用 export 语法默认导出了一个类,在编译后,Labrador会自动增加 App() 方法调用,所有请勿手动调用 App() 方法。这样做是因为代码风格不建议粗暴地访问全局对象和方法。
自定义组件
Labrador的自定义组件,是基于微信小程序框架的组件之上,进一步自定义组合,拥有逻辑处理和样式。
项目中通用自定义组件存放在 src/compontents 目录,一个组件一般由三个文件组成,*.js 、 *.xml 和 *.less 分别对应微信小程序框架的 js 、 wxml 和 wxss 文件。在Labardor项目源码中,我们特意采用了 xml 和 less 后缀以示区别。如果组件包含单元测试,那么在组件目录下会存在一个 *.test.js 的测试脚本文件。
自定义组件示例
下面是一个简单的自定义组件代码实例:
逻辑 src/compontents/title/title.js
import wx from 'labrador';import randomColor from '../../utils/random-color';const { string } = wx.PropTypes;export default class Title extends wx.Component { propTypes = { text: string }; props = { text: '' }; data = { text: '', color: randomColor() }; onUpdate(props) { this.setData('text', props.text); } handleTap() { this.setData({ color: randomColor() }); } }
自定义组件的逻辑代码和微信框架中的page很相似,最大的区别是在js逻辑代码中,没有调用全局的 Page() 函数声明页面,而是用 export 语法导出了一个默认的类,这个类必须继承于 labrador.Component 组件基类。
相对于微信框架中的page,Labrador自定义组件扩展了 propTypes 、 props 、 children 选项及 onUpdate 生命周期函数。children 选项代表当前组件中的子组件集合,此选项将在下文中叙述。
Labrador的目标是构建一个可以重用、嵌套的自定义组件方案,在现实情况中,当多个组件互相嵌套组合,就一定会遇到父子组件件的数据和消息传递。因为所有的组件都实现了 setData 方法,所以我们可以使用this.children.foobar.setData(data) 或 this.parent.setData(data) 这样的代码调用来解决父子组件间的数据传递问题,但是,如果项目中出现大量这样的代码,那么数据流将变得非常混乱。
我们借鉴了 React.js 的思想,为组件增加了 props 机制。子组件通过 this.props 得到父组件给自己传达的参数数据。父组件怎样将数据传递给子组件,我们下文中叙述。
onUpdate 生命周期函数是当组件的 props 发生变化后被调用,类似React.js