咸鱼

咸鱼是以盐腌渍后,晒干的鱼

0%

声明式UI:微信小程序简单语法总结

此文档为了对比各个声明式UI编程语法,避免混淆。

小程序框架

0. 声明式渲染

1
<view> {{message}} </view>
1
2
3
4
5
Page({
data: {
message: 'Hello World!'
}
})

1. 访问变量

1
<view> {{message}} </view>
1
2
3
4
5
6
7
8
9
10
Page({
data: {
message: 'Hello World!'
},
hello(){
this.setData({
message: this.data.message + " 6666666!"
})
}
})

2. 条件 (wx-if)

1
2
3
4
5
6
7
8
<view wx:if="{{view == 'WEBVIEW'}}"> WEBVIEW </view>
<view wx:elif="{{view == 'APP'}}"> APP </view>
<view wx:else="{{view == 'MINA'}}"> MINA </view>

<checkbox checked="{{false}}"> </checkbox>

<view hidden="{{flag ? true : false}}"> Hidden </view>

1
2
3
4
5
Page({
data: {
view: 'MINA'
}
})

3. 循环 (wx-for)

1
<view wx:for="{{array}}"> {{item}} </view>
1
2
3
4
5
Page({
data: {
array: [1, 2, 3, 4, 5]
}
})

4. 事件 (bind:[])

绑定点击事件: tap

1
<view id="tapTest" data-hi="Weixin" bindtap="tapName"> Click me! </view>
1
2
3
4
5
Page({
tapName: function(event) {
console.log(event)
}
})

绑定其他事件

1
2
3
<view id="outer" bind:touchstart="handleTap1">
outer view
</view>

5.绑定样式

1
<view style="color:{{color}};" />
1
<view class="normal_view" />

6. 双向绑定(model:value)

单向绑定

普通的属性的绑定是单向的。例如:

1
<input value="{{value}}" />

this.setData() 会更新输入框,但输入框的修改不会改变 this.data.value

双向绑定

两边都会改变,数据监听器 也会被正常触发。

1
<input model:value="{{value}}" />

双向绑定不支持的写法:

1
2
3
4
5
6
<-- 只能是一个单一字段的绑定 -->
<input model:value="值为 {{value}}" />
<input model:value="{{ a + b }}" />

<-- 不能 data 路径 -->
<input model:value="{{ a.b }}" />

7. 计算属性(wxs)

小程序没有computed 方法,但有 WXS(WeiXin Script)(内联在 WXML 中的脚本段)实现相同的效果。

WXS 语法参考

页面渲染

1
2
3
4
5
6
7
8
9
<!--wxml-->
<wxs module="m1">
var msg = "hello world";

module.exports.message = msg;
</wxs>

<!--引用-->
<view> {{m1.message}} </view>

数据处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!--wxml-->
<!-- 下面的 getMax 函数,接受一个数组,且返回数组中最大的元素的值 -->
<wxs module="m1">
var getMax = function(array) {
var max = undefined;
for (var i = 0; i < array.length; ++i) {
max = max === undefined ?
array[i] :
(max >= array[i] ? max : array[i]);
}
return max;
}

module.exports.getMax = getMax;
</wxs>

<!-- 调用 wxs 里面的 getMax 函数,参数为 page.js 里面的 array -->
<view> {{m1.getMax(array)}} </view>
1
2
3
4
5
6
// page.js
Page({
data: {
array: [1, 2, 3, 4, 5, 1, 2, 3, 4]
}
})

8. 监听器(observers)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Component({
attached: function() {
this.setData({
numberA: 1,
numberB: 2,
})
},
observers: {
'numberA, numberB': function(numberA, numberB) {
// 在 numberA 或者 numberB 被设置时,执行这个函数
this.setData({
sum: numberA + numberB
})
}
}
})

监听器可以监听子数据字段,如下例所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Component({
observers: {
'some.subfield': function(subfield) {
// 使用 setData 设置 this.data.some.subfield 时触发
// (除此以外,使用 setData 设置 this.data.some 也会触发)
subfield === this.data.some.subfield
},
'arr[12]': function(arr12) {
// 使用 setData 设置 this.data.arr[12] 时触发
// (除此以外,使用 setData 设置 this.data.arr 也会触发)
arr12 === this.data.arr[12]
},
}
})

如果需要监听所有子数据字段的变化,可以使用通配符 **

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Component({
observers: {
'some.field.**': function(field) {
// 使用 setData 设置 this.data.some.field 本身或其下任何子数据字段时触发
// (除此以外,使用 setData 设置 this.data.some 也会触发)
field === this.data.some.field
},
},
attached: function() {
// 这样会触发上面的 observer
this.setData({
'some.field': { /* ... */ }
})
// 这样也会触发上面的 observer
this.setData({
'some.field.xxx': { /* ... */ }
})
// 这样还是会触发上面的 observer
this.setData({
'some': { /* ... */ }
})
}
})