uni-app中动态修改input的type在微信小程序和App端无效,必须用v-if切换两个input实例或uView的:password+key强制重建;因小程序原生input不支持运行时改type,仅首次创建时读取,后续setData被忽略。

直接说结论:uni-app 里不能靠动态改 input 的 type 属性来切换密码明文,微信小程序和 App 端会失效;必须用 v-if 切换两个 input 实例,或用 uView 的 :password + v-show 组合(但要注意渲染顺序和 focus 行为)。
为什么 type="password" 动态切换在小程序里不生效
因为微信小程序原生 input 组件不支持运行时修改 type。uni-app 编译到小程序时,底层调用的是 wx:input,它只在首次创建时读取 type,后续 setData 不触发 type 重置。你看到的“没变化”,其实是 DOM 节点没重建,只是属性被忽略。
常见错误现象:
- 点击眼睛图标后,
inputType变了,但输入框内容仍被星号遮盖 - H5 正常、App 正常,唯独小程序端卡在初始状态
- 手动调用
focus()失败,报错res.node is undefined
正确做法是彻底销毁并重建节点 —— 也就是用 v-if 而非 v-show 或 :type 绑定。
用 v-if 切换两个 input 的实操要点
这是最稳定、全端兼容的写法,适用于原生 input 和 uView 的 u-input(需配合 :password)。
关键点:
- 两个
input必须共用同一个v-model(如v-model="password"),否则值不同步 - 显式声明
key,避免 Vue 复用节点导致 focus/光标异常,例如:key="pwd-text"和key="pwd-password" - 切换后要主动聚焦新节点:用
uni.createSelectorQuery()查新input,再调node.focus()(document.getElementById在小程序无效) - 图标状态变量(如
showPassword)必须与 input 类型严格反向:图标显示“睁眼” →type="text"→showPassword = true
示例片段:
<input v-if="showPassword" type="text" v-model="password" placeholder="密码" :id="'pwdInput'" /> <input v-else type="password" v-model="password" placeholder="密码" :id="'pwdInput'" /> <image @tap="togglePassword" :src="showPassword ? '../../static/icons/hide.png' : '../../static/icons/show.png'" />
在 togglePassword 中:
this.showPassword = !this.showPassword;
this.$nextTick(() => {
const query = uni.createSelectorQuery().in(this);
query.select('#pwdInput').fields({ node: true }, res => {
if (res?.node) res.node.focus();
}).exec();
});
用 uView u-input 的 :password 时的坑
uView 的 u-input 提供了 :password 布尔属性,看起来能直接绑定,但实际在小程序中仍有响应延迟或失效问题,尤其搭配 v-show 时。
原因:
-
v-show只控制 display,节点未销毁,:password变更无法触发小程序 input 重绘 - 某些 uView 版本(如 2.x)在 nvue 页面中对
:password支持不完整 - 图标点击后未同步更新
input内部状态,导致光标位置错乱
稳妥方案:
- 放弃
:password单属性控制,改用v-if切换两个u-input实例 - 若坚持用
:password,必须配合key强制重建,例如:<u-input :key="showPassword" :password="!showPassword" ...></u-input> - 确保 uView 版本 ≥ 3.2.10(2026 年起已修复部分 focus 同步逻辑)
切换后光标丢失、无法聚焦的修复逻辑
这是最常被忽略的一环:单纯切换类型不等于用户能继续输入。小程序 input 节点重建后,焦点不会自动回到输入框,必须手动触发。
注意三点:
- 必须用
uni.createSelectorQuery(),且fields({ node: true })才能拿到可操作的节点对象 - 不能在
togglePassword同步执行 query,要等$nextTick确保 DOM 已更新 - 如果用了
ref(如ref="pwdRef"),H5 可用this.$refs.pwdRef.focus(),但 App 和小程序仍需 query 路径
别省略 $nextTick,也别漏掉 res?.node 的空值判断 —— 小程序 query 是异步的,时机不对就查不到节点。


















