這是我參與8月更文挑戰的第4天,活動詳情查看:8月更文挑戰javascript
這篇文章咱們來說一下key
、ref
以及v-for
怎麼去使用,使用它們的時候須要注意什麼,以及它們配合使用的時候在Vue3與Vue2中的差別。html
官方說,key
特殊 attribute 主要用作 Vue 的虛擬 DOM 算法的提示,以在比對新舊節點組時辨識 VNodes。若是不使用 key,Vue 會使用一種算法來最小化元素的移動而且儘量嘗試就地修改/複用相同類型元素。而使用 key 時,它會基於 key 的順序變化從新排列元素,而且 key 再也不存在的元素將始終被移除/銷燬。vue
根據上述說法,咱們看一個例子加深理解,以下:java
數據算法
const kings = ref(["程咬金", "安琪拉", "羋月", "呂布", "李信"])
複製代碼
渲染結果用ol、li元素渲染express
<ol>
<li>程咬金</li> //標記1
<li>安琪拉</li> //標記2
<li>羋月</li> //標記3
<li>呂布</li> //標記4
<li>李信</li> //標記5
</ol>
複製代碼
當數據發生變化時,數據爲數組
kings.value=["程咬金", "羋月", "呂布", "安琪拉", "李信"]
複製代碼
無key渲染結果markdown
<ol>
<li>程咬金</li> //標記1
<li>羋月</li> //標記2
<li>呂布</li> //標記3
<li>安琪拉</li> //標記4
<li>李信</li> //標記5
</ol>
複製代碼
有key渲染結果app
<ol>
<li>程咬金</li> //標記1
<li>羋月</li> //新標記2
<li>呂布</li> //新標記3
<li>安琪拉</li> //新標記4
<li>李信</li> //標記5
</ol>
複製代碼
從上述例子咱們能夠看出,當數據發生變化時,無key優先複用存在的相同類型的元素,只改變元素的屬性和內容;而有key則會從新排序,key不存在的會被銷燬。函數
在key的使用中,咱們須要注意是:
key
咱們在v-for中使用居多,可是咱們也能夠用在其餘元素或者組件上:這樣是爲了觸發過渡,讓其被替換而不是被修改。好比下面span
的寫法,咱們想觸發它的過渡效果,能夠給它加上key
。<span :key="text">{{ text }}</span>
複製代碼
ref
被用來給元素或子組件註冊引用信息。引用信息將會被註冊在父組件的 $refs
對象上。若是在普通的 DOM 元素上使用,引用指向的就是那個 DOM 元素;若是用在子組件上,引用就指向組件實例。
簡而言之,就是給一個marker
,讓你能夠快速的找到這個元素或組件,值得注意的是ref
綁定的時候能夠給字符串或者是表達式
。
基於源數據屢次渲染元素或模板塊。此指令之值,必須使用特定語法 alias in expression
,爲當前遍歷的元素提供別名。
以上述數據爲例,寫法以下:
<ol>
<li v-for="king in kings">{{king}}</li>
</ol>
複製代碼
在這裏咱們不只講它們三個之間的配合使用,還要講它們配合使用的時候在Vue3與Vue2中的差別。
在指令介紹中,咱們講述了v-for
與key
的配合使用,在這裏咱們來說一下它們配合使用時的另外一種狀況(v-for
做用在 template
)。
v-for
做用在 template
上時,key
在Vue2與Vue3的使用方式是不同的。以下:
//Vue2
<template v-for="king in kings">
<h1 :key="king">{{king}}</h1>
</template>
//Vue3
<template v-for="king in kings" :key="king">
<h1>{{king}}</h1>
</template>
複製代碼
下面咱們來用兩個例子說明一下它們之間的配合使用,數據用kings=["程咬金", "安琪拉", "羋月", "呂布", "李信"]
:
第一個例子 ref="li"
<ol>
<li v-for="king in kings" :key="king" ref="li">{{king}}</li>
</ol>
複製代碼
在咱們使用$refs.li
來獲取標記元素時,在Vue2中咱們能夠獲得一個數組,然而,在Vue3中咱們僅僅獲得知足這個條件的最後一個元素,即:
<li>李信</li>
複製代碼
第二個例子 :ref="'li'+king"
和 :ref="setItemRef"
若是咱們在Vue3中想要獲取全部標記元素,咱們能夠作如下操做:
<ol>
<li v-for="king in kings" :key="king" :ref="'li'+king">{{king}}</li>
</ol>
複製代碼
這樣咱們在使用$refs
是能夠得到全部標記元素:
Proxy {li程咬金: li, li安琪拉: li, li羋月: li, li呂布: li, li李信: li}
複製代碼
或者咱們也能夠這樣作:
<div id="app">
<ol>
<li v-for="king in kings" :key="king" :ref="setItemRef">{{king}}</li>
</ol>
</div>
<script src="./vue.global.js"></script>
<script> const { createApp, ref } = Vue const app = createApp({ setup() { const kings = ref(["程咬金", "安琪拉", "羋月", "呂布", "李信"]) let itemRefs = [] // 存放元素變量,想操做元素的時候,能夠今後變量裏面拿值 const setItemRef = el => { if (el) { itemRefs.push(el) } } return { kings, setItemRef } } }) app.mount("#app") </script>
複製代碼
Vue3 中 v-if
老是優先於 v-for
生效,雖然不建議在同一元素上同時使用二者。
在Vue3中,ref="li"
這種寫法將再也不在 $ref
中自動建立數組。要從單個綁定獲取多個 ref,請將 ref
綁定到一個更靈活的函數上。
v-for
做用在template
上的狀況,Vue2中 key
要放在其包裹的元素上,Vue3中key
要放在template
元素上。