微信小程序屬性剖析:wx-key就這麼重要嗎?

今天,就想和各位說說微信小程序中的【臂膀】——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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章