v-show?和?v-if?的區(qū)別及使用場景分析
v-show 和 v-if 的區(qū)別及使用場景
一、v-show 與 v-if 的共同點(diǎn)
兩者都能控制元素在頁面中的顯示與隱藏(不包括 v-else 情況),且用法相同:
<Model v-show="isShow" /> <Model v-if="isShow" />
當(dāng)表達(dá)式為 true 時,元素都會占據(jù)頁面位置;為 false 時,都不會占據(jù)位置。
二、v-show 與 v-if 的區(qū)別
v-show 和 v-if 的區(qū)別核心區(qū)別
| 特性 | v-if | v-show |
|---|---|---|
| 渲染機(jī)制 | 條件為真時渲染元素,否則銷毀 | 始終渲染元素,通過 CSS 控制顯示 |
| DOM 操作 | 動態(tài)添加/移除 DOM 元素 | 僅切換 display: none 樣式 |
| 初始開銷 | 低(條件為假時不渲染) | 高(無論條件如何都渲染) |
| 切換開銷 | 高(涉及組件銷毀/重建) | 低(僅修改 CSS 屬性) |
| 組件生命周期 | 觸發(fā) created/mounted 等鉤子函數(shù) | 不觸發(fā)生命周期鉤子(始終存在) |
| 組合使用 | 支持 v-else-if 和 v-else | 無邏輯分支語法 |
- 控制方式不同
- v-show 通過添加 CSS
display: none隱藏元素,DOM 元素依然存在 - v-if 會直接添加或刪除整個 DOM 元素
- v-show 通過添加 CSS
- 編譯過程不同
- v-if 有局部編譯/卸載過程,會銷毀和重建內(nèi)部事件監(jiān)聽及子組件
- v-show 僅進(jìn)行簡單的 CSS 切換
- 生命周期影響
- v-show 狀態(tài)變化不會觸發(fā)組件生命周期
- v-if 從 false 變?yōu)?true 會觸發(fā) beforeCreate、created、beforeMount、mounted 鉤子;從 true 變?yōu)?false 會觸發(fā) beforeDestroy、destroyed
- 性能消耗
- v-if 切換開銷更大
- v-show 初始渲染開銷更大
三、實(shí)現(xiàn)原理分析
v-show 原理
無論初始條件如何,元素都會被渲染。其實(shí)現(xiàn)邏輯:
- 有 transition 時執(zhí)行 transition 動畫
- 無 transition 時直接設(shè)置 display 屬性
// Vue 3 的 v-show 指令實(shí)現(xiàn)
export const vShow: ObjectDirective<VShowElement> = {
// 在元素掛載到 DOM 之前執(zhí)行
beforeMount(el, { value }, { transition }) {
// 保存元素的原始 display 值,用于后續(xù)恢復(fù)
// 如果當(dāng)前是隱藏狀態(tài)(display: none),則保存空字符串
// 否則保存當(dāng)前的 display 值
el._vod = el.style.display === 'none' ? '' : el.style.display
// 如果存在過渡動畫且值為真(顯示元素)
if (transition && value) {
// 執(zhí)行過渡動畫的進(jìn)入前鉤子
transition.beforeEnter(el)
} else {
// 否則直接設(shè)置元素的顯示狀態(tài)
setDisplay(el, value)
}
},
// ...其他生命周期處理(如 mounted, beforeUpdate, updated, beforeUnmount 等)
}v-if 原理
實(shí)現(xiàn)更為復(fù)雜,根據(jù)表達(dá)式值決定是否生成 DOM:
// Vue 3 的 v-if 指令轉(zhuǎn)換器
export const transformIf = createStructuralDirectiveTransform(
// 匹配 v-if、v-else、v-else-if 指令的正則表達(dá)式
/^(if|else|else-if)$/,
// 轉(zhuǎn)換函數(shù),處理?xiàng)l件指令的 AST 節(jié)點(diǎn)
(node, dir, context) => {
// 調(diào)用 processIf 函數(shù)處理?xiàng)l件分支邏輯
return processIf(node, dir, context, (ifNode, branch, isRoot) => {
// 條件分支處理邏輯
// ifNode: 當(dāng)前處理的 if 節(jié)點(diǎn)
// branch: 當(dāng)前分支(if/else-if/else)
// isRoot: 是否為根節(jié)點(diǎn)
})
}
)四、使用場景建議
- 頻繁切換場景 推薦使用 v-show
適用于需要快速響應(yīng)的交互元素:
- Tab 切換內(nèi)容
- 下拉菜單/折疊面板
- 頻繁開閉的 Modal 彈窗
- 靜態(tài)條件場景 推薦使用 v-if
適用于內(nèi)容較重且不常變更的情況:
- 根據(jù)用戶角色/權(quán)限加載的初始頁面模塊
- 登錄狀態(tài)相關(guān)的按鈕/導(dǎo)航欄切換
- 大數(shù)據(jù)列表/圖表等按需加載的組件
到此這篇關(guān)于v-show 和 v-if 的區(qū)別及使用場景的文章就介紹到這了,更多相關(guān)v-show 和 v-if 區(qū)別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue實(shí)現(xiàn)input文本框只能輸入0-99的正整數(shù)問題
這篇文章主要介紹了vue實(shí)現(xiàn)input文本框只能輸入0-99的正整數(shù)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10
Vuex中g(shù)etters和actions的使用補(bǔ)充說明
這篇文章主要介紹了在Vuex中關(guān)于getters和actions使用的補(bǔ)充作了簡要說明,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2021-09-09
vuex項(xiàng)目中登錄狀態(tài)管理的實(shí)踐過程
由于狀態(tài)零散地分布在許多組件和組件之間的交互中,大型應(yīng)用復(fù)雜度也經(jīng)常逐漸增長,為了解決這個問題,Vue 提供 vuex,這篇文章主要給大家介紹了關(guān)于vuex項(xiàng)目中登錄狀態(tài)管理的相關(guān)資料,需要的朋友可以參考下2021-09-09
vue使用elementui的el-menu的折疊菜單collapse示例詳解
這篇文章主要介紹了vue使用elementui的el-menu的折疊菜單collapse示例詳解,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-12-12
vue組件實(shí)現(xiàn)列表自動無限循環(huán)的方法
最近剛好有個功能需要實(shí)現(xiàn)列表的無限循環(huán)滾動,這篇文章主要給大家介紹了關(guān)于vue組件實(shí)現(xiàn)列表自動無限循環(huán)的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-11-11
結(jié)合Vue控制字符和字節(jié)的顯示個數(shù)的示例
這篇文章主要介紹了結(jié)合Vue控制字符和字節(jié)的顯示個數(shù)的示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-05-05
vue計算屬性無法監(jiān)聽到數(shù)組內(nèi)部變化的解決方案
今天小編就為大家分享一篇vue計算屬性無法監(jiān)聽到數(shù)組內(nèi)部變化的解決方案,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-11-11
詳解在Vue中使用TypeScript的一些思考(實(shí)踐)
這篇文章主要介紹了詳解在Vue中使用TypeScript的一些思考(實(shí)踐),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07

