Vue 模板语法——条件渲染(1)

1,254 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

在某些情况下,我们需要根据当前的条件决定某些元素或组件是否被渲染,也就是说我们需要进行条件判断了。

Vue 提供了下面的指令来进行条件判断:

  • v-if
  • v-else-if
  • v-else
  • v-show

1. v-if 指令

v-ifv-else-ifv-else 用于根据条件来渲染某一块的内容:

  • 这块内容只会在指令的表达式返回 truthy 值时被渲染;
  • 这三个指令与 JavaScript 的条件语句 ifelse ifelse 类似;

v-if 使用示例:

<template id="my-app">
  <h2 v-if="isShow">{{ message }}</h2>
  <button @click="toggle">切换</button>
</template>

<body> 中的完整代码:

<div id="app"></div>

<template id="my-app">
  <h2 v-if="isShow">{{ message }}</h2>
  <button @click="toggle">切换</button>
</template>

<script src="./js/vue.js"></script>
<script>
  const App = {
    data() {
      return {
        message: '你好啊',
        isShow: true
      }
    },
    methods: {
      toggle() {
        this.isShow = !this.isShow;
      }
    },
    template: '#my-app'
  };

  Vue.createApp(App).mount('#app');
</script>

v-ifv-else-ifv-else 使用示例(多个条件的渲染示例):

<template id="my-app">
  <!-- 这里先用一下 v-model 指令,它可以用来做双向绑定(即这里 input 中的内容就和 data 中的 score 绑定在一起了),后面我们会讲到 -->
  <input type="text" v-model="score">
  <h2 v-if="score >= 90">优秀</h2>
  <h2 v-else-if="score >= 80">良好</h2>
  <h2 v-else-if="score >= 60">及格</h2>
  <h2 v-else>不及格</h2>
</template>
data() {
  return {
    score: 100
  }
}

v-if 的渲染原理:

  • 当条件为假时,v-if 判断的内容(条件块中的内容)完全不会被渲染或者会被销毁掉(即条件块中的所有元素是不会存在于 DOM 中的);
  • 当条件为真时,v-if 才会真正渲染条件块中的内容;
  • v-if 是惰性的:如果在初始渲染时条件为假,则条件块中的内容完全不会被渲染,直到条件第一次变为真时,才会开始渲染条件块。

1.1 在 <template> 元素上使用 v-if

因为 v-if 是一个指令,所以必须把它添加到一个元素上。

但是如果我们想切换多个元素呢?

  • 此时我们可以使用 <div> 元素包裹想切换的元素们,并在 <div> 元素上面使用 v-if。但这样做 <div> 元素最终也会被渲染出来,这可能是没有必要的,也可能会造成一点点的性能浪费。
  • 所以我们推荐使用 <template> 元素。<template> 元素可以当做不可见的包裹元素,在上面使用 v-if,最终的渲染结果将不包含 <template> 元素(有点类似于小程序中的 block)。

<template> 元素和 v-if 结合使用示例:

<template id="my-app">
  <template v-if="isShow">
    <h2>{{ message }}</h2>
    <h2>{{ message }}</h2>
    <h2>{{ message }}</h2>
  </template>
  <template v-else>
    <h2>哈哈哈</h2>
    <h2>哈哈哈</h2>
    <h2>哈哈哈</h2>
  </template>
</template>
data() {
  return {
    message: '你好啊',
    isShow: true
  }
}