0%

Vue-v-if和v-show的應用與差別

v-if

這個 directive 的功能是,藉由判斷一個內容,來決定要不要將相對應的內容呈現在網頁上。
如果今天你有兩個以上的元素的 v-if 是要判斷同一個元素的話,官方文件建議你用 template 將這些元素包起來,然後,在這個 template 上用 v-if 統一對同一個內容做判斷
ex:

1
2
<div v-if="isShow">這一個區塊</div>
<span v-if="isShow">這一個span</span>

可以用 template 改寫成

1
2
3
4
<template v-if="isShow">
<div>這一個區塊</div>
<span>這一個span</span>
</template>

以上範例就能統一去判斷 isShow 這個內容,而且 template 這個 tag 也不會出現在 DOM 上面。

v-if 和 key 搭配使用

我們可以用 v-if 和 key 的搭配使用,解決保留上一區塊資料的問題
當你多個區塊使用到 v-if 和 v-else 時,很有可能會發生上一個區塊的資料被保留到下一個區塊中。 會發生這種狀況是因為 Vue 很省資源,如果,你沒有特別的利用 key 來區分區塊間的不同,Vue 會認為這些區塊是同一個人,就會有可能造成上一區塊輸入的資料被保留到下一區塊的狀況,這個時候用 key 來區分它們就解決囉。

1
2
3
4
5
6
7
8
<template v-if="type === 'A'">
<div>A Content</div>
<input type="text">
</template>
<template v-else>
<div>B Content</div>
<input type="text">
</template>

改寫成

1
2
3
4
5
6
7
8
<template v-if="type === 'A'">
<div>A Content</div>
<input type="text" key="aContent"> // 新綁定了一個 key 值
</template>
<template v-else>
<div>B Content</div>
<input type="text">
</template>

我們特別在 A 區塊加入 key=”aContent” ,這樣就能讓 Vue 知道 A, B 區塊是不同人囉。
那你可以看到這邊的 key 不像在搭配 v-for 時的 key 前面需要加冒號 :key, 那是因為在 v-for 的情境下,key 需要綁定資料,所以,才會在前面加冒號。而這邊的話並不是綁定資料,所以,不需要在 key 前面加上冒號。

v-show

功能跟 v-if 差不多,但是,機制不太一樣。 v-show 是將不需要呈現的目標元素的 display 設為 none ,而不是直接將它從 DOM 裡面拔掉。

1
2
3
<div id="app">
<span v-show="isShow">這是一段 span </span>
</div>

v-show 無法搭配 template 使用

這真得很容易在 v-show 誤用喔
v-show 無法搭配 template 使用的原因是 template 不是一個實體的 tag ,但是 v-show 是去改一個實際的元素的 display 樣式,但因為 template 不是實體,所以,v-show 的效果會失效。

Alex 宅幹嘛-眉眉角角

v-if v.s v-show 使用時機

元素經常變換的情境用 v-show

如果某個元素會經常被抽換掉的話,建議不要用 v-if ,因為, v-if 的行為是直接將該元素的 DOM 進行抽換,那如果你頻繁抽換的話,會不太好。
可以考慮用 v-show,因為,v-show 是利用更改目標元素的 css 樣式的 display:none 來決定讓他要不要出現在畫面上。

以上這個範例,假設在用戶會頻繁的變換分頁的內容,那在這種情境下,我們就建議用 v-show 來判斷是否要讓該對應內容呈現在畫面上。就不用像 v-if 那樣頻繁抽換 DOM 的內容。

v-if 和 v-show 一開始的渲染時機

當你 v-if 判斷的值一開始為 false,那 v-if 是不會渲染這個元素的,直到該判斷值轉換成 true。
而 v-show 是不管它的判斷值的初始值是否為 true 或 false,它都一定會被渲染,如果是 false 的話,它就只是將目標元素的 display 改成 none 而已。
以上就是它們倆個一開始的渲染時機的差別。

盡量將程式邏輯部分都交由程式處理

盡可能將判斷的內容歸到到程式那一端,不要都寫在 HTML 中
ex:

1
2
3
4
5
6
7
8
9
10
11
12
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>

以上這個範例就是將判斷的內容寫在 HTML 中,那 Alex 大大是希望將程式邏輯的部分可以的話,就收到程式裡面
所以,進行以下的改寫

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
---HTML---
<div>
{{ content }}
</div>

---JavaScript---
const contentMap = {
A: 'A Content',
B: 'B Content',
C: 'C Content'
}

let vm = new Vue({
el: '#app',
data:{
type: 'A'
},
computed: {
content () {
return contentMap[this.type] || 'No Content'
}
}
})

以上這種改寫,就是將程式邏輯歸到程式中,可以讓你的 HTML 裡面變得比較乾淨,蠻不錯的想法。

將 v-show 改寫成資料驅動

先上範例

<div v-show="show"> Content1 </div> 
<div v-show="!show"> Content2 </div> 

可以改寫成
<div> {{ show ? Content1: Content2}} </div>
以上這種寫法,就是直接透過判斷 show 內容,來決定要在畫面上顯示出什麼樣的內容。