修改Uniapp input 组件不刷新视图问题

uni-app 的 <input> 是原生组件,外部修改 value 不会刷新视图,改 key 强制销毁重建

组件:u-input

html 复制代码
<template>
	<view class="input-wrapper">
		<!-- 用 key 强制重新渲染,解决 uni-app input 值不同步的问题 -->
		<input class="uni-input" :key="inputKey" :placeholder="placeholder" :value="value" :type="inputType"
			:password="showPassword" @input="handleInput" v-bind="$attrs" />
		<uni-icons v-if="showClearIcon" type="close" class="uni-icon" :size="iconSize" :color="iconColor"
							 @click="handleClearValue" />
		<uni-icons v-if="isPassWord" class="uni-icon" :size="iconSize" :color="iconColor" @click="changePassword"
							:type="showPassword ? 'eye-filled' : 'eye-slash-filled'"  />
	</view>
</template>

<script>
	export default {
		name: "u-input",
		inheritAttrs: false,
		props: {
			value: {
				type: [String, Number],
				default: "",
			},
			type: {
				type: String,
				default: "text",
			},
			placeholder: {
				type: String,
				default: "请输入",
			},
			iconSize:{
				type:Number,
				default:20
			},
			iconColor:{
				type:String,
				default:"#808080"
			}
		},
		data() {
			return {
				showPassword: false,
				showClearIcon: false,
				inputKey: 0, // 用于强制刷新 input
			};
		},
		computed: {
			isPassWord() {
				return this.type === "password" || this.type === "safe-password";
			},

			inputType(){
				this.showPassword = this.isPassWord
				return this.isPassWord?"":this.type
			}

		},
		watch: {
			// 监听 value 变化,保持清除按钮状态同步
			value: {
				immediate: true,
				handler(val) {
					this.showClearIcon = val && val.length > 0;
				},
			},
		},
		methods: {
			handleInput(event) {
				const val = event.detail.value;
				this.$emit("input", val);
				this.showClearIcon = val.length > 0;
			},

			handleClearValue() {
				this.$emit("input", "");
				this.showClearIcon = false;
				this.inputKey++;
			},

			changePassword() {
				this.showPassword = !this.showPassword;
			},
		},
	};
</script>

<style scoped lang="scss">
	.input-wrapper {
		display: flex;
		flex-direction: row;
		align-items: center;
		width: 100%;
	}

	.uni-input {
		flex: 1;
		width: 100%;
	}

	.uni-icon{
		margin: 0 $uni-spacing-row-sm;
	}

</style>

|---------------------------------|-----------------------------------|
| inheritAttrs: false | 阻止 $attrs 自动绑定到组件根元素 <view> 上 |
| v-bind="$attrs" 绑定到 <input> | 未在 props 中声明的属性全部透传给原生 input |

使用组件:

html 复制代码
<!-- placeholder、maxlength、disabled 等全部透传 -->
<u-input
  v-model="form.username"
  placeholder="请输入用户名"
  maxlength="20"
  :disabled="isDisabled"
  confirm-type="done"
/>

<u-input
  v-model="form.password"
  type="password"
  placeholder="请输入密码"
  maxlength="32"
/>
相关推荐
几何心凉12 小时前
没有万能模型:我用 AiiOnly Token Plan,把多款大模型的长处拼进同一个项目
前端
kyriewen13 小时前
Claude Code 的额度今天缩水了17%——官方公告上写的是"永久提高25%"
前端·ai编程·claude
雪芽蓝域zzs13 小时前
vue解构平铺VS对象包裹
前端·javascript·vue.js
风骏时光牛马14 小时前
从零到实战,完整AI学习路线
前端
三十而立洋15 小时前
深入理解 Monorepo:子包安装依赖
前端·前端工程化
IT_陈寒15 小时前
Java Stream处理大集合,我的内存怎么就炸了
前端·人工智能·后端
Captaincc15 小时前
AI 用量桌面端-桌面宠物自定义指南
前端·人工智能
OpenTiny社区15 小时前
码力全开,智启前端新生态|OpenTiny 登陆华为全联接大会2026
前端·github
妙码生花15 小时前
利用AI从零学Go并完成实战项目,完工总结:目录结构
前端·后端·go
妙码生花16 小时前
利用AI从零学Go并完成实战项目,完工总结:商业级开源产品定位和核心特性介绍
前端·后端·go