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

相关推荐
回忆哆啦没有A梦5 小时前
Vue页面回退刷新问题解决方案:利用pageshow事件实现缓存页面数据重置
前端·vue.js·缓存
A_ugust__6 小时前
vue3+ts 封装跟随弹框组件,支持多种模式【多选,分组,tab等】
前端·javascript·vue.js
林九生6 小时前
【Vue3】v-dialog 中使用 execCommand(‘copy‘) 复制文本失效的原因与解决方案
前端·javascript·vue.js
yi碗汤园6 小时前
【一文了解】C#的StringSplitOptions枚举
开发语言·前端·c#
cxr8288 小时前
BMAD框架实践:掌握story-checklist提升用户故事质量
前端·人工智能·agi·智能体·ai赋能
emma羊羊8 小时前
【xsslabs】第12-19关
前端·javascript·靶场·xss
真的想不出名儿11 小时前
vue项目引入字体
前端·javascript·vue.js
胡楚昊11 小时前
Polar WEB(1-20)
前端
吃饺子不吃馅11 小时前
AntV X6图编辑器如何实现切换主题
前端·svg·图形学