nextTick是Vue绕不开的一个方法,nextTick的实现变了,莫名的bug就会出现,再举一个例子。
首先,Vue升级引发nextTick的bug(一)/)提到,Vue2.5.2中的nextTick是宏任务 -> 微任务 -> 宏任务交替触发,先使用宏任务。而Vue2.6.10中nextTick全部使用微任务。
我们的场景是view中有一个form组件,其内部有一个input-number组件。用户填写完信息后submit。
顺便介绍一下input-number,可以参考el-input-number,返回值是数字,当输入其他非法类型时,回弹为上一次有效数字。这一过程会在nextTick中完成。
submit的入参为params {num: string}。为啥num要传string,额~~ 一言难尽。
如何将input-number组件的数字num,转成字符串呢,form组件中有个方法来处理数据transData
。
每次reactive的数据变化都会触发nextTick。
所以提交动作的事件流为:
submit -> $refs.form.transData() -> axios request
但是,input-number为form的子组件,当子组件值变化时,会改变form中的值,引用传递,不用多讲啦。
所以Vue2.5.2完整的事件流为:
submit -> $refs.form.transData() -> axios request -> num回弹为数字
axios的拦截器中是使用promise来处理数据,promise的then为微任务。
而根据上一篇的讨论, num值的变化是在nextTick中完成的。所以当Vue升级成2.6.10,nextTick变成微任务后,事件流为:
submit -> num回弹为数字 -> $refs.form.transData() -> axios request
从console中可以看到,在Vue2.5.2中是先axios请求,然后值回弹为数字,所以发送的num为字符串,符合预期。
而升级为Vue2.6.10后,会先回弹,再发送数据,所以发送的num为数字,bug出现。