列表渲染

a:for

在组件上使用 a:for 属性可以绑定一个数组,即可使用数组中各项的数据重复渲染该组件。

数组当前项的下标变量名默认为 index,数组当前项的变量名默认为 item

  1. <view a:for="{{array}}">
  2. {{index}}: {{item.message}}
  3. </view>
  1. Page({
  2. data: {
  3. array: [{
  4. message: 'foo',
  5. }, {
  6. message: 'bar',
  7. }],
  8. },
  9. });

使用 a:for-item 可以指定数组当前元素的变量名。使用 a:for-index 可以指定数组当前下标的变量名。

  1. <view a:for="{{array}}" a:for-index="idx" a:for-item="itemName">
  2. {{idx}}: {{itemName.message}}
  3. </view>

a:for 支持嵌套。以下是九九乘法表的嵌套示例代码。

  1. <view a:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" a:for-item="i">
  2. <view a:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" a:for-item="j">
  3. <view a:if="{{i <= j}}">
  4. {{i}} * {{j}} = {{i * j}}
  5. </view>
  6. </view>
  7. </view>

block a:for

block a:if 类似,可以将 a:for 用在 <block/> 标签上,以渲染一个包含多节点的结构块。

  1. <block a:for="{{[1, 2, 3]}}">
  2. <view> {{index}}: </view>
  3. <view> {{item}} </view>
  4. </block>

a:key

如果列表项位置会动态改变或者有新项目添加到列表中,同时希望列表项保持特征和状态(比如 <input/> 中的输入内容,<switch/> 的选中状态),需要使用 a:key 来指定列表项的唯一标识。

a:key 的值以两种形式来提供:

  • 字符串:代表列表项某个属性,属性值需要是列表中唯一的字符串或数字,比如 ID,并且不能动态改变。
  • 保留关键字 *this,代表列表项本身,并且它是唯一的字符串或者数字,比如当数据改变触发重新渲染时,会校正带有 key 的组件,框架会确保他们重新被排序,而不是重新创建,这可以使组件保持自身状态,提高列表渲染效率。
说明
  • 如不提供 a:key,会报错。
  • 如果明确知道列表是静态,或者不用关注其顺序,则可以忽略。

示例代码:

  1. <view class="container">
  2. <view a:for="{{list}}" a:key="*this">
  3. <view onTap="bringToFront" data-value="{{item}}">
  4. {{item}}: click to bring to front
  5. </view>
  6. </view>
  7. </view>
  1. Page({
  2. data:{
  3. list:['1', '2', '3', '4'],
  4. },
  5. bringToFront(e) {
  6. const { value } = e.target.dataset;
  7. const list = this.data.list.concat();
  8. const index = list.indexOf(value);
  9. if (index !== -1) {
  10. list.splice(index, 1);
  11. list.unshift(value);
  12. this.setData({ list });
  13. }
  14. },
  15. });

key

key 是比 a:key 更通用的写法,里面可以填充任意表达式和字符串。

说明key 不能设置在 block 上。

示例代码:

  1. <view class="container">
  2. <view a:for="{{list}}" key="{{item}}">
  3. <view onTap="bringToFront" data-value="{{item}}">
  4. {{item}}: click to bring to front
  5. </view>
  6. </view>
  7. </view>
  1. Page({
  2. data:{
  3. list:['1', '2', '3', '4'],
  4. },
  5. bringToFront(e) {
  6. const { value } = e.target.dataset;
  7. const list = this.data.list.concat();
  8. const index = list.indexOf(value);
  9. if (index !== -1) {
  10. list.splice(index, 1);
  11. list.unshift(value);
  12. this.setData({ list });
  13. }
  14. },
  15. });

同时可以利用 key 来防止组件复用,例如允许用户输入不同类型数据:

  1. <input a:if="{{name}}" placeholder="Enter your name" />
  2. <input a:else placeholder="Enter your email address" />

那么当输入 name 然后切换到 email 时,当前输入值会保留,如果不想保留,可以加 key

  1. <input key="name" a:if="{{name}}" placeholder="Enter your name" />
  2. <input key="email" a:else placeholder="Enter your email address" />