uni-app input组件@blur+v-model或@blur+:value时值更新界面不更新问题,可能是严重UBG,valueSync未更新,App和小程序出现概率高

uni-app input组件@blur+v-model或@blur+:value时值更新界面不更新问题,可能是严重UBG,valueSync未更新,App和小程序出现概率高

开发环境 版本号 项目创建方式
Windows 18363.778 HBuilderX

示例代码:

小程序

<evan-form-item vue-id="{{('2efbf9ec-5')+','+('2efbf9ec-2')}}" label="楼层:" prop class="data-v-69ac2100"  
bind:__l="__l" vue-slots="{{['default']}}"  
>  
<cell-view vue-id="{{('2efbf9ec-6')+','+('2efbf9ec-5')}}" mode="slot" class="data-v-69ac2100" bind:__l="__l"  
vue-slots="{{['default']}}"  
>  
<view class="num-input data-v-69ac2100">  
<view class="data-v-69ac2100">  
<view style="flex:1;" class="data-v-69ac2100">  
<input class="text-center data-v-69ac2100" placeholder="请输入"  
type="text" maxlength="5"  
data-event-opts="{{[['blur',[['numBlur',['$event','beginFloor',-10]]]],['input',[['__set_model',['$0','beginFloor','$event',[]],['form']]]]]}}"  
value="{{form.beginFloor}}" bindblur="__e" bindinput="__e" />  
</view>  
<text class="data-v-69ac2100">~</text>  
<view style="flex:1;" class="data-v-69ac2100">  
<input class="text-center data-v-69ac2100" type="text"  
placeholder="请输入" maxlength="5"  
data-event-opts="{{[['blur',[['numBlur',['$event','endFloor',-10]]]]]}}" value="{{form.endFloor}}"  
bindblur="__e" />  
</view>  
<view class="num-unit data-v-69ac2100">层</view>  
</view>  
</view>  
</cell-view>  
</evan-form-item>  
numBlur: function (e, t, n) {  
var o = this,  
i = e.detail.value;  
console.log(Number(i).toString()), "NaN" === Number(i).toString() && (i = ""), "" !== i && void 0 !== n && Number(i) < n && (i = String(n), this.msg("不能小于" + i)), setTimeout((function () {  
o.form[t] = i  
}))  
},

### 操作步骤:


源码

```html
<evan-form-item label="楼层:" prop="">
  <cell-view mode="slot">
    <view class="num-input">
      <view>
        <view style="flex:1">
          <input class="text-center" placeholder="请输入" type="text" [@blur](/user/blur)="numBlur($event,'beginFloor',-10)"  
                 maxlength="5"  
                 v-model="form.beginFloor"/>
        </view>
        <text> ~</text>
        <view style="flex:1">
          <input class="text-center" type="text" placeholder="请输入" [@blur](/user/blur)="numBlur($event,'endFloor',-10)"  
                 maxlength="5"  
                 v-model="form.endFloor"/>
        </view>
        <view class="num-unit"> 层</view>
      </view>
    </view>
  </cell-view>
</evan-form-item>
numBlur(e, f, min) {
  let v = e.detail.value
  console.log(Number(v).toString())
  if (Number(v).toString() === 'NaN')
    v = ''
  if (v !== '' && min !== undefined && Number(v) < min) {
    v = String(min)
    this.msg('不能小于' + v)
  }

  setTimeout(() => {
    this.form[f] = v
  })
}

### 预期结果:


界面值应当更新

实际结果:

部分为更新,小程序下完全不更新


### bug描述:


input组件[@blur](/user/blur)+v-model,或者[@blur](/user/blur)+:value,会出现值更新,界面不更新问题,好像有个valueSync未更新,App和小程序出现概率高。
原生小程序写法bindblur + value是正常的

更多关于uni-app input组件@blur+v-model或@blur+:value时值更新界面不更新问题,可能是严重UBG,valueSync未更新,App和小程序出现概率高的实战教程也可以访问 https://www.itying.com/category-93-b0.html

13 回复

求助啊

更多关于uni-app input组件@blur+v-model或@blur+:value时值更新界面不更新问题,可能是严重UBG,valueSync未更新,App和小程序出现概率高的实战教程也可以访问 https://www.itying.com/category-93-b0.html


延迟赋值

setTimeout加到500也是有问题的,已经是异步赋值了,浏览器,app,小程序表现不一,我弄了个demo,加在了下方评论,测试结果见下方评论

测试结果,浏览器基本正常,app多次输入后出现异常(见视频),小程序开发工具完全无效,见附图(附图)。源码:input-bug-test

+1,有没人测试一下~

你的 form 为空对象,你把具体的属性在定义的时候写上
form: {
beginFloor: ‘’
}

是的,我都忘了,以前小程序是需要的,小程序是需要先初始化值,初始化后,结果v-model 可以,:value不行。除此之外,浏览器和APP怎么解释,这两个可不是微信小程序特有的,截图见下方评论

我想知道valueSync是干嘛用的,浏览器vue-devtool下看到input组件有这个值,很可能跟这个值有关

答复“APP 怎么解释”APP和 h5 的差异是因为架构并不太相同,存在部分缺陷。答复“valueSync是干嘛”组件内部的状态,看下组件源码就明白了:https://github.com/dcloudio/uni-app/blob/master/src/core/view/components/input/index.vue

回复 DCloud_UNI_GSQ: 那这个算是bug吗?小程序:value + blur有问题,app也有问题,这不是构架的问题,app和浏览器都是谷歌内核吧,这是组件有问题吧。我看了源码,valueSync没有初始化,不知道是不是跟这个有关,但我找不到uni-mixins,无法调试,方便提供下这个东西的地址吗,github太卡,下载uni-app.git太卡,github搜不到

这里指的就是 uni-app 框架缺陷,另外不用纠结valueSync,问题不在这里。如果确认 h5 和 APP 存在差异,算作 bug,不过处理优先级并不高。

初始化值后的附图

这是一个典型的 uni-app 数据绑定时序问题。问题根源在于 @blur 事件和 v-model 的数据更新机制冲突。

问题分析:

  1. v-model 本质是 :value + [@input](/user/input) 的语法糖
  2. 当同时使用 @blurv-model 时,@blur 中修改数据会与 v-model 的更新机制产生竞争
  3. 在小程序和 App 端,这种时序问题更容易出现,因为渲染机制与 Web 不同

解决方案:

  1. 移除 v-model,改用 :value + @input
<input 
  class="text-center" 
  placeholder="请输入" 
  type="text" 
  :value="form.beginFloor"
  [@input](/user/input)="form.beginFloor = $event.detail.value"
  @blur="numBlur($event,'beginFloor',-10)"
  maxlength="5"
/>
  1. 在 blur 事件中使用 $nextTick
numBlur(e, f, min) {
  let v = e.detail.value
  if (Number(v).toString() === 'NaN') v = ''
  if (v !== '' && min !== undefined && Number(v) < min) {
    v = String(min)
    this.msg('不能小于' + v)
  }
  
  this.$nextTick(() => {
    this.form[f] = v
  })
}
  1. 使用异步更新确保数据同步
setTimeout(() => {
  this.form[f] = v
  this.$forceUpdate() // 强制更新视图
})
回到顶部