v-show 的使用

v-show 是另一个用于控制元素显示的指令,它通过切换元素的 CSS display 属性来实现。

基本用法

<h1 v-show="ok">Hello!</h1>

<script>
new Vue({
  data: {
    ok: true
  }
})
</script>

okfalse 时,元素会被设置为 display: none,但仍然存在于 DOM 中。

v-show 的特点

1. 元素始终渲染

v-if 不同,v-show 的元素始终会被渲染并保留在 DOM 中:

<div id="app">
  <div v-show="visible">v-show 元素</div>
  <div v-if="visible">v-if 元素</div>
</div>

visiblefalse 时:

  • v-show 元素:存在,style="display: none"
  • v-if 元素:不存在于 DOM 中

2. 不支持 template

v-show 不支持 <template> 元素,也不能和 v-else 配合使用:

<!-- ❌ 不支持 -->
<template v-show="ok">
  <p>内容</p>
</template>

<!-- ❌ 不支持 -->
<div v-show="ok">Yes</div>
<div v-else>No</div>

3. 适合频繁切换

由于 v-show 只是切换 CSS 属性,切换开销很小:

<div id="app">
  <button @click="toggle">切换</button>
  <div v-show="show">
    这个元素会被频繁显示/隐藏
  </div>
</div>

<script>
new Vue({
  data: {
    show: true
  },
  methods: {
    toggle: function() {
      this.show = !this.show
    }
  }
})
</script>

v-if vs v-show 对比

渲染行为

<!-- v-if:条件为假时不渲染 -->
<div v-if="false">不会出现在 DOM 中</div>

<!-- v-show:始终渲染,只是隐藏 -->
<div v-show="false">存在于 DOM,但 display: none</div>

性能对比

特性v-ifv-show
初始渲染(条件为假)不渲染渲染但隐藏
切换开销高(销毁/重建)低(CSS 切换)
适用场景条件很少改变频繁切换

代码示例

<div id="app">
  <h3>Tab 切换示例</h3>
  
  <!-- 使用 v-show:适合 Tab 切换 -->
  <div class="tabs">
    <button 
      v-for="tab in tabs" 
      :key="tab.id"
      :class="{ active: currentTab === tab.id }"
      @click="currentTab = tab.id"
    >
      {{ tab.name }}
    </button>
  </div>
  
  <div class="content">
    <div v-show="currentTab === 'home'">首页内容</div>
    <div v-show="currentTab === 'profile'">个人资料</div>
    <div v-show="currentTab === 'settings'">设置</div>
  </div>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    currentTab: 'home',
    tabs: [
      { id: 'home', name: '首页' },
      { id: 'profile', name: '个人资料' },
      { id: 'settings', name: '设置' }
    ]
  }
})
</script>

实际应用场景

1. Tab 切换

<div class="tabs">
  <button @click="tab = 'a'">Tab A</button>
  <button @click="tab = 'b'">Tab B</button>
</div>
<div v-show="tab === 'a'">内容 A</div>
<div v-show="tab === 'b'">内容 B</div>

2. 下拉菜单

<div class="dropdown">
  <button @click="isOpen = !isOpen">菜单</button>
  <ul v-show="isOpen">
    <li>选项 1</li>
    <li>选项 2</li>
    <li>选项 3</li>
  </ul>
</div>

3. 模态框

<div class="modal" v-show="showModal">
  <div class="modal-content">
    <h2>标题</h2>
    <p>内容</p>
    <button @click="showModal = false">关闭</button>
  </div>
</div>

4. 展开/折叠

<div class="accordion">
  <div class="header" @click="expanded = !expanded">
    点击展开/折叠
  </div>
  <div class="content" v-show="expanded">
    折叠的内容
  </div>
</div>

5. 加载指示器

<div v-show="loading" class="loading">
  <span class="spinner"></span>
  加载中...
</div>

与 CSS 过渡配合

v-show 可以很好地与 CSS 过渡配合:

<style>
.fade-enter-active, .fade-leave-active {
  transition: opacity 0.3s;
}
.fade-enter, .fade-leave-to {
  opacity: 0;
}
</style>

<div id="app">
  <button @click="show = !show">切换</button>
  <transition name="fade">
    <p v-show="show">带过渡效果的文字</p>
  </transition>
</div>

注意:使用 <transition> 时,v-showv-if 都可以触发过渡效果。

选择指南

是否需要频繁切换?
    ├── 是 → 使用 v-show
    └── 否 → 初始条件是否为假?
                  ├── 是 → 使用 v-if(节省初始渲染)
                  └── 否 → 两者皆可,v-if 更语义化

小结

v-show 的特点:

  • 通过 CSS display 控制显示
  • 元素始终存在于 DOM
  • 切换开销小
  • 适合频繁切换的场景
  • 不支持 <template>v-else

记住:频繁切换用 v-show,条件很少改变用 v-if