和
v-if
的差別是什麼?
v-show
v-if
為什麼不能一起用?
v-for
中的
v-for
有什麼作用?
key
1 v-if 和 v-show
1.1 作用
都用來控制元素的顯示和隐藏
1.2 控制元素顯隐的方式
v-if
控制虛拟
DOM
樹上元素的建立和銷毀,
Vue
的響應系統會根據虛拟
DOM
樹對實際
DOM
進行更新,進而間接控制實際
DOM
上元素的顯隐
v-show
通過給元素添加樣式
display:none
來讓元素隐藏
1.3 初始渲染對比
v-if
是惰性的,如果初始渲染條件為
false
,什麼都不做;隻有條件為
true
,才會開始編譯
v-show
不管初始渲染條件如何,元素始終被編譯并保留,之後根據條件通過
CSS
切換
1.4 切換消耗對比
如果頻繁切換顯示與隐藏,
v-if
會頻繁建立、銷毀元素,而
v-show
隻是切換樣式
故
v-if
的切換消耗更高
1.5 使用場景對比
如果元素的顯示隐藏在一開始就定下來不會再變了,使用
v-if
如果元素需要頻繁切換顯隐,使用
v-show
1.6 其他
-
可以搭配v-if
使用,template
不可以v-show
-
v-if
,v-else
無特殊文法v-show
2 v-if 和 v-for
2.1 v-if 和 v-for 不能同時用的原因
為什麼不能把
v-if
v-for
同時用在同一個元素上?
當 Vue 處理指令的時候,
v-for
的優先級比
v-if
高,是以這個模闆:
<ul>
<li v-for="item in list" v-if="item.isActive" :key="item.id">
{{item.name}}
</li>
</ul>
會經過如下運算:
this.list.map(function(item) {
if (item.isActive) {
return item.name
}
})
我們每次重新渲染的時候都要周遊整個清單,即使
isActive
為
true
的
item
很少,這會帶來性能方面的極大浪費,是以兩者不能同時用在同一個元素上
2.2 v-if 和 v-for 一起用的解決方案
1、如果想控制整個清單的顯隐,可以将
v-if
移動到容器元素上,比如:
<body>
<div id="example">
<ul v-if="listShow">
<li v-for="item in activeItems" :key="item.id">{{item.name}}</li>
</ul>
</div>
</body>
<script>
const vm = new Vue({
el: "#example",
data: {
list: [
{ id: 1, name: "路飛", isActive: true },
{ id: 2, name: "索隆", isActive: false },
{ id: 3, name: "山治", isActive: true },
],
listShow: false,
}
});
</script>
2、如果想過濾清單中的項目,可以使用計算屬性(
computed
)傳回過濾後的清單,比如:
<body>
<div id="example">
<ul>
<li v-for="item in activeItems" :key="item.id">{{item.name}}</li>
</ul>
</div>
</body>
<script>
const vm = new Vue({
el: "#example",
data: {
list: [
{ id: 1, name: "路飛", isActive: true },
{ id: 2, name: "索隆", isActive: false },
{ id: 3, name: "山治", isActive: true },
],
},
computed: {
activeItems: function () {
return this.list.filter((item) => item.isActive);
},
},
});
</script>
3 清單渲染的 key 有什麼用
在使用
v-for
進行清單渲染時,必須給元素添加一個
key
屬性,并且這個
key
必須是唯一辨別
<ul>
<li v-for="item in list" :key="item.id">{{item.name}}</li>
</ul>
我們知道,Vue 在更新元素時,不會直接操作真實DOM(渲染真實DOM開銷是很大的),而是根據新資料生成新的虛拟 DOM,然後對新舊虛拟DOM進行差異對比,根據對比結果進行DOM操作來更新視圖
清單渲染時,如果有
key
屬性,由于它是唯一辨別,在對比兩個新舊節點時若
key
不同也就沒有深入對比的必要了。
為什麼不能用
index
作為
key
?因為
index
是不穩定可變的,比如删除了清單第一個元素,會導緻後面的元素
index
發生變化,進而導緻
key
發生變化。這時,Vue 在對比新舊節點時,遇到
key
相同的節點,就會進行深入對比,發現節點内容發生了變化,就會去建立新的真實DOM用來替換原來的真實DOM。原本隻需要删除真實DOM中第一個元素的操作,會變成建立、替換後續所有真實DOM,造成性能的極大浪費