今天我們進入「條件渲染」的章節囉~
將分為兩部分講解:
v-if
、v-else-if
、v-else
v-show
OK,請開始我的表演。
Vue 的條件渲染提供了「v-if
、v-else-if
、v-else
、v-show
」語法,我們可以利用它實現「動態決定網頁上要顯示哪一部分內容」。
邏輯概念和 JS 判斷式相同:
v-if
區塊並渲染對應的內容。v-if
條件不成立,則會檢查 v-else-if
區塊(如果有的話),並根據條件渲染對應內容。v-else
區塊並渲染其內容。可以這樣理解:
<div v-if="conditionA">區塊一</div>
<div v-else-if="conditionB">區塊二</div>
<div v-else>區塊三</div>
if (conditionA) {
渲染區塊一
} else if (conditionB) {
渲染區塊二
} else {
渲染區塊三
}
渲染條件基於 ""
中的表達式是否成立(return true)。
v-if="表達式"
條件成立,該區塊會被渲染,反之不會(或進入下個條件判斷)。
v-else="表達式"
當 v-if
和 v-else-if
(若有) 的條件都不成立時,會渲染 v-else
區塊。
特點:不能單獨存在,必須緊跟在 v-if
或 v-else-if
之後。
v-else-if="表達式"
當 v-if
的條件不成立時,會渲染 v-else-if
。
特點:
v-if
之後。v-if
和 v-else
。我們可以用一些範例來更認識它們!
定義兩個 <h3>
,使用 v-if
語法,分別綁定真值/假值。
<script setup>
import { ref } from "vue";
const cute = ref(true);
const naughty = ref(false);
</script>
<template>
<h3 v-if="cute">Sprouts is CUTE!</h3>
<h3 v-if="naughty">Sprouts is NAUGHTY!</h3>
</template>
cute
為 true
,因此 <h3 v-if="cute">Sprouts is CUTE!</h3>
區塊會被渲染。
瀏覽器會呈現:
定義一個按鈕,點擊了會更改 v-if
為反值(就不渲染),因而渲染 v-else
區塊。
<script setup>
import { ref } from "vue";
const cute = ref(true);
const changeMind = function () {
cute.value = !cute.value;
};
</script>
<template>
<img v-if="cute" src="./cute.png" />
<img v-else src="./naughty.png" />
<h3 v-if="cute">Sprouts is CUTE!</h3>
<h3 v-else>Sprouts is NAUGHTY!</h3>
<button @click="changeMind">改變心意鈕</button>
</template>
button
綁定了click
事件,點擊按鈕後會觸發 changeMind
函式,將 cute
響應式狀態的值改為相反,true
變為 false
,因此v-else
的區塊會被渲染。
瀏覽器會呈現:
注意必須緊鄰在 v-if
區塊後。
增加 v-else-if
區塊試試看!
<script setup>
import { ref } from "vue";
const howSproutsIs = ref("cute");
</script>
<template>
<h3 v-if="howSproutsIs === 'cute'">Sprouts is CUTE!</h3>
<h3 v-else-if="howSproutsIs === 'quiet'">Sprouts is QUIET!</h3>
<h3 v-else-if="howSproutsIs === 'lazy'">Sprouts is LAZY!</h3>
<h3 v-else>Sprouts is NAUGHTY!</h3>
</template>
在此,我們將 v-if
和 v-else-if
更改為了表達式,而 howSproutsIs
響應式綁定了 "cute"
,因此在 v-if
區塊的條件成立(就不進入接下來的條件了),預設會顯示 Sprouts is CUTE!
。
以上程式碼也可以想成這樣:
if(howSproutsIs === 'cute') {
渲染 Sprouts is CUTE!
} else if (howSproutsIs === 'quiet') {
渲染 Sprouts is QUIET!
} else if (howSproutsIs === 'lazy') {
渲染 Sprouts is LAZY!
} else {
渲染 Sprouts is NAUGHTY!
}
因此如果我們更改 howSproutsIs
的值,又會重新進入條件判斷。
觀察渲染的結果:
我們再把 貓咪系統 完善一下 XD
在 changeMind
函式中添加一些邏輯,讓點選按鈕後可以做到更多切換:
<script setup>
import { ref } from "vue";
const howSproutsIs = ref("cute");
const changeMind = function () {
// 根據目前的狀態來改變 Sprouts 的狀態
if (howSproutsIs.value === "cute") {
howSproutsIs.value = "quiet";
} else if (howSproutsIs.value === "quiet") {
howSproutsIs.value = "lazy";
} else if (howSproutsIs.value === "lazy") {
howSproutsIs.value = "naughty";
} else {
howSproutsIs.value = "cute";
}
};
</script>
<template>
<img v-if="howSproutsIs === 'cute'" src="./cute.png" />
<img v-else-if="howSproutsIs === 'quiet'" src="./quiet.png" />
<img v-else-if="howSproutsIs === 'lazy'" src="./lazy.png" />
<img v-else src="./naughty.png" />
<h3 v-if="howSproutsIs === 'cute'">Sprouts is CUTE!</h3>
<h3 v-else-if="howSproutsIs === 'quiet'">Sprouts is QUIET!</h3>
<h3 v-else-if="howSproutsIs === 'lazy'">Sprouts is LAZY!</h3>
<h3 v-else>Sprouts is NAUGHTY!</h3>
<button @click="changeMind">改變心意鈕</button>
</template>
和以上範例是同樣的概念,渲染的條件取決於綁定之表達式的真/假值。
瀏覽器上將會呈現:
v-if
可以直接用來控制是否渲染 <template>
。
在 <template>
中若有多個區塊需要被渲染/不被渲染,可以這麼寫:
<template>
<template v-if="conditionA">
<div>區塊一</div>
<div>區塊二</div>
<div>區塊三</div>
</template>
<template v-else-if="conditionA">
<div>區塊一</div>
<div>區塊二</div>
<div>區塊三</div>
</template>
<template v-else>
<div>區塊一</div>
<div>區塊二</div>
<div>區塊三</div>
</template>
</template>
渲染條件基於 ""
中的表達式是否成立(return true)。
v-show="表達式"
特點:
display
屬性,表達式 return false
時,切換為 none
。v-else
一起使用。<template>
元素上使用。定義兩個 <h3>
,使用 v-if
語法,分別綁定真值/假值。
<script setup>
import { ref } from "vue";
const cute = ref(true);
const naughty = ref(false);
</script>
<template>
<h3 v-show="cute">Sprouts is CUTE!</h3>
<h3 v-show="naughty">Sprouts is NAUGHTY!</h3>
</template>
cute
為 true
,因此 <h3 v-if="cute">Sprouts is CUTE!</h3>
區塊會被渲染。
瀏覽器會呈現:
可以注意到:綁定 naughty
的區塊,display
為 none
。
因此:元素在初始渲染時皆會被加入到 DOM 中,即使它的顯示狀態是 none
。
實際感受一下,元素綁定真/假值時,影響 display
切換的渲染行為:
官方文件:
v-if 是“真實的”按條件渲染,因為它確保了在切換時,條件區塊內的事件監聽器和子組件都會被銷毀與重建。v-if 也是惰性的:如果在初次渲染時條件值為 false,則不會做任何事。條件區塊只有當條件首次變為 true 時才被渲染。
相比之下,v-show 簡單許多,元素無論初始條件如何,始終會被渲染,只有 CSS display 屬性會被切換。
總的來說,v-if 有更高的切換開銷,而 v-show 有更高的初始渲染開銷。因此,如果需要頻繁切換,則使用 v-show 較好;如果在運行時綁定條件很少改變,則 v-if 會更合適。
我們整理一下兩者區別:
特性 | v-if | v-show |
---|---|---|
行為 | 切換時會銷毀/重建元素 | 始終渲染元素,只切換 display 屬性 |
初次渲染 | 條件為 true 才渲染 |
元素始終渲染 |
切換開銷 | 較高 | 較低 |
初始渲染開銷 | 較低 | 較高 |
適用情景 | 條件變動少、不頻繁切換的 | 條件變動多、頻繁切換的 |
官方文件這邊說不推薦兩者同時使用,因為同時存在時,v-if
會首先被執行。
(淺淺帶過⋯⋯明天我們就會講到 v-for
囉)
雖然 GPT 有點胡言亂語,但我學這章的時候真的蠻開心的:)
(開心就好)
明天~~我們來看列表渲染拉!
https://github.com/Jamixcs/2024iThome-jamixcs/tree/main/src/components/day19