微信小程序属性剖析:wx-key就这么重要吗?

本文探讨了微信小程序中wx:key的关键作用,特别是在for循环中的应用。通过实例展示了wx:key如何确保数据与结构的对应关系,强调了当数据项需要保持其特征或状态时,添加wx:key的必要性。同时,解释了为何仅使用索引作为key无效,并提出了正确使用wx:key的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天,就想和各位说说微信小程序中的【臂膀】——wx-key

fg

毫无疑问,wx-key在微信小程序中可谓是“大出风头”,这一点尤其在for循环中体现出来。但wx-key的作用,你真的了解吗?

事实上,作为“唯一标识”,微信小程序也极力提倡在一些组件中使用


我们先来写一个简单的list列表:

//wxml
<block wx:for="{{arr}}">
	<view>{{item}}</view>
</block>

//js-data
data:{
	arr:['wxml','js','wxss','json']
},

0

现在,我们给它加上索引:

//wxml
<block wx:for="{{arr}}">
	<view>{{index}}-{{item}}</view>
</block>

微信小程序for循环默认每一项是一个“item”,默认每一项的索引为“index”。
当然,也可以通过wx:for-item重新设置(每一项的名称)。

上面是wx-for循环的使用,
为了更好的展示wx:key的作用,我们给每一项前面加个【复选框】,并增加一个button按钮用来对list进行“随机排序”:

//wxml
<block wx:for="{{arr}}" wx:for-item="data">
	<view><checkbox />{{data}}</view>
</block>
<button bindtap="sort">随机排序</button>

2

//js-随机排序代码(本文所有“随机排序”皆用此代码)
sort(){
	const len=this.data.arr.length
	for(let i in this.data.arr){
		let x=Math.floor(Math.random()*len)
		let y=Math.floor(Math.random()*len)
		let temp=this.data.arr[x]
		this.data.arr[x]=this.data.arr[y]
		this.data.arr[y]=temp
	}
	this.setData({
		arr:this.data.arr
	})
},

11

重点来了,现在我随机勾选两项,然后按下button按钮:
12

我们会“惊恐”的发现:不管怎样,选中的都是“第二项”和“第四项”;但显然,我们希望选中的只是最开始“第二项”和“第四项”对应的数据!

其实,这无疑是“数据优先”的一个特点:从始至终我们都在操控数据,而无关结构

当然,这也是wx:key的作用之一:


正式篇:wx:key的解析

可能有的初学者会发现,有的地方完全“没必要”加上wx:key,而有的地方却必须要用?
这是【数据项是否发生变化】的区别。

所谓key —— 钥匙。正如“一把钥匙对应一把锁”。当一个数据项需要保证(持)他自己的【特征】,或者说【状态】时,才需要为其添加“key属性”。

我们改写一下上面的代码:

//wxml
<block wx:for="{{arr}}" wx:for-item="data" wx:key="{{index}}">
	<view><checkbox />{{data}}</view>
</block>
<button bindtap="sort">随机排序</button>

前面说过,微信中for循环默认每一项“下标”用index显示。
然后我们会发现:毫无作用。

是key坏了么?
还是不应该加index?
但是不是说为每一项加一个“唯一标识”就行么,难道下标不是?
mv

其实还真不行:“前面说了,for循环索引是index” —— 坏就坏在这句话上:索引本来就是“不变的”啊。

这么说吧:比如这里的arr数组,索引永远是0、1、2、3,哪怕元素改变了,下标却并不“被携带”。
这有点像什么呢?
“索引是数组为元素(位置)定下的索引,而不是元素的索引”

遇见这种情况我们就需要用到另一个关键字 —— *this,用于小程序的for循环中,作为“指针”指向每一项自身:

//wxml
<block wx:for="{{arr}}" wx:for-item="data" wx:key="*this">
	<view><checkbox />{{data}}</view>
</block>
<button bindtap="sort">随机排序</button>

13

现在就可以了!

由此可见:key属性必须是“关乎数据项自身的”、“独一无二的”。


我们不妨来看另一种情况,把数据变“复杂”一些:

//js-data
data:{
	arr:[{
		id:1,
		name:'wxml'
	},{
		id:2,
		name:'js'
	},{
		id:3,
		name:'wxss'
	},{
		id:4,
		name:'json'
	}]
},

好吧,现在又回到“解放前”。
不过有了上面的经验,我们知道:这是key不到位的缘故;
但现在数据项变成了一个一个的对象了,还能和以前一样吗?

是的。但是我们的数据中已经有了“唯一性表示” —— id了,又何必“舍近求远”呢?

//wxml
<block wx:for="{{arr}}" wx:for-item="data" wx:key="{{id}}">
	<view><checkbox />{{data}}</view>
</block>
<button bindtap="sort">随机排序</button>

15

### 关于微信小程序中 `:last-child` 和 `:nth-last-child` 的报错解决方案 在微信小程序开发过程中,`:last-child` 和 `:nth-last-child` 是常见的 CSS 伪类选择器。然而,在某些情况下可能会遇到这些选择器无法正常工作的现象。 #### 原因分析 1. **WXSS 对标准 CSS 支持有限** 尽管 WXSS 类似于 CSS,但它并非完全支持所有的 CSS 特性。部分现代 CSS 伪类可能未被全面兼容[^1]。 2. **父级容器的子元素数量不足** 如果目标元素不是其父节点下的最后一个子元素,则 `:last-child` 不会生效。同样地,如果指定的索引超出了实际存在的子元素范围,`:nth-last-child(n)` 也会失效[^2]。 3. **样式冲突或优先级问题** 当存在多个样式规则作用在同一组元素上时,可能导致预期的选择器未能正确应用。 --- #### 解决方案 ##### 方法一:确认父子关系并调整 HTML 结构 确保目标元素确实是其父节点下符合条件的最后一项子元素。例如: ```html <view class="parent"> <view class="child">Child 1</view> <view class="child">Child 2</view> <!-- 这里是最后的一个 child --> </view> ``` 对应的 WXSS 需要如下书写: ```css .parent .child:last-child { color: red; /* 应用于最后一个 child */ } ``` 注意:如果 `.child` 并非直接位于 `.parent` 下或者有其他兄弟标签干扰,则需重新审视 DOM 层次结构。 ##### 方法二:替换为更通用的选择方式 当发现特定伪类不适用时,可以考虑通过类名手动标记需要特殊样式的元素。比如给最后一个子元素单独加一个专属类名为 `last-item`: ```html <view class="parent"> <view class="child">Child 1</view> <view class="child last-item">Child 2 (Last)</view> </view> ``` 相应修改样式表: ```css .last-item { font-weight: bold; } ``` 这种方法虽然牺牲了一定程度上的自动化能力,但在复杂场景下更加可靠稳定[^3]。 ##### 方法三:动态绑定数据控制显示逻辑 利用 WXML 数据绑定功能来自定义渲染行为也是一种有效手段。假设我们有一个数组代表列表项内容,那么可以在 JavaScript 中预先计算好哪些条目应该附加额外属性再传入模板层处理。 示例代码片段如下所示: ```javascript Page({ data: { items: ['Item A', 'Item B'], }, }); ``` 配合条件渲染语句完成最终效果呈现: ```wxml <block wx:for="{{items}}" wx:key="index"> <view class="item {{ index === items.length - 1 ? 'highlight' : '' }}"> {{ item }} </view> </block> ``` 关联样式声明: ```css .highlight { background-color: yellow; } ``` 这样即使底层框架本身存在问题也能绕过限制达成目的。 --- ### 总结 针对微信小程序内的 `:last-child` 或者 `:nth-last-child` 出现异常的情况,可以通过验证HTML层级准确性、采用替代策略以及借助前端编程技巧等多种途径加以应对。具体采取哪种方法取决于项目的实际情况和个人偏好等因素决定。
评论 50
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

恪愚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值