v-if和v-show

66 阅读2分钟

一、基础区别

特性v-ifv-show
渲染机制条件为假时,完全移除 DOM 元素条件为假时,隐藏 DOM 元素(display: none
编译过程惰性渲染:条件首次为真时才渲染初始渲染时就创建元素
性能消耗切换时有较高开销(涉及 DOM 增删)切换时开销较低(仅修改 CSS 属性)
适用场景运行时条件很少改变的场景需要频繁切换显示状态的场景

二、代码示例对比

<!-- v-if 示例 -->
<div v-if="isLoggedIn">欢迎回来!</div>

<!-- v-show 示例 -->
<div v-show="isLoading">加载中...</div>

三、执行流程差异

  1. v-if 的执行流程

    • 条件为 false 时:DOM 中不存在该元素。
    • 条件变为 true 时:动态创建元素,并触发组件生命周期钩子(如 mounted)。
  2. v-show 的执行流程

    • 无论条件真假,元素始终存在于 DOM 中。
    • 通过修改 display 样式控制显示/隐藏,不触发生命周期钩子。

四、性能考量

  • 频繁切换场景:使用 v-show,避免重复创建和销毁 DOM 元素。

    <!-- 频繁显示/隐藏的提示框 -->
    <div v-show="showTooltip">这是一个提示</div>
    
  • 条件很少改变场景:使用 v-if,初始渲染时可减少 DOM 节点数量。

    <!-- 用户登录状态,很少切换 -->
    <div v-if="user.isAdmin">管理员面板</div>
    

五、特殊场景注意事项

1. v-for 同时使用

  • 不推荐v-if 优先级高于 v-for,可能导致意外行为。
  • 推荐方案:通过计算属性过滤列表数据。
<!-- 错误示例:可能导致遍历未定义数据 -->
<li v-for="item in list" v-if="item.visible">{{ item.name }}</li>

<!-- 正确示例:使用计算属性 -->
<li v-for="item in visibleList">{{ item.name }}</li>

<script>
export default {
  computed: {
    visibleList() {
      return this.list.filter(item => item.visible);
    }
  }
}
</script>

2. 模板编译优化

  • v-if 条件为 false 时,其内部的事件监听器和子组件不会被初始化。
  • v-show 无论条件如何,元素及其子元素都会被初始化。

六、问题

1. 问:何时该用 v-if,何时该用 v-show

    • 若需要频繁切换显示状态(如表单验证提示),使用 v-show
    • 若条件在运行时很少改变(如权限控制),使用 v-if 以减少初始 DOM 体积。

2. 问:v-ifv-show 对组件生命周期有何影响?

    • v-if 切换时会触发组件的挂载(mounted)和销毁(destroyed)钩子。
    • v-show 切换时不会触发任何生命周期钩子。

3. 问:v-ifv-show 哪个性能更好?

    • 初始渲染v-if 在条件为 false 时更优(不渲染元素)。
    • 频繁切换v-show 更优(仅修改 CSS,无 DOM 操作)。