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 辅助生成,并由作者整理审核。

相关推荐
bugcome_com1 小时前
JWT 知识小课堂:从入门到精通,一文吃透 JSON Web Token
前端·json
To_OC2 小时前
写了三天 Next.js,我的 React 世界观被拆了又装回去
前端·全栈·next.js
独泪了无痕2 小时前
viewer.js 安装与配置指南:实现图片预览功能
前端·vue.js
Fluxart.ai4 小时前
电商商品图审核怎么自动化?规则引擎、人工复核与发布门禁
java·前端·自动化
why技术4 小时前
AI 写的文章,可能都带着手敲一遍都去不掉的“隐形水印”。
前端·人工智能·后端
愚公搬代码5 小时前
【愚公系列】《Android应用案例开发大全》016-LBS类应用掌上杭州(辅助工具类的开发)
android·前端
CodeSheep5 小时前
又一个华为天才少年,离职了!
前端·后端·程序员
kyriewen5 小时前
面试官说"打开你的AI工具"——我才发现,他考的根本不是写代码
前端·人工智能·面试
IT_陈寒6 小时前
Vue的双向绑定把我坑惨了,原来这个场景不能用
前端·人工智能·后端
hunterandroid7 小时前
[Android 从零到一] Compose LazyColumn 性能优化:key、稳定性与重组治理
android·前端