v-if和v-show的区别

156 阅读4分钟

前言

v-ifv-show 都是 Vue.js 中用于控制元素显示和隐藏的指令,但它们有一些区别:

  1. 编译时处理v-if 在编译时进行处理,如果条件为 false,则元素及其子元素在模板中会被完全删除,不会生成对应的虚拟 DOM。而 v-show 不会在编译时删除元素,而是直接在模板中生成虚拟 DOM,只是通过 CSS 的 display 属性来控制元素的显示和隐藏。
  2. 初始渲染成本v-if 有更高的初始渲染成本,因为它需要进行额外的编译时处理。而 v-show 的初始渲染成本较低,因为它只是简单地生成虚拟 DOM,并且不涉及元素的添加或删除。
  3. 切换成本v-if 在切换时需要重新渲染元素及其子元素,而 v-show 只需要切换 CSS 的 display 属性,所以 v-show 的切换成本较低。
  4. 适用场景v-if 适用于不需要频繁切换的场景,因为它的初始渲染成本较高。而 v-show 适用于需要频繁切换显示状态的场景,因为它的切换成本较低。

下面是一个简单的示例:

<template>
  <div>
    <button @click="toggle">切换</button>
    <p v-if="show">这是一个条件渲染的段落。</p>
    <p v-show="show">这是一个动态显示的段落。</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      show: true
    }
  },
  methods: {
    toggle() {
      this.show = !this.show;
    }
  }
}
</script>

在这个示例中,我们同时使用了 v-ifv-show 来控制两个段落的显示状态。可以看到,当 show 的值为 true 时,两个段落都会显示;当 show 的值为 false 时,v-if 控制的段落会被完全删除,而 v-show 控制的段落只会隐藏。

v-if和v-show到底触发了哪些生命周期钩子?

v-if

如果 v-if 的条件为 true,Vue 会生成元素并将其挂载到 DOM 上,这时会触发 beforeMountmounted 生命周期钩子。

具体来说,当 v-if 的条件由 false 变为 true 时,Vue 编译器会生成元素,并在模板中插入它。然后,Vue 会执行元素的生命周期钩子,包括 beforeMountmounted

beforeMount 钩子在元素被挂载到 DOM 之前调用,而 mounted 钩子在元素被挂载到 DOM 之后调用。这两个钩子都允许你在元素被渲染和插入到 DOM 之前或之后执行一些自定义逻辑。

v-show

v-show 指令不会触发 beforeMountmounted 生命周期钩子,因为它不会影响元素的生成和挂载过程。

但是,v-show 仍然会触发 createdbeforeDestroy 生命周期钩子,因为它会生成元素,并在需要时切换元素的 display 属性。

具体来说,当 v-show 的元素首次渲染时,Vue 会执行 created 生命周期钩子。然后,当 v-show 的条件发生变化时,Vue 会切换元素的 display 属性,从而显示或隐藏元素。最后,当 v-show 的元素被销毁时,Vue 会执行 beforeDestroy 生命周期钩子。

需要注意的是,与 v-if 不同,v-show 始终会生成元素,并在模板中插入它,而不管条件是否满足。因此,v-show 会触发 created 生命周期钩子,而 v-if 则不会。

举一个销毁的例子来说清楚他们两个的区别:

假设我们有一个 Vue 实例,其中包含一个 v-if 元素和一个 v-show 元素:

wrap_textheart_pluscontent_pastekeyboard_return
<div v-if="isVisible">I'm using v-if</div>
<div v-show="isVisible">I'm using v-show</div>

在 Vue 实例中,我们可以定义一个 isVisible 数据属性,并在 beforeDestroydestroyed 生命周期钩子中添加一些自定义逻辑:

new Vue({
  data: {
    isVisible: true
  },
  beforeDestroy() {
    console.log('beforeDestroy hook called');
  },
  destroyed() {
    console.log('destroyed hook called');
  }
});

在这个例子中,当 isVisible 的值为 true 时,两个元素都会被渲染。但是,当我们将 isVisible 的值设置为 false 时,v-if 会完全移除元素,而 v-show 只会切换元素的 display 属性。

beforeDestroydestroyed 是 Vue 实例销毁时的生命周期钩子。beforeDestroy 钩子允许你在实例销毁之前执行一些自定义逻辑,而 destroyed 钩子允许你在实例销毁之后执行一些自定义逻辑。

区别在于,v-if 还会触发 unmounted 生命周期钩子,而 v-show 则不会。unmounted 钩子允许你在元素从 DOM 中移除之前执行一些自定义逻辑。这是因为 v-if 会完全移除元素,而 v-show 只会切换元素的 display 属性。

总的来说,v-ifv-show 销毁时的生命周期钩子有所不同,具体取决于元素的销毁方式和移除方式。