Skip to content
On this page

条件渲染就是"根据条件决定显示还是隐藏某个元素"。Vue 提供了两个指令:v-ifv-show

v-if / v-else-if / v-else

和 JavaScript 的 if...else 逻辑一模一样,控制元素是否在 DOM 中存在。

vue
<template>
  <p v-if="score >= 90">优秀</p>
  <p v-else-if="score >= 60">及格</p>
  <p v-else>不及格</p>
</template>
<script>
export default {
  data() {
    return { score: 75 }
  }
}
</script>

结果:页面只显示"及格"那一行。另外两行根本不在 HTML 里(你可以打开浏览器开发者工具验证)。 📝 Note:规则

  • v-if / v-else-if / v-else 必须紧挨着,中间不能插其他元素
  • 只有第一个带条件(v-if),后面的 v-else-ifv-else 跟着就行

v-show

v-show 也能控制显示隐藏,但原理不同——元素始终在 DOM 中,只是通过 CSS display: none 隐藏了

vue
<template>
  <p v-show="visible">我一直都在 DOM 里</p>
</template>
<script>
export default {
  data() {
    return { visible: true }
  }
}
</script>

visiblefalse 时:

html
<p style="display: none;">我一直都在 DOM 里</p>

v-if vs v-show,怎么选?

| | v-if | v-show | | 原理 | 条件为假时,元素从 DOM 中完全移除 | 条件为假时,元素还在,只是隐藏display: none) | | 初始渲染 | 条件为假时不渲染,更快(省资源) | 始终渲染,初始时慢一点点 | | 切换开销 | 每次切换要销毁/重建,开销大 | 只改 CSS,开销极小 | | 适用场景 | 条件很少改变的情况(如用户是否登录) | 条件频繁切换的情况(如选项卡切换) | 筛选分类时就可以用show减少css开销 💡 Tip:记住一个口诀少切换用 v-if,多切换用 v-show。

<template> 上使用 v-if

如果你想用 v-if 控制多个元素,但不想多包一层 <div>,可以用 <template>

vue
<template v-if="loggedIn">
  <h2>欢迎回来</h2>
  <p>今天天气不错</p>
  <button>开始使用</button>
</template>

<template> 是一个"隐形容器"——它本身不会渲染成任何 HTML,只是用来组织逻辑。 📝 Note:注意v-show 不能用在 <template> 上,因为 <template> 没有实际 DOM 元素。

实际例子:登录状态切换

vue
<template>
  <div>
    <p v-if="user">欢迎,{{ user }}</p>
    <button v-else @click="login">请登录</button>
  </div>
</template>
<script>
export default {
  data() {
    return { user: null }
  },
  methods: {
    login() {
      this.user = '小明'    // 数据一变,v-if 自动重新判断
    }
  }
}
</script>

点击按钮 → usernull 变成 "小明" → Vue 自动把"请登录"替换成"欢迎,小明"。

新手常见问题

Q:v-if 和 v-show 可以同时用吗? A:分开用就行,别同时加一个元素上。先判断用哪个:切换频繁用 v-show,否则用 v-ifQ:为什么 v-if 里用 v-for 会告警? A:Vue 规定 v-ifv-for 不能放在同一个元素上(执行优先级会出问题)。应该先用 v-for 循环,再在里面用 v-if。 下一步: 💡 Tip:Composition API 写法(Vue 3)

vue
<script setup>
import { ref } from 'vue'
const score = ref(75)
const visible = ref(true)
const user = ref(null)
</script>

模板部分完全不变。 详见: