1.wepy组件的编译
wepy中使用一个组件时候,需要先引用(import)。再在需要使用该组件的页面(或组件)中声明。例如:
import Counter from '/path/to/Counter';
components = { counter1: Counter, counter2: Counter
}
引入一个组件要出现在多处分别使用时,需要为组件分配不同的id,此处分别为counter1,counter2。
如果Counter组件模板
<view>{{counter}}</view>
则编译后的counter1内容在其引用的页面中的样子为:
<view>{{$counter1$counter}}</view>
编译后的counter2内容为
<view>{{$counter2$counter}}</view>
2.wepy组件中的setData
wepy通过在函数运行周期结束时候,进行脏值检查,以便使用者可以不用手动setData更新视图。
但是在组件中,由于组件被编译成了$prefix$value的形式,即组件中定义的data,无法直接通过this.setData({key:value})形式去更新。
如果需要手动调用this.setData({key: value});需要这样使用-> this.setData({this.$prefix+key: value});
用上面的Counter组件为例:
export default class Counter extends wepy.component { data = { counter: 1 }
onload() {
// 正确
this.setData({this.prefix+'counter': 2});
this.data = 2; //setData 完要记得更新counter中的值。
// 错误
this.setData({counter: 2});
}
}
应用场景:脏值检查时候由于值未更新,所以不会自动触发setData去更新(脏值检查会在合适时触发setData)。有时候需要特殊的效果
比如focus文本框,此时文本框已经失去了焦点,但是控制文本框焦点的变量值仍为true。此时想要让文本框再次获得焦点,setData一下。
3.wepy对于wx.xxx一系列的promise化
1 // 原生代码: 2 wx.request({ 3 url: 'xxx', 4 success: function (data) { 5 console.log(data); 6 } 7 }); 8 9 // WePY 使用方式 10 wepy.request('xxxx').then((d) => console.log(d));
原生代码中需要将成功回调作为参数传入request,wepy中可以通过promise的用法使用。
其中核心的代码如下:
其中obj为传入函数的参数。
翻译一下这段代码就是:
var wx = { getStorage: function(config) { // 如果异步事情搞定: if(ok) { config.success(res); } else { config.error({err:'错误'}); } } } //使用 wx.getStorage({ success: (res)=> {}, error: (err) => {} }); // promisify Object.defineProperties(wx, 'getStorage', { get() { // get函数,则返回函数 // obj为传入函数的参数 return (obj) => { obj = obj || {}; var p = new Promise((okFn, errFn) => { const oldHandler = {}; oldHandler['success'] = obj.success; oldHandler['failed'] = obj.failed; // 成功的话,resolve这个promise。 obj.success = (res) => { okFn(res); } // 失败的话reject这个promise。 obj.error = (err) => { errFn(err); }; // 调用这个函数 wx.getStorage(obj); }); // 返回这个promise return p; } } })
4.wepy对请求队列的优化
原生的小程序对并发的请求有最大个数限制是10个。也就是说一次发送11个请求就会报错。
wepy对其进行了优化,其核心代码如下:
import native from './native'; let RequestMQ = { map: {}, mq: [], running: [], MAX_REQUEST: 5, push (param) { param.t = +new Date(); while ((this.mq.indexOf(param.t) > -1 || this.running.indexOf(param.t) > -1)) { param.t += Math.random() * 10 >> 0; } this.mq.push(param.t); this.map[param.t] = param; }, next () { let me = this; if (this.mq.length === 0) return; if (this.running.length < this.MAX_REQUEST - 1) { let newone = this.mq.shift(); let obj = this.map[newone]; let oldComplete = obj.complete; obj.complete = (...args) => { me.running.splice(me.running.indexOf(obj.t), 1); delete me.map[obj.t]; oldComplete && oldComplete.apply(obj, args); me.next(); } this.running.push(obj.t); return wx.request(obj); } }, request (obj) { obj = obj || {}; obj = (typeof(obj) === 'string') ? {url: obj} : obj; this.push(obj); return this.next(); } };
核心思想为,维护一个等待队列和一个执行中队列。如果有请求过来,先放到等待队列,然后判断执行队列中任务数是否达到最大,未达到最大则从等待队列取出任务放到执行队列执行。一旦执行队列有任务执行完成。则进行新一轮的检查执行。