一、相关技术背景
小程序是一种全新的连接用户与服务的方式,它可以在微信内被便捷地获取和传播,同时具有出色的使用体验。小程序并非凭空冒出来的一个概念。当微信中的 WebView 逐渐成为移动 Web 的一个重要入口时,微信就有相关的 JS API 了,通过暴露微信的接口使得 Web 开发者能够拥有更多的能力。
小程序的主要开发语言是 JavaScript、WXSS样式、WXMl模板,小程序的开发同普通的网页开发相比有很大的相似性。网页编程采用的是 HTML + CSS + JS 这样的组合,其中 HTML 是用来描述当前这个页面的结构,CSS 用来描述页面的样子,JS 通常是用来处理这个页面和用户的交互。同样道理,在小程序中也有同样的角色,其中 WXML 充当的就是类似 HTML 的角色,WXSS充当的就是类似 CSS的角色。其次,微信小程序中还有JSON配置文件,SON 是一种数据格式,并不是编程语言,在小程序中,JSON扮演的静态配置的角色。它能通过配置改变项目和各个页面的表现。
二、WXML模版语法缺陷
原生的WXML模板语法能实现将JavaScript中的逻辑状态绑定到WXML模板中,当状态改变时,模板中会自动更新数据,将最新状态展示给用户。但是,在WXML模板语法中,插入变量的双括号内只能进行简单的运算:三元运算、算术运算、逻辑判断等。
html
1 | <view hidden="{{flag ? true : false}}"> Hidden </view> |
某个状态需要经过稍复杂的计算处理再展示,那原生的WXML模板语法就实现不了。比如下面这个常见需求:一个用户可以搜索的列表;
html
1 | <!-- WXML代码 --> |
javascript
1 | // JavaScript代码 |
此时,列表只是展示了所有数据。如果要加入搜索框的搜索功能,则需要在WXML模板中加入列表筛选逻辑:
html
1 | <view class="list-item" wx:for="{{list.map(item => item.indexOf(searchValue) >= 0)}}" wx:key="{{item}}">{{item}}</view> |
但是,WXML模板只支持简单运算,并不支持map, indexOf语法,微信小程序开发者工具会报错:bad attr。
三、computed函数的实现
- 流程图
- 代码实现javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44// 暂时存储
let computedHandle = null;
function computed(context, computedFuncs) {
// 代理对象,监听取值和赋值
const handlerObj = {};
context.data = new Proxy(context.data, {
get: function(obj, prop) {
if (computedHandle) {
if (!handlerObj[prop]) {
handlerObj[prop] = [];
}
handlerObj[prop].push(computedHandle)
}
return obj[prop];
},
set: function(obj, prop, value) {
if (obj[prop] === value) return;
if (handlerObj[prop].length > 0) {
// 用 setTimeout 延时更新
setTimeout(() => {
handlerObj[prop].forEach(handle => handle())
}, 0);
}
obj[prop] = value;
}
});
// 添加各个计算属性所依赖的原始data中的状态
const computedObj = {};
Object.keys(computedFuncs).forEach(prop => {
computedHandle = function() {
context.setData({
[prop]: computedFuncs[prop].call(context)
})
};
computedObj[prop] = computedFuncs[prop].call(context);
computedHandle = null;
}, {})
context.setData(computedObj)
}
export default computed;
四、computed工具函数的使用
以上面的可搜索列表为例:
javascript
1 | // 1. 引入computed函数 |