v-if 与 v-show 区别
2026/6/15 13:37:51 网站建设 项目流程

文章目录

  • 前言
  • 一、v-if 条件渲染
    • 1.1 定义
    • 1.2 分支语法
    • 1.3 生命周期影响
  • 二、v-show 显示隐藏
    • 2.1 定义
    • 2.2 不支持的场景
  • 三、核心区别
    • 3.1 机制对比
    • 3.2 性能差异
  • 四、应用场景区分
    • 4.1 适合 v-if 的场景
    • 4.2 适合 v-show 的场景
  • 五、v-if 与 v-for 优先级
    • 5.1 Vue 2 vs Vue 3
    • 5.2 Vue 3 推荐写法
  • 六、SSR 场景
    • 6.1 v-show 在 SSR 中的问题
  • 七、面试聚焦
    • 7.1 生命周期差异
    • 7.2 初始渲染开销
  • 八、易混淆点
  • 九、思考与练习
  • 总结

前言

v-ifv-show是 Vue 中控制元素显示与隐藏的两种方式,理解它们的区别对性能优化至关重要。本篇会讲清楚:

  • v-if 的动态创建/销毁机制
  • v-show 的 CSS 切换机制
  • 两者的性能差异与选型
  • v-if 与 v-for 的优先级问题

一、v-if 条件渲染

1.1 定义

v-if是条件渲染指令,通过动态创建和销毁 DOM 节点来控制元素的显示与隐藏。

<template> <!-- 条件为 false 时,元素完全不存在于 DOM 中 --> <div v-if="show">显示内容</div> </template>

1.2 分支语法

<template> <!-- v-if / v-else-if / v-else 分支 --> <div v-if="type === 'A'">类型 A</div> <div v-else-if="type === 'B'">类型 B</div> <div v-else>其他类型</div> <!-- 在 <template> 上使用 --> <template v-if="show"> <h1>标题</h1> <p>内容</p> </template> </template>

1.3 生命周期影响

<script setup> import { ref, onMounted, onUnmounted } from 'vue' const show = ref(false) // 组件 A 的生命周期 onMounted(() => console.log('A 挂载')) onUnmounted(() => console.log('A 卸载')) </script> <template> <!-- show 从 false → true:触发 onMounted --> <!-- show 从 true → false:触发 onUnmounted --> <ComponentA v-if="show" /> </template>

二、v-show 显示隐藏

2.1 定义

v-show通过切换 CSSdisplay属性来控制元素的可见性,DOM 节点始终存在。

<template> <!-- 条件为 false 时,元素仍在 DOM 中,只是 display: none --> <div v-show="show">显示内容</div> </template>

2.2 不支持的场景

<template> <!-- ❌ 错误:v-show 不能用在 <template> 上 --> <template v-show="show"> <div>内容</div> </template> <!-- ❌ 错误:v-show 不支持 v-else --> <div v-show="show">显示</div> <!-- <div v-else>隐藏</div> 语法错误 --> </template>

三、核心区别

3.1 机制对比

对比项v-ifv-show
实现方式动态创建/销毁 DOM切换 CSS display
DOM 节点条件为 false 时不存在始终存在
初始渲染条件为 false 时无开销始终渲染
切换开销高(创建/销毁)低(切换样式)
生命周期触发创建/销毁钩子不触发任何钩子
template支持不支持
v-else支持不支持

3.2 性能差异

// 场景 1:条件很少变化// ✅ 推荐 v-if:初始渲染开销低(条件为 false 时不渲染)// ❌ v-show:始终渲染,浪费// 场景 2:频繁切换// ✅ 推荐 v-show:切换开销低(只切换样式)// ❌ v-if:每次切换都要创建/销毁 DOM

四、应用场景区分

4.1 适合 v-if 的场景

<template> <!-- 1. 权限控制:条件很少变化 --> <AdminPanel v-if="isAdmin" /> <UserPanel v-else /> <!-- 2. 角色判断:运行时条件固定 --> <div v-if="role === 'editor'">编辑器</div> <div v-else-if="role === 'viewer'">查看器</div> <!-- 3. 条件渲染多个元素 --> <template v-if="isLoggedIn"> <UserProfile /> <UserSettings /> </template> <!-- 4. 懒加载组件:首次需要时才创建 --> <HeavyComponent v-if="showHeavy" /> </template>

4.2 适合 v-show 的场景

<template> <!-- 1. Tab 切换:频繁切换 --> <div v-show="activeTab === 'tab1'">Tab 1 内容</div> <div v-show="activeTab === 'tab2'">Tab 2 内容</div> <div v-show="activeTab === 'tab3'">Tab 3 内容</div> <!-- 2. 折叠面板:频繁展开/收起 --> <div class="panel"> <div class="header" @click="expanded = !expanded">标题</div> <div v-show="expanded" class="content">内容</div> </div> <!-- 3. Tooltip / Popover:频繁显隐 --> <div v-show="tooltipVisible" class="tooltip">提示内容</div> <!-- 4. 加载状态:频繁切换 --> <div v-show="loading" class="spinner">加载中...</div> </template>

五、v-if 与 v-for 优先级

5.1 Vue 2 vs Vue 3

<template> <!-- Vue 2:v-for 优先级更高 --> <!-- 先遍历,再判断条件 --> <li v-for="item in list" v-if="item.active"> {{ item.name }} </li> <!-- Vue 3:v-if 优先级更高 --> <!-- 先判断条件,但 item 未定义! --> <!-- ❌ 错误写法 --> </template>

5.2 Vue 3 推荐写法

<script setup> import { ref, computed } from 'vue' const list = ref([ { id: 1, name: 'A', active: true }, { id: 2, name: 'B', active: false }, { id: 3, name: 'C', active: true } ]) // ✅ 推荐:用 computed 过滤 const activeList = computed(() => list.value.filter(item => item.active)) </script> <template> <!-- ✅ 正确:直接遍历过滤后的列表 --> <li v-for="item in activeList" :key="item.id"> {{ item.name }} </li> <!-- ✅ 或者用 <template> 包裹 --> <template v-for="item in list" :key="item.id"> <li v-if="item.active"> {{ item.name }} </li> </template> </template>

六、SSR 场景

6.1 v-show 在 SSR 中的问题

<template> <!-- v-show 在服务端渲染时无效 --> <!-- 因为服务端无法操作 DOM 的 display 属性 --> <!-- 服务端返回的 HTML 始终包含该元素 --> <div v-show="show">内容</div> <!-- ✅ SSR 推荐使用 v-if --> <!-- 条件为 false 时,服务端不会渲染该元素 --> <div v-if="show">内容</div> </template>

七、面试聚焦

7.1 生命周期差异

// v-if:切换时触发组件的创建/销毁生命周期// false → true:触发 onMounted// true → false:触发 onUnmounted// v-show:不触发任何生命周期钩子// 始终存在于 DOM 中

7.2 初始渲染开销

// v-if:条件为 false 时,初始渲染无开销(不创建 DOM)// v-show:无论条件如何,始终渲染 DOM(有初始渲染开销)// 场景:条件默认为 false,首次需要时才显示// v-if:首次无开销,切换时有开销// v-show:首次有开销,切换时无开销

八、易混淆点

  1. v-show 不可用在<template><template>不会渲染为真实 DOM,无法设置display属性。
  2. v-show 不支持 v-else:v-show 是简单的样式切换,不支持分支语法。
  3. SSR 场景 v-show 无效:服务端无法操作 DOM 的display属性,应使用 v-if。
  4. Vue 3 的优先级变化:v-if 优先级高于 v-for,Vue 2 中相反,这是常见迁移坑点。
  5. v-if 有"惰性":条件为 false 时,内部组件不会被创建;切换到 true 时才会创建。

九、思考与练习

1.v-if 和 v-show 的核心区别是什么?

解析:

  • v-if:动态创建/销毁 DOM,切换开销高,初始渲染开销低
  • v-show:切换 CSS display,切换开销低,初始渲染开销高

2.什么场景用 v-if,什么场景用 v-show?

解析:

  • v-if:条件很少变化(权限控制、角色判断)
  • v-show:频繁切换(Tab、折叠面板、Tooltip)

3.v-show 为什么不能用在<template>上?

解析:<template>不会渲染为真实 DOM 节点,而 v-show 需要通过操作 DOM 的display属性来切换显示,所以无法在<template>上使用。

4.Vue 3 中 v-if 和 v-for 一起用会怎样?

解析:Vue 3 中 v-if 优先级高于 v-for,会导致 v-if 中无法访问 v-for 的变量。推荐用 computed 先过滤列表,或用<template>包裹。

5.v-show 在 SSR 中为什么无效?

解析:SSR 是在服务端生成 HTML,服务端无法操作 DOM 的display属性。v-show 始终渲染元素到 HTML 中,无法在服务端实现隐藏效果,应使用 v-if。


总结

  • v-if:动态创建/销毁 DOM,适合条件很少变化的场景
  • v-show:切换 CSS display,适合频繁切换的场景
  • v-if 有分支语法:v-if / v-else-if / v-else
  • v-show 不支持<template>和 v-else
  • v-if 触发生命周期:创建/销毁钩子
  • v-show 不触发生命周期
  • Vue 3 优先级:v-if > v-for
  • SSR 场景:v-show 无效,用 v-if

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询