在工作中遇到了一个需求:在input框中实时监测用户输入的内容,只能是数字,如果不是数字,就返回默认值。
-
用input事件监听用户输入的内容,但是发现如果用户输入的不是数字,在返回默认值的时候出了问题。
- 这里在赋值的时候在控制台看是赋值成功的,但是页面中还是一个错误的值,并不是返回的那个默认值。
想到了$nextTick(),开始查阅资料。
- Vue的官方文档异步更新队列的介绍
可能你还没有注意到,Vue 异步执行 DOM 更新。 只要观察到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据改变。 如果同一个 watcher 被多次触发,只会被推入到队列中一次。 这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作上非常重要。 然后,在下一个的事件循环“tick”中,Vue 刷新队列并执行实际 (已去重的) 工作。 Vue 在内部尝试对异步队列使用原生的 Promise.then 和 MessageChannel, 如果执行环境不支持,会采用 setTimeout(fn, 0) 代替。 例如,当你设置 vm.someData = 'new value' ,该组件不会立即重新渲染。 当刷新队列时,组件会在事件循环队列清空时的下一个“tick”更新。 多数情况我们不需要关心这个过程,但是如果你想在 DOM 状态更新后做点什么,这就可能会有些棘手。 虽然 Vue.js 通常鼓励开发人员沿着“数据驱动”的方式思考,避免直接接触 DOM,但是有时我们确实要这么做。 为了在数据变化之后等待 Vue 完成更新 DOM ,可以在数据变化之后立即使用 Vue.nextTick(callback) 。 这样回调函数在 DOM 更新完成后就会调用。
- vue在修改数据后,视图不会立刻更新,而是等同一事件循环中的所有数据变化完之后,再统一进行视图更新。
- 草稿
数据改变开启异步更新队列,随之产生两个时间循环。第一个事件循环去处理重复数据, 减少不必要的计算和DOM操作;第二个事件循环刷新队列,并执行已去重的工作。
- 使用场景
1. 在数据变化后要执行的某个操作,而这个操作需要使用随数据改变而改变的DOM结构的时候。 2. 需要在试图更新之后,基于新的试图进行操作。
- 作用:如果你想在 DOM 状态更新后做点什么,那么就需要用到$nextTick()去知道什么时候DOM更新完成。
综上所述,解决办法如下:
- 上边的赋值虽然是成功的,但是没有渲染到页面上面,是因为用的是oninput事件,这个时候DOM还没有渲染完成,所以就需要用到$nextTick()来监听什么时候DOM更新完成。
- 更改事件,改为keyup或者keydown事件就不需要用$nextTick()
- 反正只要不用@input事件就都解决了。