uni-app nvue input标签使用v-if控制显示隐藏时,前一个被隐藏的input中的值会被赋到后一个出现的input上

uni-app nvue input标签使用v-if控制显示隐藏时,前一个被隐藏的input中的值会被赋到后一个出现的input上

开发环境 版本号 项目创建方式
Windows win10 HBuilderX
产品分类:uniapp/App

PC开发环境操作系统:Windows

PC开发环境操作系统版本号:win10

HBuilderX类型:正式

HBuilderX版本号:3.2.3

手机系统:Android

手机系统版本号:Android 11

手机厂商:华为

手机机型:华为nova2plus

页面类型:nvue

打包方式:离线

项目创建方式:HBuilderX

### 示例代码:

```html
<template>
<view class="page">
<image src="../../static/logo.png" mode="" class="logo"></image>
<view class="account-login-way">
<view class="list" [@click](/user/click)="tab_index=0">
<text class="text" :class="{active:tab_index==0}">账号密码登录</text>
<view class="border" :class="{active:tab_index==0}"></view>
</view>
<view class="list" [@click](/user/click)="tab_index=1">
<text class="text" :class="{active:tab_index==1}">手机验证码登录</text>
<view class="border" :class="{active:tab_index==1}"></view>
</view>
</view>
<view class="input-group">
<text class="icon"></text>
<input class="input" type="number" v-model="user_phone" placeholder="请输入手机号"/>
</view>
<view class="input-group" v-if="tab_index==0">
<text class="icon"></text>
<input class="input" v-if="tab_index==0" type="password" v-model="user_pwd" placeholder="请输入密码"/>
</view>
<view class="input-group" v-if="tab_index==1">
<text class="icon"></text>
<input class="input" type="text" v-if="tab_index==1" v-model="check_code" placeholder="请输入验证码"/>
<view class="btn-send">
<text class="btn-text">发送验证码</text>
</view>
</view>
<view class="link-box">
<text class="left" [@click](/user/click)="goForgetPassword">忘记密码?</text>
<text class="right" [@click](/user/click)="goRegister">新用户注册</text>
</view>
<view class="btn" [@click](/user/click)="login">
<text class="btn-text">登录</text>
</view>
<view class="agreements">
<view class="select-icon" [@click](/user/click)="is_agree=!is_agree">
<text class="icon" v-if="!is_agree"></text>
<text class="icon-active" v-if="is_agree"></text>
</view>
<text class="text">同意</text>
<text class="agreement-name" [@click](/user/click)="goPrivacyPolicy">《隐私政策》</text>
<text class="text">以及</text>
<text class="agreement-name" [@click](/user/click)="goServiceAgreement">《施工日志App服务协议》</text>
</view>
</view>
</template>
<template>
<script>
let that;
export default {
data() {
return {
tab_index:0,
is_agree:false,
user_phone:'',
user_pwd:'',
check_code:''
}
},
onLoad() {
that = this;
},
methods: {
/*登录*/
login(){
console.log(this.user_phone);
console.log(this.user_pwd);
if (!this.is_agree){
uni.ajax.toast('请勾选下方登录相关服务选项');
return;
}
if (!uni.checkRules.checkPhone(this.user_phone)){
uni.ajax.toast('手机号格式不正确');
return;
}
if (this.user_pwd.length<6){
uni.ajax.toast('密码最少6位');
return;
}
uni.ajax.post({
url:'/login_register/login',
loading:true,
data:{
password:that.user_phone,
username:that.user_pwd
},
success:res=>{
console.log(res);
}
});
},
/*跳转至忘记密码*/
goForgetPassword(){
uni.navigateTo({
url:'../forget-password/forget-password'
})   
},
/*跳转至注册*/
goRegister(){
uni.navigateTo({
url:'../register/register'
})
},
/*跳转至隐私政策*/
goPrivacyPolicy(){
uni.navigateTo({
url:'../rich-text-page/rich-text-page?page=privacyPolicy'
})
},
/*跳转至服务协议*/
goServiceAgreement(){
uni.navigateTo({
url:'../rich-text-page/rich-text-page?page=serviceAgreement'
})
}
}
}
</script>
.page{
width: 750rpx;
[@include](/user/include) flex('column');
}
.logo{
width: 120rpx;
height: 120rpx;
border-radius: 15rpx;
margin-top: 150rpx;
margin-bottom: 100rpx;
}
.account-login-way{
width: 600rpx;
height: 100rpx;
[@include](/user/include) flex('between');
}
.list{
width: 280rpx;
height: 100rpx;
[@include](/user/include) flex('column-center');
}
.text{
color: $color-3;
font-size: 26rpx;
&.active{
color: $color-blue;
}
}
.border{
background-color: #F8F8F8;
width: 60rpx;
height: 6rpx;
border-radius: 3rpx;
margin-top: 15rpx;
&.active{
background-color: $color-blue;
}
}
.input-group{
width: 600rpx;
height: 100rpx;
[@include](/user/include) flex('start');
border-bottom:{
width: 1rpx;
style:solid;
color: #e0e0e0;
}
.icon{
[@extend](/user/extend) %icon-font;
color: $color-9;
font-size: 36rpx;
}
.input{
height: 100rpx;
flex: 1;
margin-left: 10rpx;
font-size: 26rpx;
}
.btn-send{
width: 180rpx;
height: 70rpx;
background-color: $color-blue;
[@include](/user/include) flex('center');
border-radius: 8rpx;
[@include](/user/include) touch-darken($color-blue);
}
.btn-text{
color: white;
font-size: 30rpx;
}
}
.link-box{
width: 600rpx;
height: 100rpx;
[@include](/user/include) flex('between');
margin-top: 20rpx;
.left{
height: 100rpx;
line-height: 100rpx;
color: $color-blue;
font-size: 26rpx;
}
.right{
[@extend](/user/extend) .left;
}
}
.btn{
[@include](/user/include) btn;
margin-top: 10rpx;
}
.agreements{
width: 700rpx;
[@include](/user/include) flex('start');
margin-top: 20rpx;
}
.select-icon{
width: 80rpx;
height: 80rpx;
[@include](/user/include) flex('end');
}
.icon{
[@extend](/user/extend) %icon-font;
font-size: 30rpx;
margin-right: 10rpx;
color: $color-3;
}
.icon-active{
[@extend](/user/extend) %icon-font;
font-size: 30rpx;
margin-right: 10rpx;
color: $color-blue;
}
.text{
font-size: 26rpx;
height: 80rpx;
line-height: 80rpx;
color: $color-3;
}
.agreement-name{
font-size: 26rpx;
height: 80rpx;
line-height: 80rpx;
color: $color-blue;
}
</style>

更多关于uni-app nvue input标签使用v-if控制显示隐藏时,前一个被隐藏的input中的值会被赋到后一个出现的input上的实战教程也可以访问 https://www.itying.com/category-93-b0.html

7 回复

给input加不同的key试下

更多关于uni-app nvue input标签使用v-if控制显示隐藏时,前一个被隐藏的input中的值会被赋到后一个出现的input上的实战教程也可以访问 https://www.itying.com/category-93-b0.html


有用,同样的问题,终于解决了

请提供可稳定复现直接运行的简单完整示例(上传附件),方便我们快速排查问题哦。 【正确报bug的姿势】https://ask.dcloud.net.cn/article/38139

哎,我加你个联系方式,发给你视频吧,现象不好描述,太费劲了,玩呐?

登录功能,一个是账号密码登录(输入框有账号、密码),另一个是手机号验证码登录(输入框有手机号、验证码),从账号密码登录切换到手机号验证码登录时,密码里边输入的值会莫名其妙的跑到验证码的框子里边,我写了6年多程序了,这个不会是我个人的低级错误,头一次遇到这么古怪的bug,我上传啥例子?你们自己写一个试试就对了,三两分钟就能写完试出来,nvue的页面

这个问题是由于 nvue 页面中 input 组件在 v-if 切换时的复用机制导致的。在 nvue 中,当使用 v-if 控制 input 显示隐藏时,系统可能会复用相同的 DOM 节点,导致数据绑定出现混乱。

解决方案有以下几种:

  1. 使用 key 属性:为每个 input 添加唯一的 key 值,强制 Vue 重新创建组件
<input class="input" v-if="tab_index==0" type="password" v-model="user_pwd" placeholder="请输入密码" key="password"/>
<input class="input" v-if="tab_index==1" type="text" v-model="check_code" placeholder="请输入验证码" key="code"/>
  1. 使用 v-show 替代 v-if:v-show 只是控制显示隐藏,不会销毁和重建组件
<view class="input-group" v-show="tab_index==0">
<view class="input-group" v-show="tab_index==1">
  1. 在切换时清空数据:在切换 tab 时手动清空不需要的输入框数据
methods: {
  switchTab(index) {
    if(index === 0) {
      this.check_code = ''; // 清空验证码
    } else {
      this.user_pwd = ''; // 清空密码
    }
    this.tab_index = index;
  }
}
  1. 使用不同的容器包裹:确保两个 input 不在同一位置渲染
<view v-if="tab_index==0">
  <input class="input" type="password" v-model="user_pwd" placeholder="请输入密码"/>
</view>
<view v-if="tab_index==1">
  <input class="input" type="text" v-model="check_code" placeholder="请输入验证码"/>
</view>
回到顶部