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 元素。

相关推荐
小飞侠在吗18 分钟前
vue ref
前端·javascript·vue.js
悟能不能悟19 分钟前
在 Vue Router 4 中,如何设置base参数
前端·javascript·vue.js
Lovely_Ruby1 小时前
前端er Go-Frame 的学习笔记:实现 to-do 功能(三),用 docker 封装成镜像,并且同时启动前后端数据库服务
前端·后端
kong@react1 小时前
react+ts项目,富文本开发(wangEditor)
前端·react.js·前端框架
重铸码农荣光1 小时前
AI First + Mobile First:用大模型重构下一代应用开发范式
前端·架构·llm
Lovely_Ruby1 小时前
前端er Go-Frame 的学习笔记:实现 to-do 功能(二),前端项目的开发,对接后端
前端
Cassie燁1 小时前
el-button源码解读4——props color和native-type
vue.js·element
willingtolove1 小时前
使用chrome修改请求参数重新发送请求
前端·chrome
-曾牛1 小时前
CSRF跨站请求伪造:原理、利用与防御全解析
前端·网络·web安全·网络安全·渗透测试·csrf·原理解析
大佐不会说日语~2 小时前
SSE 流式输出 Markdown 实时渲染问题解决方案
java·vue.js·sse·spring ai·前端实时渲染