wx:key
如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如 input 中的输入内容,switch 的选中状态),需要使用 wx:key 来指定列表中项目的唯一标识符。
wx:key 的值以两种形式提供:
- 字符串:代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。
- 保留关键字:
*this
代表在 for 循环中 item 本身,这种表示需要 item 本身是一个唯一的字符串或者 - 数字。
?> 底层原理:小程序内部也使用了虚拟DOM(和Vue,React相似),通过key可以更好更快的判断是否可以复用
首先来看一个不使用wx:key的情况下,我们的示例会出现什么意想不到的情况,我们现在index.js定义一个属性来存储一些数据,然后编写一个方法用来给index.wxml页面按钮点击事件使用:
index.js:
data: { chs: ['a', 'b', 'c'] }, _myClickHandle: function(){ console.log("加之前:" + this.data.chs) this.data.chs.push('d'); this.setData(this.data); console.log("加之后:" + this.data.chs) },
index.wxml:
<view wx:for="{{ chs }}"> <switch/> <text>{{ item }}</text> </view> <button bindtap="_myClickHandle">按钮</button>
这个实例看起来一切正常,我们是往数组的后面追加元素的,我们来改造成往前面进行添加元素,更改一下_myClickHandle方法的追加方式从 push 改为 unshift:
this.data.chs.unshift('d');
再次运行我们的程序结果如下:
发现我们新增的元素的开关状态自动被打开了,这个时候就出现了很严重的问题。
出现问题的原因:
正是因为如此,就有了wx:key这么一个东西来解决该问题。
wx:key 官方文档:https://developers.weixin.qq.com/miniprogram/dev/reference/wxml/list.html#wx-key
到了这里我们就知道了如果不用wx:key那么就会出现复用DOM出错的情况,那么我们就来使用下,经过上面的一帆介绍我们知道了有两种wx:key的使用方式我们先来看,保留关键字。
保留关键字
如果上图的效果很显然,我们的问题已经得到了解决,那么为啥添加了wx:key那么就不会导致我们新增的元素复用错误呢,我画了张图看下图:
好了,通过上图我们可以很清楚的看明白,我们的新增元素在复用组件当中找不到所以会重新创建一个新的。
如果列表渲染出来的数据不会发生变化,那么添加不添加wx:key都无所谓,但是还是建议添加,如果列表渲染出来的数据会发生变化,那么必须添加wx:key保证数据状态的正确性。
*this
:表示当前遍历到的元素,也就是item中存储的内容,如果是独一无二的简单类型数据,可以使用 *this
但是如果是复杂类型(对象/数组), 不能使用*this。因为给到的结构是[object object] 无法保证唯一。
字符串
关于字符串的wx:key这里就简单弄个数据结构进行渲染即可:
index.js:
objectArray: [ {id: 5, unique: 'unique_5'}, {id: 4, unique: 'unique_4'}, {id: 3, unique: 'unique_3'}, {id: 2, unique: 'unique_2'}, {id: 1, unique: 'unique_1'}, {id: 0, unique: 'unique_0'}, ],
index.wxml:
<view wx:for="{{ objectArray }}" wx:key="id"> <text>{{ item.unique }}</text> </view>
wx:key=“id” 表示从当前遍历到的数组中获取id的值,item -> object -> item.id。