前端八股Vue(5)---v-if和v-show

目录


一、核心区别速览

对比维度 v-if v-show
控制方式 真正的条件渲染 CSS 切换 display: none
DOM 存在性 条件为假时 DOM 不存在 DOM 始终存在
初始渲染 条件为假时不渲染 条件为假时渲染但隐藏
切换开销 高(销毁/重建 DOM) 低(只切换 CSS)
初始开销 低(条件假时不渲染) 高(总是渲染)
支持 template ✅ 支持 ❌ 不支持
支持 v-else ✅ 支持 ❌ 不支持
适用场景 很少切换 频繁切换

二、图解区别

v-if:真正的条件渲染

复制代码
条件 = true                    条件 = false

┌─────────────┐               ┌─────────────┐
│             │               │             │
│   DOM 存在   │               │   DOM 不存在 │
│   显示内容   │               │   (被移除)   │
│             │               │             │
└─────────────┘               └─────────────┘

条件 false → true:创建 DOM
条件 true → false:销毁 DOM

v-show:CSS 切换

复制代码
条件 = true                    条件 = false

┌─────────────┐               ┌─────────────┐
│             │               │  display:   │
│   DOM 存在   │               │   none      │
│   显示内容   │               │  (隐藏但存在)│
│             │               │             │
└─────────────┘               └─────────────┘

条件 false → true:display: none → display: 原值
条件 true → false:display: 原值 → display: none
DOM 始终存在,只是隐藏/显示

三、代码演示

v-if 示例

javascript 复制代码
<template>
  <div>
    <!-- 条件为 true 时才渲染 -->
    <div v-if="isVisible">
      <p>这个元素只在 isVisible = true 时才存在</p>
    </div>
    
    <!-- ✅ 支持 template(批量渲染) -->
    <template v-if="isLoggedIn">
      <h2>欢迎回来</h2>
      <p>用户名:{{ username }}</p>
    </template>
    
    <!-- ✅ 支持 v-else-if 和 v-else -->
    <div v-if="status === 'success'">成功</div>
    <div v-else-if="status === 'loading'">加载中</div>
    <div v-else>失败</div>
  </div>
</template>

v-show 示例

javascript 复制代码
<template>
  <div>
    <!-- 条件为 false 时,display: none,但 DOM 还在 -->
    <div v-show="isVisible">
      <p>这个元素始终存在,只是通过 CSS 隐藏/显示</p>
    </div>
    
    <!-- ❌ v-show 不支持 template -->
    <template v-show="isLoggedIn">  <!-- 无效! -->
      <h2>欢迎回来</h2>
    </template>
    
    <!-- ❌ v-show 不支持 v-else -->
    <div v-show="status === 'success'">成功</div>
    <div v-else>失败</div>  <!-- 不生效! -->
  </div>
</template>

四、性能对比详解

场景 v-if v-show
初始渲染(条件为假) ✅ 不渲染,快 ❌ 渲染但隐藏,慢
切换(假→真) ❌ 创建 DOM,慢 ✅ 改 display,快
切换(真→假) ❌ 销毁 DOM,慢 ✅ 改 display,快
频繁切换 ❌ 不推荐 ✅ 推荐
很少切换 ✅ 推荐 ⚠️ 初始开销大

五、实际场景选择

场景1:频繁切换 → 用 v-show

javascript 复制代码
<template>
  <!-- 选项卡/标签页频繁切换 -->
  <div class="tabs">
    <button @click="activeTab = 'tab1'">标签1</button>
    <button @click="activeTab = 'tab2'">标签2</button>
    
    <!-- 频繁切换,用 v-show -->
    <div v-show="activeTab === 'tab1'">内容1</div>
    <div v-show="activeTab === 'tab2'">内容2</div>
  </div>
</template>

场景2:很少切换 → 用 v-if

javascript 复制代码
<template>
  <!-- 用户登录状态(切换很少) -->
  <div v-if="isLoggedIn">
    <UserDashboard />
  </div>
  <div v-else>
    <LoginPage />
  </div>
  
  <!-- 权限控制(页面加载时决定,基本不变) -->
  <AdminPanel v-if="user.isAdmin" />
</template>

场景3:初始可能不显示 → 用 v-if

javascript 复制代码
<template>
  <!-- 弹窗:初始不显示,用 v-if 避免渲染 -->
  <Modal v-if="showModal" @close="showModal = false" />
  
  <!-- 懒加载组件 -->
  <LazyComponent v-if="shouldLoad" />
</template>

六、优先级说明

v-if 的优先级远高于 v-show:

javascript 复制代码
<template>
  <!-- ⚠️ 注意:v-if 优先级高于 v-for -->
  <!-- ❌ 不推荐:v-if 和 v-for 一起用 -->
  <div v-for="item in list" v-if="item.active" :key="item.id">
    {{ item.name }}
  </div>
  
  <!-- ✅ 推荐:用 computed 过滤 -->
  <div v-for="item in activeList" :key="item.id">
    {{ item.name }}
  </div>
</template>

优先级顺序:

复制代码
v-if > v-for > v-show

v-if 和 v-show 不在同一执行阶段,v-if 的条件判断更早执行。


七、源码层面的区别

v-if 的编译结果

javascript 复制代码
// 源码:v-if 会被编译成三元表达式
// <div v-if="show">内容</div>

// 编译后(简化)
show ? renderDiv() : null

v-show 的编译结果

javascript 复制代码
// 源码:v-show 会被编译成样式绑定
// <div v-show="show">内容</div>

// 编译后(简化)
<div style={show ? null : { display: 'none' }}>内容</div>

八、面试高频问题

Q1:v-if 和 v-show 的区别?

答:

  1. 控制方式不同 :v-if 是真正的条件渲染,条件为假时 DOM 不存在;v-show 只是切换 CSS 的 display: none,DOM 始终存在

  2. 性能开销不同:v-if 切换开销高(创建/销毁 DOM),初始开销低;v-show 切换开销低,初始开销高

  3. 功能支持不同 :v-if 支持 template 和 v-else,v-show 不支持

Q2:什么时候用 v-if,什么时候用 v-show?

答:

  • 频繁切换 → 用 v-show,切换成本低

  • 很少切换 → 用 v-if,减少初始渲染开销

  • 初始可能不显示 → 用 v-if,避免渲染无用 DOM

  • 需要配合 v-else → 只能用 v-if

Q3:v-if 和 v-show 能一起用吗?

答:

可以,但没必要。因为 v-if 优先级更高,如果 v-if 条件为假,v-show 根本不会生效(DOM 都不存在)。通常只需要用一个。


  1. v-if 是"真实的"条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建

  2. v-show 是简单的 CSS 切换,适合频繁切换的场景

  3. v-if 也是懒加载的,初始条件为假时,什么也不做,直到条件第一次变为真时才开始渲染

  4. v-if 优先级高于 v-for,不建议一起使用

相关推荐
码艺-Alimjan39 分钟前
Vben Admin 新增维吾尔语 Vben-Modal的关键坑之一
前端·javascript·vue.js
可乐鸡翅yeah_1 小时前
hls.js 手动自定义 http 请求 loader,修改请求头实战
开发语言·前端·javascript·网络协议·http·ecmascript·m3u8在线
IT_陈寒1 小时前
Vite静态资源导入这个坑我帮你们踩过了
前端·人工智能·后端
广州华水科技2 小时前
大坝安全监测解决方案:单北斗GNSS形变监测系统应用与维护
前端
星光开发者2 小时前
基于决策树随机森林算法的小说推荐系统的设计与实现-计算机毕设【课程设计】78485
vue.js·算法·微信小程序·django·php·课程设计·express
yivifu2 小时前
中文古籍电子书注释集成
前端·javascript·python·beautifulsoup·epub
vx_Biye_Design3 小时前
springboot高校选课系统82776-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·spring·课程设计·express
niyongsheng3 小时前
后端零改动,给若依换一套现代化前端
vue.js·开源·node.js
weixin_448290253 小时前
书庐开发实战教学
javascript·css·html
默_笙3 小时前
🛴 从散件到整机:DeepAgents 与 Agent 身上预留的那些"插槽"(前置介绍)
前端·javascript