源本科技 | 码上会

Vue3 条件渲染

2026/04/22
31
0

引言

Vue.js 的条件渲染通过 v-ifv-else-ifv-else 指令,根据数据状态动态决定是否渲染特定部分 DOM 结构。这有助于实现界面的灵活变化,提升用户体验并简化视图层逻辑处理

v-if 条件渲染

v-if 指令用于惰性条件渲染,它会根据表达式的真假值,动态创建或销毁 DOM 元素 / 组件。 当表达式返回假值时,对应的 DOM 结构完全不会被渲染到页面中;只有表达式为真值时,才会生成真实 DOM。

<template>
  <div>
    <!-- 单元素条件渲染 -->
    <span v-if="isShow">Hi Vue.js</span>
  </div>
</template>

<script setup lang="ts">
// 导入响应式 API
import { ref } from 'vue'

// 定义布尔类型响应式变量
const isShow = ref<boolean>(false)
</script>

<style scoped>
</style>

说明

  1. 响应式数据:使用 ref 创建基础类型响应式变量,是 Vue 3 标准用法;

  2. 指令规则v-if 可直接作用于任意 HTML 标签 / 组件;

  3. 渲染特性:惰性渲染,条件不满足时无 DOM 开销。

v-else 反向条件

v-else 用于为 v-if 添加反向渲染分支,无需绑定任何表达式。 强制规则v-else 元素必须紧跟v-ifv-else-if 元素之后,中间不能插入任何其他元素,否则无法被 Vue 识别。

<template>
  <div>
    <span v-if="isShow">Hi Vue.js</span>
    <!-- 必须紧跟前一个条件指令 -->
    <span v-else>Bye Vue.js</span>
    <button @click="isShow = !isShow">切换显示</button>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const isShow = ref<boolean>(false)
</script>

<style scoped>
</style>

v-else-if 多分支条件

v-else-if 用于构建多分支互斥条件渲染,支持连续链式使用,适配多个判断场景。 它同样需要遵循紧跟规则,且分支的判断顺序会直接影响渲染结果。

<template>
  <div>
    <div v-if="type === 'A'">选项 A</div>
    <div v-else-if="type === 'B'">选项 B</div>
    <div v-else-if="type === 'C'">选项 C</div>
    <div v-else>未匹配 A / B / C</div>

    <button @click="changeType('A')">切换为 A</button>
    <button @click="changeType('B')">切换为 B</button>
    <button @click="changeType('C')">切换为 C</button>
    <button @click="changeType('D')">切换为 D</button>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const type = ref<string>('D')

// 修改类型的方法
const changeType = (newType: string) => {
  type.value = newType
}
</script>

<style scoped>
</style>

template 无渲染包装器

v-if 是指令,必须依附于具体元素。如果需要同时控制多个元素的渲染,可以使用 <template> 标签作为逻辑包装器。 <template> 是 Vue 提供的虚拟容器,不会被渲染为真实 DOM,仅用于分组元素,不影响最终页面结构。 v-elsev-else-if 均可配合 <template> 使用。

<template>
  <div>
    <!-- 包装多个元素,无额外 DOM 生成 -->
    <template v-if="isShow">
      <h1>主标题</h1>
      <p>段落 1</p>
      <p>段落 2</p>
    </template>
    <button @click="isShow = !isShow">切换内容</button>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const isShow = ref<boolean>(false)
</script>

<style scoped>
</style>

v-show 条件显示

v-show 是用于控制元素显示 / 隐藏的指令,用法与 v-if 相似,但底层实现完全不同。

  • 无论条件真假,v-show 都会将元素渲染到 DOM 中,仅切换 CSS 的 display 属性;

  • 不支持 <template> 标签;

  • 不支持搭配 v-else 使用。

<template>
  <div>
    <h1 v-show="isShow">Hello Vue 3!</h1>
    <button @click="isShow = !isShow">切换显示</button>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const isShow = ref<boolean>(false)
</script>

<style scoped>
</style>

v-if 与 v-show

这是 Vue 条件渲染的高频考点,两者适用场景不同,需根据业务需求选择:

对比维度

v-if

v-show

渲染机制

惰性渲染,条件为假时销毁 / 不创建 DOM

始终渲染 DOM,仅切换 display: none

性能开销

切换开销大,初始渲染开销小

初始渲染开销大,切换开销极小

支持场景

支持 <template>、支持 v-else 分支

不支持 <template>、不支持分支

适用场景

条件极少变化、一次性渲染

元素需要频繁切换显示 / 隐藏

key 管理可复用元素

Vue 会默认复用 DOM 元素以提升渲染性能,在条件切换相同标签的元素时,可能会保留元素的内部状态,导致非预期效果。 此时需要使用 key 属性,强制 Vue 区分元素,禁止复用。

<template>
  <div>
    <!-- 不加 key,输入框内容会被复用 -->
    <input v-if="isLogin" type="text" placeholder="账号" key="account">
    <input v-else type="password" placeholder="密码" key="password">
    <button @click="isLogin = !isLogin">切换登录类型</button>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const isLogin = ref<boolean>(true)
</script>

最佳实践

  1. 频繁切换的元素(如 tab 切换、折叠面板)优先使用 v-show

  2. 运行时极少变化的条件(如权限控制、环境判断)优先使用 v-if,减少 DOM 占用;

  3. 批量控制多元素渲染时,统一使用 <template> + v-if,避免多余容器标签;

  4. 相同标签的条件切换,必须添加 key 防止 DOM 复用问题;

  5. 不要在 v-if 和分支指令之间插入无关元素,保证语法合法性。

总结

  1. v-if 系列是销毁 / 创建 DOMv-show切换 CSS 样式

  2. <template> 用于无侵入式分组渲染,仅支持 v-if 不支持 v-show

  3. 性能选型:频繁切换用 v-show,静态条件用 v-if

  4. 配合 key 可解决 DOM 复用导致的状态异常问题。