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

相关推荐
日光倾1 分钟前
【Vue.js 入门笔记】 状态管理器Vuex
vue.js·笔记·flutter
Highcharts.js3 分钟前
如何在构建音频图表中映射到数据?
javascript·信息可视化·音视频·开发文档·highcharts·数据映射
Jiaberrr3 分钟前
小程序setData性能优化指南:避开坑点,让页面丝滑如飞
前端·javascript·vue.js·性能优化·小程序
m0_694845573 分钟前
HandBrake 是什么?视频转码工具使用与服务器部署教程
服务器·前端·pdf·开源·github·音视频
方安乐5 分钟前
react笔记之tanstack
前端·笔记·react.js
学嵌入式的小杨同学9 小时前
从零打造 Linux 终端 MP3 播放器!用 C 语言实现音乐自由
linux·c语言·开发语言·前端·vscode·ci/cd·vim
weixin_425543739 小时前
TRAE CN3.3.25 构建的Electron简易DEMO应用
前端·typescript·electron·vite·nestjs
Mr Xu_10 小时前
【Vue3 + ECharts 实战】正确使用 showLoading、resize 与 dispose 避免内存泄漏
前端·信息可视化·vue·echarts
0思必得010 小时前
[Web自动化] Selenium设置相关执行文件路径
前端·爬虫·python·selenium·自动化
雯0609~10 小时前
hiprint:实现项目部署与打印1-官网提供普通html版本
前端·html