前言

在 Vue 模板开发中,指令的优先级和渲染机制直接决定了应用的性能。尤其是 v-ifv-for 的“爱恨情仇”,在 Vue 2 和 Vue 3 中经历了完全相反的变革。本文将带你从底层逻辑出发,看透这些指令的本质。

一、 v-if 与 v-for 的优先级之战

1. Vue 2 时代:v-for 称王

在 Vue 2 中,v-for 的优先级高于 v-if

这意味着如果你在同一个元素上同时使用它们,Vue 会先执行循环,再对循环出的每一个项进行条件判断。

  • 后果:即使 v-iffalse,循环依然会完整执行,造成极大的性能浪费。

2. Vue 3 时代:v-if 反超

在 Vue 3 中,v-if 的优先级高于 v-for

此时,如果两者并列,v-if 会先执行。但由于此时循环尚未开始,v-if 无法访问到 v-for 循环中的变量,会导致报错。

3. 最佳实践:永远不要同台竞技

无论哪个版本,永远不要把v-if和v-for同时用在同一个元素上。如果非要一起使用可以通过如下方式:

  • 方案 A:外层包裹 template(推荐)

    如果判断条件与循环项无关,先判断再循环。

    <template v-if="isShow">
      <div v-for="item in items" :key="item.id">{{ item.name }}</div>
    </template>
    
  • 方案 B:使用计算属性 computed(推荐)

    如果需要根据条件过滤列表项,先过滤再循环。

    <script setup lang="ts">
    import { computed } from 'vue';
    const activeItems = computed(() => items.value.filter(item => item.isActive));
    </script>
    
    <template>
      <div v-for="item in activeItems" :key="item.id">{{ item.name }}</div>
    </template>
    

二、 v-if 与 v-show:隐藏背后的玄机

两者都能控制显隐,但“手段”截然不同。

1. 核心区别对照表

特性v-ifv-show
手段真正的数据驱动,动态添加/删除 DOM 元素CSS 驱动,切换 display: none 属性
本质组件的销毁与重建元素的显示与隐藏
初始渲染若初始为 false,则完全不渲染无论真假,都会渲染并保留 DOM
切换消耗较高(涉及生命周期与 DOM 增删)较低(仅改变 CSS)
生命周期切换时触发完整生命周期不触发生命周期钩子

2. 生命周期触发逻辑(Vue 3 + TS 视角)

由于 v-if 是真实的销毁与重建,它会完整走一遍生命周期。

<script setup lang="ts">
import { onMounted, onUnmounted } from 'vue';

// 假设这是一个被 v-if 控制的子组件
onMounted(() => {
  console.log('子组件已创建并挂载 (v-if 为 true)');
});

onUnmounted(() => {
  console.log('子组件已卸载并销毁 (v-if 为 false)');
});
</script>
  • v-if 切换

    • false -> true:触发 onBeforeMount, onMounted 等。
    • true -> false:触发 onBeforeUnmount, onUnmounted 等。
  • v-show 切换

    • 不会触发上述任何钩子,因为组件实例始终保存在内存中。

三、 总结:如何选型?

  • 选择 v-show:如果元素在页面上频繁切换(如 Tab 标签、折叠面板),v-show 的性能表现更优。
  • 选择 v-if:如果运行条件下改变较少,或者该部分包含大量复杂的子组件,使用 v-if 可以保证初始渲染的轻量化,并在不需要时彻底释放内存。
本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:alixiixcom@163.com