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
求助啊
更多关于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
的数据更新机制冲突。
问题分析:
v-model
本质是:value
+[@input](/user/input)
的语法糖- 当同时使用
@blur
和v-model
时,@blur
中修改数据会与v-model
的更新机制产生竞争 - 在小程序和 App 端,这种时序问题更容易出现,因为渲染机制与 Web 不同
解决方案:
- 移除 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"
/>
- 在 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
})
}
- 使用异步更新确保数据同步
setTimeout(() => {
this.form[f] = v
this.$forceUpdate() // 强制更新视图
})