条件渲染:从传统原生到 Vue 的进化之路

在前端开发中,我们经常需要根据条件决定某个内容是否显示,比如登录状态不同、用户角色不同或网络数据是否加载完成。这种「条件渲染」的方式,既可以用原生 HTML + JS 实现,也可以借助现代框架如 Vue 来优雅处理。

一、传统 HTML + JavaScript 实现条件渲染

1. 使用

style.display

控制显示隐藏(类似 v-show)

这是最基础的方式,我们可以通过 JavaScript 来操作元素的样式属性,实现是否显示。

js 复制代码
<div id="message">Hello World</div>
<button onclick="toggle()">切换</button>

<script>
  let visible = true;
  function toggle() {
    visible = !visible;
    document.getElementById("message").style.display = visible ? 'block' : 'none';
  }
</script>

优点:简单直观。
缺点:只是隐藏了 DOM,并没有真正移除元素;元素仍然存在于页面中、仍会占内存。


2. 使用 DOM API 动态添加/删除节点(类似 v-if)

js 复制代码
<div id="container"></div>
<button onclick="toggle()">切换</button>

<script>
  let visible = false;
  const container = document.getElementById("container");

  function toggle() {
    container.innerHTML = '';
    if (visible) {
      container.innerHTML = '<p>Hello World</p>';
    }
    visible = !visible;
  }
</script>

优点:可以真正控制元素是否存在于 DOM 中。
缺点:代码冗长,维护困难,容易出错。


3. 基于 class 切换样式控制显示

js 复制代码
<style>
  .hidden { display: none; }
</style>

<div id="msg" class="hidden">条件文本</div>
<button onclick="toggle()">切换</button>

<script>
  const el = document.getElementById("msg");
  function toggle() {
    el.classList.toggle('hidden');
  }
</script>

这相当于封装了 display 样式切换的逻辑,和 v-show 本质相似,但需要手动维护类名。


二、传统方式的缺陷

  • 手动操作 DOM 麻烦且容易引入 Bug。

  • 无法清晰表达复杂的条件逻辑(例如多重 if-else)。

  • 多次切换 DOM 节点会引发性能问题。

  • 缺少响应式:当数据变化时,无法自动更新视图。

于是,Vue 的条件渲染应运而生。


三、Vue 的条件渲染指令详解

1. v-if:真正的条件渲染

js 复制代码
<script setup>
import { ref } from 'vue'
const awesome = ref(true)
</script>
<template>
  <button @click="awesome = !awesome">toggle</button>
	<h1 v-if="awesome">Vue is awesome!</h1>
	<h1 v-else>Oh no 😢</h1>
</template>

如果 awesome 是 true,这个标签会被渲染到 DOM;否则根本不会出现在页面中。


2. v-else:if 的"否则"分支

js 复制代码
<script setup>
import { ref } from 'vue'
const awesome = ref(true)
</script>
<button @click="awesome = !awesome">切换</button>
<h1 v-if="awesome">Vue is awesome!</h1>
<h1 v-else>Oh no 😢</h1>

v-else 必须紧跟在 v-if 或 v-else-if 后面,才会被 Vue 正确识别为"否则"分支。


3. v-else-if:多重条件判断

js 复制代码
<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>

这段代码的逻辑就类似于传统 JS 的 if - else if - else 结构,但更清晰、模板更直观。


4. v-if 使用在<template>上:条件渲染多个元素

js 复制代码
<template v-if="ok">
  <h1>标题</h1>
  <p>段落 1</p>
  <p>段落 2</p>
</template>

因为 HTML 中不能在多个兄弟元素上同时使用 v-if,所以 Vue 提供了 <template> 标签作为"包裹器",它本身不会被渲染成 DOM 元素,只会输出内部内容。


5. v-show:仅切换 display 样式

js 复制代码
<h1 v-show="ok">Hello!</h1>
  • 不会删除 DOM 节点,只是动态修改 display: none。
  • 适合频繁切换显示状态的场景(如 Tab 切换)。

四、v-if 和 v-show 的对比总结

特性 v-if v-show
原理 动态添加/移除 DOM 切换 display 样式
初始渲染 条件为 false 不渲染 总是渲染
性能 初始渲染开销小,切换开销大 初始开销大,切换更快
适合场景 条件不频繁切换 条件频繁切换
支持 template ✅ 支持 ❌ 不支持
可与 v-else 配合 ✅ 可以 ❌ 不可以

五、Vue 相比传统方法的优势

  1. 响应式绑定:只需控制数据,视图自动更新;
  2. 模板语法清晰易懂:v-if、v-else、v-show 一目了然;
  3. 无需手动操作 DOM:避免出错,提高效率;
  4. 可组合性强:可与组件、列表、事件绑定等无缝集成;
  5. 可维护性高:逻辑集中、代码简洁、易于团队协作。

六、补充知识:class 和 style 的传统绑定方式

详情请看这篇文章# 从传统 CSS 到 Vue 的 Class 与 Style 动态绑定全解

在条件渲染之外,我们还需要了解传统样式绑定的方式,这些知识和 v-bind:class、v-bind:style 是关联的:

常见方式

方式 示例 特点
HTML class 属性 静态类名,无法动态控制
DOM element.className el.className = 'box active' 覆盖原有类名
DOM element.classList.add/remove/toggle el.classList.add('new') 更加灵活,可组合类名
内联样式 写死样式,优先级高
DOM element.style 设置 el.style.display = 'none' 可动态控制单个样式

在 Vue 中,这些传统方式的繁琐操作都可以被简洁地用 v-bind:class 或 v-bind:style 替代,实现更清晰的逻辑。


结语

条件渲染是前端开发中的核心概念,而 Vue 的设计让这一过程变得简单、高效、清晰。通过 v-if、v-show、v-else-if 等指令,我们能轻松应对各种业务场景,而无需手动操控 DOM 或维护类名。


如果你觉得这篇文章对你有帮助,欢迎收藏或分享给你的朋友们。你还想了解哪些 Vue 的核心指令或和传统开发的对比?欢迎留言交流!

相关推荐
谢尔登2 分钟前
【JavaScript】手写 Object.prototype.toString()
前端·javascript·原型模式
蓝倾4 分钟前
小红书获取笔记详情API接口调用操作指南
前端·api·fastapi
浩龙不eMo4 分钟前
设置单行省略号后不生效?你肯定忘记了这几点!
前端·css
李大玄12 分钟前
一个轻量级、无依赖的 Loading 插件 —— @lijixuan/loading
前端·javascript·vue.js
巴厘猫13 分钟前
从 0 到 1 搭建 Vue3 + Vite 组件库:流程、规范与最佳实践
前端·vue.js·vite
VincentFHR17 分钟前
Three.js 利用 shader 实现 3D 热力图
前端·three.js·canvas
想要学好前端的阿毛19 分钟前
手写一个简单的react-router6 Part1
前端
shenyi22 分钟前
高德地图经纬度显示点位及输入位置选择经纬度
前端
星_离22 分钟前
初识Threejs
前端·three.js
程序员日常点滴23 分钟前
Vxetable v3.6.9 合并单元格+虚拟滚动问题
前端·vue.js