前端八股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-ifv-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 支持 templatev-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,不建议一起使用

相关推荐
yuki_uix2 小时前
跨域与安全:CORS、HTTPS 与浏览器安全机制
前端·面试
用户3153247795452 小时前
React19项目中 FormEdit / FormEditModal 组件封装设计说明
前端·react.js
陆枫Larry2 小时前
Git 合并冲突实战:`git pull` 失败与 `pull.ff=only` 的那些事
前端
江南月2 小时前
让智能体边想边做:从 0 理解 ReActAgent 的工作方式
前端·人工智能
YiuChauvin2 小时前
vue2中使用 AntV G6
javascript·vue.js
袋鱼不重2 小时前
Hermes Agent 安装与实战:从安装到与 OpenClaw 全方位对比
前端·后端·ai编程
汉秋2 小时前
iOS 自定义 UICollectionView 拼图布局 + 布局切换动画实践
前端
江南月2 小时前
让智能体学会自我改进:从 0 理解 ReflectionAgent 的迭代优化
前端·人工智能
尽欢i2 小时前
前端响应式布局新宠:vw 和 clamp (),你了解吗?
前端·css