v-if 和 v-show 的区别📊

v-if 和 v-show 的区别

一句话总结

  • v-if条件满足才创建,不满足就销毁(条件渲染)
  • v-show总是创建,只是用CSS切换显示隐藏(显示切换)

比喻理解

v-if 就像租房

有钱时 → 租房子(创建DOM)
没钱时 → 退租(销毁DOM)
再有钱 → 重新租房(重新创建DOM)

v-show 就像开灯关灯

开灯时 → 房间亮着(display: block)
关灯时 → 房间黑了(display: none)
房间一直在,只是看不见

详细对比

特性

v-if

v-show

DOM操作

条件为假时,元素从DOM移除

条件为假时,元素还在DOM,只是 display: none

首次渲染

条件为假时,不渲染元素

条件为假时,会渲染元素,然后隐藏

切换开销

高(销毁/重建DOM)

低(只是CSS切换)

生命周期

切换时触发创建/销毁钩子

只触发挂载,不会销毁

性能

适合不频繁切换的场景

适合频繁切换的场景

初始渲染

如果初始不需要,可节省资源

无论是否需要,都会渲染


代码示例

<template>
  <div>
    <!-- v-if 示例 -->
    <div v-if="showWithIf">
      这个内容在showWithIf为true时创建,为false时销毁
    </div>
    
    <!-- v-show 示例 -->
    <div v-show="showWithShow">
      这个内容一直存在,showWithShow为false时只是隐藏
    </div>
    
    <!-- 切换按钮 -->
    <button @click="toggle">切换显示</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      showWithIf: false,
      showWithShow: false
    }
  },
  methods: {
    toggle() {
      this.showWithIf = !this.showWithIf
      this.showWithShow = !this.showWithShow
    }
  },
  mounted() {
    console.log('组件挂载')
  },
  // 在控制台观察
  // 当showWithIf为true时,会创建元素
  // 当showWithIf为false时,元素会从DOM移除
  // showWithShow的元素一直在DOM中
}
</script>

实际场景提议

✅ 用 v-if

<!-- 场景1:初始不需要的内容 -->
<div v-if="user.isAdmin">
  <!-- 管理员面板,大部分用户看不到 -->
  <AdminPanel />
</div>

<!-- 场景2:不常切换的组件 -->
<div v-if="currentTab === 'settings'">
  <!-- 设置页面,不常切换 -->
  <SettingsPage />
</div>

<!-- 场景3:提高初始加载速度 -->
<template v-if="dataLoaded">
  <!-- 数据加载完才显示 -->
  <DataTable :data="data" />
</template>

✅ 用 v-show

<!-- 场景1:频繁切换的UI -->
<div v-show="showToolbar">
  <!-- 工具栏,频繁显示/隐藏 -->
  <Toolbar />
</div>

<!-- 场景2:标签页内容 -->
<div v-show="activeTab === 'home'">
  <!-- 标签页内容,切换频繁 -->
  <HomeContent />
</div>
<div v-show="activeTab === 'profile'">
  <ProfileContent />
</div>

<!-- 场景3:需要保留状态的表单 -->
<form v-show="showForm">
  <!-- 表单输入状态需要保留 -->
  <input v-model="formData" />
</form>

性能对比演示

<template>
  <div>
    <h2>性能测试</h2>
    
    <!-- 测试按钮 -->
    <button @click="toggleMode">当前模式:{{ mode === 'v-if' ? 'v-if' : 'v-show' }}</button>
    <button @click="startTest">开始测试(切换1000次)</button>
    
    <!-- 测试结果 -->
    <p>v-if 耗时:{{ ifTime }}ms</p>
    <p>v-show 耗时:{{ showTime }}ms</p>
    
    <!-- 测试区域 -->
    <div v-if="mode === 'v-if'">
      <div v-if="isVisible">v-if 内容</div>
    </div>
    
    <div v-else>
      <div v-show="isVisible">v-show 内容</div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      mode: 'v-if',
      isVisible: true,
      ifTime: 0,
      showTime: 0
    }
  },
  methods: {
    toggleMode() {
      this.mode = this.mode === 'v-if' ? 'v-show' : 'v-if'
    },
    
    startTest() {
      if (this.mode === 'v-if') {
        this.testVif()
      } else {
        this.testVshow()
      }
    },
    
    testVif() {
      const start = performance.now()
      
      // 模拟快速切换1000次
      for (let i = 0; i < 1000; i++) {
        this.isVisible = !this.isVisible
        // 需要强制更新
        this.$forceUpdate()
      }
      
      this.ifTime = performance.now() - start
    },
    
    testVshow() {
      const start = performance.now()
      
      for (let i = 0; i < 1000; i++) {
        this.isVisible = !this.isVisible
        this.$forceUpdate()
      }
      
      this.showTime = performance.now() - start
    }
  }
}
</script>

结果:v-show 的切换速度一般比 v-if 快许多倍。


特殊注意事项

1. 与 <template>标签一起使用

<!-- v-if 可以与 <template> 一起使用 -->
<template v-if="condition">
  <div>内容1</div>
  <div>内容2</div>
</template>

<!-- v-show 不能与 <template> 一起使用 -->
<!-- ❌ 这是错误的 -->
<template v-show="condition">
  <div>内容</div>
</template>

2. 与 v-else 配合

<!-- v-if 可以配合 v-else -->
<div v-if="isLoggedIn">欢迎回来!</div>
<div v-else>请先登录</div>

<!-- v-show 不能配合 v-else -->
<!-- ❌ 这是错误的 -->
<div v-show="isLoggedIn">欢迎回来!</div>
<div v-else>请先登录</div>

3. 对子组件的影响

<template>
  <div>
    <!-- 子组件会随 v-if 销毁/重建 -->
    <ChildComponent v-if="showChild" />
    <!-- 触发 created、mounted、beforeDestroy、destroyed -->
    
    <!-- 子组件不会随 v-show 销毁 -->
    <ChildComponent v-show="showChild" />
    <!-- 只触发 created、mounted,不会销毁 -->
  </div>
</template>

4. 对 <input>值的影响

<template>
  <div>
    <!-- v-if:切换时会丢失输入值 -->
    <input v-if="showInput" v-model="inputValue" placeholder="v-if输入" />
    
    <!-- v-show:切换时保留输入值 -->
    <input v-show="showInput" v-model="inputValue" placeholder="v-show输入" />
    
    <button @click="showInput = !showInput">切换显示</button>
  </div>
</template>

记忆口诀

v-if 是懒汉,不用就不干
v-show 是勤快,干了藏起来

创建销毁用 v-if
显示隐藏用 v-show

选择指南

问自己:
1. 这个元素会频繁显示/隐藏吗?
   - 是 → 用 v-show
   - 否 → 用 v-if
   
2. 初始状态需要隐藏吗?
   - 是,且隐藏是常态 → 用 v-if(节省资源)
   - 是,但很快会显示 → 用 v-show
   
3. 需要保留元素状态吗?
   - 是(如表单输入)→ 用 v-show
   - 否 → 用 v-if
   
4. 元素很重(组件复杂)吗?
   - 是 → 用 v-if(不显示时完全卸载)
   - 否 → 用 v-show

简单说:v-if 是真正的条件渲染,v-show 是 CSS 显示切换。根据你的具体需求选择即可!

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
椿岛莓奏的头像 - 鹿快
评论 抢沙发

请登录后发表评论

    暂无评论内容