Vue 中 v-show 与 v-if 的全面解析

一、概念

在 Vue 中,v-showv-if 都能控制元素在页面上的显示与隐藏。

它们在语法层面几乎一致:

ini 复制代码
<Model v-show="isShow" />
<Model v-if="isShow" />

当表达式为 true 时,元素可见;为 false 时,元素不可见。

表面上效果相同,但它们在实现原理、性能消耗、触发生命周期等方面却有显著差异。


二、共同点

  1. 作用效果相同:都能控制元素是否显示在页面中。
  2. 语法用法相同:都接收一个布尔值或表达式。

三、区别解析

1. 控制手段不同

  • v-show :通过设置 display: none 隐藏元素,DOM 节点依旧存在。
  • v-if :根据条件真正地 创建或销毁 DOM 节点

2. 编译过程不同

  • v-show:只做样式切换,逻辑简单,不涉及编译卸载。
  • v-if:有完整的编译/卸载过程,会销毁和重建子组件与事件监听。

3. 生命周期触发

  • v-show :切换时 不会触发生命周期钩子
  • v-if :从 false → true 会触发 beforeCreate → created → beforeMount → mounted
    true → false 会触发 beforeDestroy → destroyed

4. 性能消耗

  • v-show:初始渲染开销大(始终渲染),切换开销小(仅改 CSS)。
  • v-if:初始渲染开销小(按条件渲染),切换开销大(频繁销毁/重建 DOM)。

四、底层原理

v-show 原理

源码位置:runtime-dom/src/directives/vShow.ts

简化逻辑如下:

javascript 复制代码
export const vShow = {
  beforeMount(el, { value }) {
    // 保存原始 display 值
    el._vod = el.style.display === 'none' ? '' : el.style.display
    setDisplay(el, value) // 根据表达式控制 display
  },
  updated(el, { value }) {
    setDisplay(el, value)
  }
}

👉 总结:无论条件真假,元素始终渲染,只是通过 display 控制显示与否


v-if 原理

源码位置:compiler-core/src/transforms/vIf.ts

简化逻辑如下:

javascript 复制代码
export const transformIf = createStructuralDirectiveTransform(
  /^(if|else|else-if)$/,
  (node, dir, context) => {
    return processIf(node, dir, context, (ifNode, branch, isRoot) => {
      return () => {
        if (isRoot) {
          ifNode.codegenNode = createCodegenNodeForBranch(branch, key, context)
        } else {
          // else/else-if 附加到 v-if 根节点
          const parentCondition = getParentCondition(ifNode.codegenNode!)
          parentCondition.alternate = createCodegenNodeForBranch(branch, key, context)
        }
      }
    })
  }
)

👉 总结:通过 AST 转换生成不同的分支节点,真正决定是否生成 DOM


五、使用场景

  • 适合用 v-show

    • 需要频繁切换的场景(如 Tab 页切换、折叠面板)。
  • 适合用 v-if

    • 条件很少变化的场景(如按权限渲染按钮、初始化渲染大块组件)。

六、对比总结表

特性 v-show v-if
控制手段 CSS display:none DOM 节点增删
编译过程 简单,无编译卸载 有编译/卸载,重建子组件
生命周期触发 不触发 会触发创建/销毁钩子
性能特点 初始渲染耗时,切换高效 初始快,频繁切换性能差
适用场景 高频切换 条件偶尔变化

七、记忆口诀

"常切换用 v-show,偶尔显示用 v-if"

------一句话总结性能差异与使用场景。


八、拓展思考

  • 过渡动画

    • v-if 可结合 <transition> 在 DOM 创建/销毁时触发进出动画。
    • v-show 只会控制 display,动画需结合 CSS transition 实现。
  • SSR(服务端渲染)差异

    • v-if 在服务端能减少不必要的 DOM 节点输出。
    • v-show SSR 输出时仍会包含该节点,只是隐藏。
  • 组合使用

    有时可结合使用,比如外层用 v-if 控制大范围渲染,内层用 v-show 控制局部切换。


九、潜在问题

  1. 误用 v-show:可能导致页面存在过多隐藏 DOM,影响内存占用。
  2. 误用 v-if:在高频切换场景下导致性能瓶颈(频繁重建 DOM)。
  3. 误解生命周期:开发者常误以为 v-show 也会触发生命周期,实际并不会。

十、结语

v-showv-if 虽然看似类似,但本质上是 "样式切换" vs "结构渲染" 的区别。合理选择它们能让项目性能与体验更优。

👉 记住一句话:
"频繁切换用 v-show,条件变化用 v-if"。


本文部分内容借助 AI 辅助生成,并由作者整理审核。

相关推荐
全栈前端老曹7 分钟前
【ReactNative】核心组件与 JSX 语法
前端·javascript·react native·react.js·跨平台·jsx·移动端开发
用户542778485154015 分钟前
JavaScript 闭包详解:由浅入深掌握作用域与内存管理的艺术
前端
小小黑00715 分钟前
快手小程序-实现插屏广告的功能
前端·javascript·小程序
用户542778485154016 分钟前
闭包在 Vue 项目中的应用
前端
TG:@yunlaoda360 云老大19 分钟前
配置华为云国际站代理商OBS跨区域复制时,如何编辑委托信任策略?
java·前端·华为云
dlhto42 分钟前
前端登录验证码组件
前端
@万里挑一44 分钟前
vue中使用虚拟列表,封装虚拟列表
前端·javascript·vue.js
黑臂麒麟1 小时前
Electron for OpenHarmony 跨平台实战开发:Electron 文件系统操作实战
前端·javascript·electron·openharmony
wordbaby1 小时前
Tanstack Router 文件命名速查表
前端
1024肥宅1 小时前
工程化工具类:模块化系统全解析与实践
前端·javascript·面试