v-show 在 uni-app 中不生效的主因是不能用于 标签或组件根节点,且需确保绑定变量响应式、避免与 v-if 混用、注意小程序平台样式和事件兼容性问题。
v-show 在 uni-app 里不生效?先看是不是用了 v-if
uni-app 的 v-show 本质是切换元素的 display: none 样式,但它**完全不支持在 <template></template> 标签或组件根节点上使用**——这点和 vue 2/3 一致,但 uni-app 编译到小程序时更容易暴露问题。
常见错误现象:v-show 绑定变量变化了,DOM 完全没反应,甚至控制台报错 Cannot read property 'xxx' of undefined。
- 检查是否把
v-show写在了<template></template>上(比如想控制一组元素显隐)→ 改用v-if或包一层<view></view> - 检查是否在自定义组件的根节点上用了
v-show→ 小程序不支持对根节点做样式控制,必须改用v-if - 确认绑定的变量是响应式的:不能是
const show = true这种字面量,得是data()返回的对象属性或ref()/reactive()声明的值
v-if 和 v-show 混用导致渲染异常
在 uni-app 中,v-if 和 v-show 同时出现在同一个元素上会触发编译警告,且实际行为以 v-if 为准——v-show 被忽略。更隐蔽的问题是嵌套使用时的“条件覆盖”。
使用场景:比如一个弹窗组件,外层用 v-if="showDialog" 控制挂载,内部按钮又用 v-show="canClose" 控制显隐。如果 showDialog 为 false,整个子树被销毁,canClose 的变化就毫无意义。
- 不要在同一元素上同时写
v-if和v-show - 需要频繁切换的显隐(如 tab 切换、折叠面板),优先用
v-show;只在必要时才挂载/卸载(如登录态校验失败后彻底移除表单),才用v-if - 注意生命周期:用
v-if时,组件的mounted/onLoad会反复触发;v-show不影响生命周期
小程序平台下 v-show 样式失效的兼容性坑
uni-app 编译到微信/支付宝小程序时,v-show 依赖注入内联 style,但某些情况会被覆盖或忽略:
- 父级设置了
overflow: hidden+ 子元素position: absolute,v-show隐藏后仍占位或显示异常 → 改用v-if或手动加visibility: hidden - 使用了 CSS-in-JS 库(如
@dcloudio/uni-ui的部分组件)内部已封装显隐逻辑,再套v-show可能冲突 → 查文档确认组件是否自带显示控制 - 真机调试时发现隐藏了但还能点到 → 检查是否遗漏了
pointer-events: none,v-show只改display,不阻止事件
示例:正确处理点击穿透
<view v-show="showPopup" style="pointer-events: {{ showPopup ? 'auto' : 'none' }}"><button>确定</button>
</view>
条件渲染中 data 响应性丢失的典型写法
uni-app 的 data 是函数返回对象,但很多人在赋值时直接替换整个对象或数组,导致响应性中断 —— v-show 绑定的变量看似变了,视图却不更新。
- 错误写法:
this.showList = newList(newList 是新数组引用)→ 小程序平台可能无法检测变化 - 正确做法:用
this.$set(this, 'showList', newList)或Vue.set(Vue 2);Vue 3 + Composition API 下用ref或reactive并确保修改方式符合响应规则 - watch 使用陷阱:监听
showList时没加deep: true,深层属性变化不会触发v-show依赖更新
容易被忽略的地方:H5 和小程序对响应式处理不一致,H5 可能“看起来正常”,但小程序立刻白屏或卡死 —— 调试一定要在目标平台真机运行,别只信 H5 预览









