uniapp 中 v-if 与 v-show 完整区别
- 底层实现原理(核心差异)
v-if
真正的销毁 / 创建 DOM
条件为 false:直接从页面移除该节点,不存在 DOM 结构
条件为 true:重新创建、渲染、挂载 DOM
支持 v-else / v-else-if 链式判断
v-show
仅控制 CSS 显示隐藏,DOM 始终存在
条件为 false:给元素添加 display: none,DOM 节点还在页面里
条件为 true:移除 display: none,恢复显示
不支持 v-else - 性能对比
v-if
初始渲染开销大:初次为 true 时要创建 DOM、渲染、绑定事件
切换开销极大:频繁显隐会反复销毁重建,卡顿明显
初始为 false 时性能更好:页面加载完全不渲染该节点,节省资源
v-show
初始渲染开销略大:无论真假,页面初始化都会渲染该 DOM
切换开销极小:只修改 CSS 属性,无 DOM 重建,适合频繁切换场景 - 适用场景
用 v-if 的情况
元素很少切换(弹窗、分页、权限模块、tab 页面)
初始大概率不显示,想减少首屏 DOM 数量、优化加载速度
需要搭配 v-else 做分支渲染
组件内包含复杂子组件、大量节点,隐藏时不想占用渲染资源
用 v-show 的情况
高频反复切换(标签切换、下拉展开 / 收起、悬浮弹窗)
页面加载时就需要提前渲染好,只是临时隐藏 - uniapp 特有注意点(小程序 / H5/App 通用坑)
v-if 会重置组件状态
组件被销毁重建后,内部数据、输入框内容、滚动位置都会丢失;v-show 保留所有状态。
vue
<input v-if="flag" v-model="text" />
<input v-show="flag" v-model="text" />
v-if 搭配 uni 组件慎用
如 swiper、scroll-view、地图、视频组件,频繁 v-if 销毁重建容易出现渲染异常、白屏。
template 标签只能配合 v-if,不能 v-show
vue
<template v-if="show">
<view></view>
</template>
<template v-show="show"></template>
页面 onLoad 生命周期触发差异
v-if 包裹的自定义组件:条件变为 true 才会执行 onLoad
v-show 包裹组件:页面初始化就执行一次 onLoad,切换不会重复触发
- 简单总结口诀
少切换、首次大概率隐藏、需要 else → v-if
频繁显隐、要保留组件状态 → v-show
template 只能用 v-if;v-show 靠 display 隐藏 DOM