Vue:条件渲染 (Conditional Rendering)

1. 核心指令:v-if

作用 :用于条件性地渲染 一块内容。这块内容只会在指令的表达式返回真值 (truthy value) 时才被渲染和保留在 DOM 中

语法

html 复制代码
<h1 v-if="awesome">Vue is awesome!</h1>

工作机制

  • 当 awesome 为真值时,

    元素会被创建并插入到 DOM 中。

  • 当 awesome 变为假值时,Vue 会销毁该元素及其内部的事件监听器和子组件(触发相应的生命周期钩子)。

  • 当 awesome 再次变为真值时,Vue 会重新创建该元素及其内容(再次触发生命周期钩子)。

特点:是"真正"的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件被正确地销毁和重建。

2. 辅助指令:v-else

作用 :为 v-if 添加一个"else 区块"。必须紧跟在 v-if 或 v-else-if 元素后面,否则它将无法被识别。

语法

html 复制代码
<button @click="awesome = !awesome">Toggle</button>

<h1 v-if="awesome">Vue is awesome!</h1>
<h1 v-else>Oh no 😢</h1>

注意 :v-else 不需要任何表达式。

3. 辅助指令:v-else-if

作用 :提供相当于 v-if 的"else if 区块"。可以连续多次重复使用,用于实现多个分支的条件判断。

语法

html 复制代码
<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>
  Not A/B/C
</div>

注意 :和 v-else 类似,一个使用 v-else-if 的元素必须紧跟 在一个 v-if 或一个 v-else-if 元素后面。

4. 在 <template> 上使用 v-if

问题v-if 必须依附于单个元素。如果想切换多个元素,包裹一个 div 有时会破坏 HTML 结构。

解决方案 :可以在一个 <template> 元素上使用 v-if。<template> 是一个不可见的包装器元素,最终的渲染结果不会包含它

语法

html 复制代码
<template v-if="ok">
  <h1>Title</h1>
  <p>Paragraph 1</p>
  <p>Paragraph 2</p>
</template>

注意 :v-else 和 v-else-if 同样可以在 <template> 上使用。

5. 替代指令:v-show

作用 :另一个用于按条件显示 一个元素的指令。元素始终会被渲染并保留在 DOM 中 ,v-show 只是简单地切换该元素的 CSS display 属性。

语法

html 复制代码
<h1 v-show="ok">Hello!</h1>

限制

  • 不支持 在 <template> 元素上使用。

  • 不能 和 v-else 搭配使用。

6. v-if vs. v-show 核心对比

特性 v-if v-show
工作机制 条件性地渲染/销毁元素 始终渲染 ,仅切换 CSS display 属性
编译/渲染 惰性的:初始为 false 则不编译 无论条件如何,初始都会编译
DOM 操作 操作 DOM 节点的添加和移除 仅操作 CSS 样式
性能开销 更高的切换开销(尤其是初始为 false 时) 更高的初始渲染开销(无论是否显示都要渲染)
适用场景 运行时条件很少改变 ,或需要避免初始渲染 需要非常频繁切换的场景

选择策略流程图

7. 重要注意事项

v-ifv-for 的优先级

规则 :当 v-if 和 v-for 同时用于同一个元素 时,v-if 会首先被执行

强烈建议不要在同一元素上使用这两个指令。可以通过以下方式解决:

  1. 使用 <template> 包装 :将 v-for 放在 <template> 上,v-if 放在内部元素上。

  2. 使用计算属性 :预先通过计算属性过滤列表,避免同时需要 v-if 和 v-for。

示例 (不推荐)

html 复制代码
<!-- 不推荐的做法 -->
<li v-for="todo in todos" v-if="!todo.isComplete">
  {{ todo.name }}
</li>

示例 (推荐)

html 复制代码
<!-- 推荐做法 1: 使用 <template> -->
<template v-for="todo in todos">
  <li v-if="!todo.isComplete">
    {{ todo.name }}
  </li>
</template>

<!-- 推荐做法 2: 使用计算属性 -->
<li v-for="todo in incompleteTodos">
  {{ todo.name }}
</li>
// ...
computed: {
  incompleteTodos() {
    return this.todos.filter(todo => !todo.isComplete);
  }
}

8. 总结

  1. v-if、v-else-if、v-else 是一套用于实现条件块渲染/销毁的指令链,它们控制的是元素是否存在於 DOM 中。

  2. v-show 是一个独立的指令,它通过 CSS 控制元素的显示与隐藏,元素始终存在于 DOM 中

  3. 选择 v-if 还是 v-show 取决于你的具体需求:

    • 需要频繁切换 (如 tabs 切换)? -> v-show

    • 条件在运行时很少改变 ,或希望减少初始负载 ? -> v-if

  4. 绝对避免 在同一个元素上同时使用 v-if 和 v-for。如果需要,请使用 <template> 标签或计算属性来拆分逻辑。

  5. 使用 <template> 标签可以对多个元素进行分组条件渲染,而无需引入多余的 DOM 元素。

相关推荐
颜酱6 小时前
图结构完全解析:从基础概念到遍历实现
javascript·后端·算法
失忆爆表症6 小时前
05_UI 组件库集成指南:Shadcn/ui + Tailwind CSS v4
前端·css·ui
小迷糊的学习记录7 小时前
Vuex 与 pinia
前端·javascript·vue.js
发现一只大呆瓜7 小时前
前端性能优化:图片懒加载的三种手写方案
前端·javascript·面试
不爱吃糖的程序媛7 小时前
Flutter 与 OpenHarmony 通信:Flutter Channel 使用指南
前端·javascript·flutter
利刃大大7 小时前
【Vue】Element-Plus快速入门 && Form && Card && Table && Tree && Dialog && Menu
前端·javascript·vue.js·element-plus
NEXT067 小时前
AI 应用工程化实战:使用 LangChain.js 编排 DeepSeek 复杂工作流
前端·javascript·langchain
念风零壹7 小时前
AI 时代的前端技术:从系统编程到 JavaScript/TypeScript
前端·ai
光影少年8 小时前
react的hooks防抖和节流是怎样做的
前端·javascript·react.js
小毛驴8508 小时前
Vue 路由示例
前端·javascript·vue.js