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

相关推荐
带娃的IT创业者21 小时前
TypeScript + React + Ant Design 前端架构入门:搭建一个 Flask 个人博客前端
前端·react.js·typescript
二十雨辰21 小时前
vite如何处理项目中的资源
开发语言·javascript
非凡ghost1 天前
MPC-BE视频播放器(强大视频播放器) 中文绿色版
前端·windows·音视频·软件需求
Stanford_11061 天前
React前端框架有哪些?
前端·微信小程序·前端框架·微信公众平台·twitter·微信开放平台
洛可可白1 天前
把 Vue2 项目“黑盒”嵌进 Vue3:qiankun 微前端实战笔记
前端·vue.js·笔记
学习同学1 天前
从0到1制作一个go语言游戏服务器(二)web服务搭建
服务器·前端·golang
-D调定义之崽崽1 天前
【初学】调试 MCP Server
前端·mcp
四月_h1 天前
vue2动态实现多Y轴echarts图表,及节点点击事件
前端·javascript·vue.js·echarts
文心快码BaiduComate1 天前
用Zulu轻松搭建国庆旅行4行诗网站
前端·javascript·后端
正义的大古1 天前
OpenLayers地图交互 -- 章节十八:拖拽旋转和缩放交互详解
javascript·vue.js·openlayers