nexttick(如何使用VuenextTick)

2025-03-03 04:50:32 :1

nexttick(如何使用VuenextTick)

大家好,今天小编来为大家解答以下的问题,关于nexttick,如何使用VuenextTick这个很多人还不知道,现在让我们一起来看看吧!

本文目录

如何使用VuenextTick

这次给大家带来如何使用Vue nextTick,使用Vue nextTick的注意事项有哪些,下面就是实战案例,一起来看一下。export default { data () { return { msg: 0 } }, mounted () { this.msg = 1 this.msg = 2 this.msg = 3 }, watch: { msg () { console.log(this.msg) } }}这段脚本执行我们猜测1000m后会依次打印:1、2、3。但是实际效果中,只会输出一次:3。为什么会出现这样的情况?我们来一探究竟。queueWatcher我们定义 watch 监听 msg ,实际上会被Vue这样调用 vm.$watch(keyOrFn, handler, options) 。 $watch 是我们初始化的时候,为 vm 绑定的一个函数,用于创建 Watcher 对象。那么我们看看 Watcher 中是如何处理 handler 的:this.deep = this.user = this.lazy = this.sync = false... update () { if (this.lazy) { this.dirty = true } else if (this.sync) { this.run() } else { queueWatcher(this) } }...初始设定 this.deep = this.user = this.lazy = this.sync = false ,也就是当触发 update 更新的时候,会去执行 queueWatcher 方法:const queue: Array《Watcher》 = let has: { : ?true } = {}let waiting = falselet flushing = false...export function queueWatcher (watcher: Watcher) { const id = watcher.id if (has == null) { has = true if (!flushing) { queue.push(watcher) } else { // if already flushing, splice the watcher based on its id // if already past its id, it will be run next immediately. let i = queue.length - 1 while (i 》 index && queue.id 》 watcher.id) { i-- } queue.splice(i + 1, 0, watcher) } // queue the flush if (!waiting) { waiting = true nextTick(flushSchedulerQueue) } }}这里面的 nextTick(flushSchedulerQueue) 中的 flushSchedulerQueue 函数其实就是 watcher 的视图更新:function flushSchedulerQueue () { flushing = true let watcher, id ... for (index = 0; index 《 queue.length; index++) { watcher = queue id = watcher.id has = null watcher.run() ... }}另外,关于 waiting 变量,这是很重要的一个标志位,它保证 flushSchedulerQueue 回调只允许被置入 callbacks 一次。 接下来我们来看看 nextTick 函数,在说 nexTick 之前,需要你对 Event Loop 、 microTask 、 macroTask 有一定的了解,Vue nextTick 也是主要用到了这些基础原理。如果你还不了解,可以参考我的这篇文章 Event Loop 简介 好了,下面我们来看一下他的实现:export const nextTick = (function () { const callbacks = let pending = false let timerFunc function nextTickHandler () { pending = false const copies = callbacks.slice(0) callbacks.length = 0 for (let i = 0; i 《 copies.length; i++) { copies() } } // An asynchronous deferring mechanism. // In pre 2.4, we used to use microtasks (Promise/MutationObserver) // but microtasks actually has too high a priority and fires in between // supposedly sequential events (e.g. #4521, #6690) or even between // bubbling of the same event (#6566). Technically setImmediate should be // the ideal choice, but it’s not available everywhere; and the only polyfill // that consistently queues the callback after all DOM events triggered in the // same loop is by using MessageChannel. /* istanbul ignore if */ if (typeof setImmediate !== ’undefined’ && isNative(setImmediate)) { timerFunc = () =》 { setImmediate(nextTickHandler) } } else if (typeof MessageChannel !== ’undefined’ && ( isNative(MessageChannel) || // PhantomJS MessageChannel.toString() === ’’ )) { const channel = new MessageChannel() const port = channel.port2 channel.port1.onmessage = nextTickHandler timerFunc = () =》 { port.postMessage(1) } } else /* istanbul ignore next */ if (typeof Promise !== ’undefined’ && isNative(Promise)) { // use microtask in non-DOM environments, e.g. Weex const p = Promise.resolve() timerFunc = () =》 { p.then(nextTickHandler) } } else { // fallback to setTimeout timerFunc = () =》 { setTimeout(nextTickHandler, 0) } } return function queueNextTick (cb?: Function, ctx?: Object) { let _resolve callbacks.push(() =》 { if (cb) { try { cb.call(ctx) } catch (e) { handleError(e, ctx, ’nextTick’) } } else if (_resolve) { _resolve(ctx) } }) if (!pending) { pending = true timerFunc() } // $flow-disable-line if (!cb && typeof Promise !== ’undefined’) { return new Promise((resolve, reject) =》 { _resolve = resolve }) } }})()首先Vue通过 callback 数组来模拟事件队列,事件队里的事件,通过 nextTickHandler 方法来执行调用,而何事进行执行,是由 timerFunc 来决定的。我们来看一下 timeFunc 的定义:if (typeof setImmediate !== ’undefined’ && isNative(setImmediate)) { timerFunc = () =》 { setImmediate(nextTickHandler) } } else if (typeof MessageChannel !== ’undefined’ && ( isNative(MessageChannel) || // PhantomJS MessageChannel.toString() === ’’ )) { const channel = new MessageChannel() const port = channel.port2 channel.port1.onmessage = nextTickHandler timerFunc = () =》 { port.postMessage(1) } } else /* istanbul ignore next */ if (typeof Promise !== ’undefined’ && isNative(Promise)) { // use microtask in non-DOM environments, e.g. Weex const p = Promise.resolve() timerFunc = () =》 { p.then(nextTickHandler) } } else { // fallback to setTimeout timerFunc = () =》 { setTimeout(nextTickHandler, 0) } }可以看出 timerFunc 的定义优先顺序 macroTask --》 microTask ,在没有 Dom 的环境中,使用 microTask ,比如weexsetImmediate、MessageChannel VS setTimeout我们是优先定义 setImmediate 、 MessageChannel 为什么要优先用他们创建macroTask而不是setTimeout? HTML5中规定setTimeout的最小时间延迟是4ms,也就是说理想环境下异步回调最快也是4ms才能触发。Vue使用这么多函数来模拟异步任务,其目的只有一个,就是让回调异步且尽早调用。而MessageChannel 和 setImmediate 的延迟明显是小于setTimeout的。解决问题有了这些基础,我们再看一遍上面提到的问题。因为 Vue 的事件机制是通过事件队列来调度执行,会等主进程执行空闲后进行调度,所以先回去等待所有的进程执行完成之后再去一次更新。这样的性能优势很明显,比如:现在有这样的一种情况,mounted的时候test的值会被++循环执行1000次。 每次++时,都会根据响应式触发 setter-》Dep-》Watcher-》update-》run 。 如果这时候没有异步更新视图,那么每次++都会直接操作DOM更新视图,这是非常消耗性能的。 所以Vue实现了一个 queue 队列,在下一个Tick(或者是当前Tick的微任务阶段)的时候会统一执行 queue 中 Watcher 的run。同时,拥有相同id的Watcher不会被重复加入到该queue中去,所以不会执行1000次Watcher的run。最终更新视图只会直接将test对应的DOM的0变成1000。 保证更新视图操作DOM的动作是在当前栈执行完以后下一个Tick(或者是当前Tick的微任务阶段)的时候调用,大大优化了性能。有趣的问题var vm = new Vue({ el: ’#example’, data: { msg: ’begin’, }, mounted () { this.msg = ’end’ console.log(’1’) setTimeout(() =》 { // macroTask console.log(’3’) }, 0) Promise.resolve().then(function () { //microTask console.log(’promise!’) }) this.$nextTick(function () { console.log(’2’) }) }})这个的执行顺序想必大家都知道先后打印:1、promise、2、3。因为首先触发了 this.msg = ’end’ ,导致触发了 watcher 的 update ,从而将更新操作callback push进入vue的事件队列。this.$nextTick 也为事件队列push进入了新的一个callback函数,他们都是通过 setImmediate --》 MessageChannel --》 Promise --》 setTimeout 来定义 timeFunc 。而 Promise.resolve().then 则是microTask,所以会先去打印promise。在支持 MessageChannel 和 setImmediate 的情况下,他们的执行顺序是优先于 setTimeout 的(在IE11/Edge中,setImmediate延迟可以在1ms以内,而setTimeout有最低4ms的延迟,所以setImmediate比setTimeout(0)更早执行回调函数。其次因为事件队列里,优先收入callback数组)所以会打印2,接着打印3但是在不支持 MessageChannel 和 setImmediate 的情况下,又会通过 Promise 定义 timeFunc ,也是老版本Vue 2.4 之前的版本会优先执行 promise 。这种情况会导致顺序成为了:1、2、promise、3。因为this.msg必定先会触发dom更新函数,dom更新函数会先被callback收纳进入异步时间队列,其次才定义 Promise.resolve().then(function () { console.log(’promise!’)}) 这样的microTask,接着定义 $nextTick 又会被callback收纳。我们知道队列满足先进先出的原则,所以优先去执行callback收纳的对象。相信看了本文案例你已经掌握了方法,更多精彩请关注Gxl网其它相关文章!推荐阅读:如何操作JS实现透明度渐变动画怎样操作JS实现简单折叠展开动画

this.$nextTick()怎么使用

应用场景 : this.$nextTick() 方法主要是用在 随数据改变而改变的dom应用场景中 ,vue中数据和dom渲染由于是异步的,所以,要让dom结构随数据改变这样的操作都应该放进this. $nextTick() 的回调函数中。 created()中使用的方法时,dom还没有渲染,如果此时在该钩子函数中进行dom赋值数据(或者其它dom操作)时无异于徒劳,所以, created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中 ,而与created()对应的是mounted()的钩子函数则是在dom完全渲染后才开始渲染数据,所以在mounted()中操作dom基本不会存在渲染问题。

简单的理解,vue.js中this.$nextTick()就是起到了一个等待数据的作用,也就是说,将一些回调延迟,等到DOM更新之后再开始执行。简单点说,相当于setTimeout()的作用。

例如: 1.你改变了dom元素数据,然后你又想输出dom,那你只能等到dom更新完成之后才会实现. 2.通过事件改变data数据,然后输出dom,在方法里直接打印的话, 由于dom元素还没有更新, 因此打印出来的还是未改变之前的值,而通过this.$nextTick()获取到的值为dom更新之后的值.

如何使用VuenextTick的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于如何使用VuenextTick、如何使用VuenextTick的信息别忘了在本站进行查找哦。

nexttick(如何使用VuenextTick)

本文编辑:admin
: nexttick,

更多文章:


红旗l9和l5哪个档次更高(红旗l9和l5哪个档次更高)

红旗l9和l5哪个档次更高(红旗l9和l5哪个档次更高)

本文目录红旗l9和l5哪个档次更高红旗l系列购买条件红旗l5和l9谁是国宾车中国“第一车“原来有三个版本,如何区分红旗L5、L7和L9为什么买红旗L9要政审,红旗l9没有身份买不了吗红旗l9和l5哪个档次更高红旗I9的档次要高于红旗15,I

2024年9月28日 11:40

中国十大卫浴品牌(中国卫浴十大名牌)

中国十大卫浴品牌(中国卫浴十大名牌)

中国卫浴十大名牌2022年中国卫浴十大名牌:1、日丰卫浴日丰卫浴是日丰企业集团旗下品牌,总部位于中国陶瓷名都——佛山。2002年日丰集团推出卫浴五金产品,产品涵盖卫浴五金陶瓷洁具、浴室柜、淋浴房、浴缸、玻璃胶等全系列卫浴产品线,能够全面满足

2025年1月30日 18:10

s2全球总决赛队伍(s4世界冠军成员现在分别在什么战队)

s2全球总决赛队伍(s4世界冠军成员现在分别在什么战队)

本文目录s4世界冠军成员现在分别在什么战队S2全球总决赛的冠军是谁lpl全球冠军哪国多英雄联盟s2全球总决赛的亚军是s2冠军是五个中国人吗英雄联盟s2冠军是谁s4世界冠军成员现在分别在什么战队S1:欧洲Fnatic战队;S2台北暗杀星战队;

2024年11月12日 05:20

联想yoga13论坛(联想yoga-13 开机黑屏,只有鼠标,怎么办)

联想yoga13论坛(联想yoga-13 开机黑屏,只有鼠标,怎么办)

联想yoga-13 开机黑屏,只有鼠标,怎么办尊敬的联想用户您好:请您通过Ctrl+Alt+Ddl”按键调出任务管理器,切换到”进程”选项卡,找到Explorer.exe并单击”结束进程”,这时系统会给出一个警告,直接选”是”即可. 然后文

2024年12月25日 13:00

三星电视tizen刷安卓(如何安装最新泰泽系统)

三星电视tizen刷安卓(如何安装最新泰泽系统)

三星电视泰泽系统如何安装第三方软件?2022三星电视app安装腾讯视频投屏2.安卓手机的多屏互动这个方法适用于安卓手机,”三星智能电视怎么安装第三方软件三星智能电视下载安装软件的方法:2015年:按电视遥控器【SMART HUB】键进入智能

2024年3月4日 05:30

oppo reno4手机图片(OPPO Reno4价格是多少,值得吗)

oppo reno4手机图片(OPPO Reno4价格是多少,值得吗)

本文目录OPPO Reno4价格是多少,值得吗OPPO Reno4什么时候上市的opporeno4的参数配置pdrm00是什么型号手机reno4上市时间reno4参数配置图片pdpm00是oppo什么手机OPPO Reno4 系列的实际体验

2024年9月25日 20:40

a380座位分布图(空客A380紧急出口在哪排)

a380座位分布图(空客A380紧急出口在哪排)

本文目录空客A380紧急出口在哪排机票里A和L是不是靠窗的座位要坐南航A380了,请问坐位选哪里舒服空客320座位图,哪个舒服中国南航(CZ6403) 机型: 321,在网上选了座位38K,是个什么位置,在机翼上吗国航 空客 36A大概是什

2024年4月10日 21:00

canon相机拍照按什么键(canon单反相机eos拍摄键是那个)

canon相机拍照按什么键(canon单反相机eos拍摄键是那个)

本文目录canon单反相机eos拍摄键是那个佳能单反怎么拍照佳能4000d按哪个是拍照canon单反相机eos拍摄键是那个单反的快门键都在一个位置,如图红箭头所示。快门按键用于拍摄照片,当半按时会先启动自动对焦,当完全合焦后按下快门进行拍摄

2024年6月8日 16:30

松京DS02除湿机怎么使用?家用除湿机哪个牌子好

松京DS02除湿机怎么使用?家用除湿机哪个牌子好

本文目录松京DS02除湿机怎么使用家用除湿机哪个牌子好松京与海尔除湿机哪个好松京除湿机外壳怎么拆下来松京除湿机怎么样啊除湿机什么牌子好十大名牌除湿机排行榜家庭除湿机什么品牌好松京dl150e除湿机湿度设置松京除湿机cnt怎么灭了松京DS02

2024年9月17日 13:10

iphone越狱后能升级系统吗(ios16越狱后能更新吗)

iphone越狱后能升级系统吗(ios16越狱后能更新吗)

本文目录ios16越狱后能更新吗越狱苹果手机系统怎么不能更新了正版的iphone越狱后想要用itunes升级固件可不可以iphone越狱了还能升级系统吗,升级了之后会怎样越狱的iphone可以直接升级吗苹果越狱后还可以升级吗苹果手机,越狱了

2024年5月4日 00:00

联想g470奔腾(联想G470 CPU是奔腾B940的 做PS CDR 会不会卡或者说慢)

联想g470奔腾(联想G470 CPU是奔腾B940的 做PS CDR 会不会卡或者说慢)

本文目录联想G470 CPU是奔腾B940的 做PS CDR 会不会卡或者说慢我的是联想G470,奔腾处理器内存是DDR1333的2G,刚买一个金士顿DDR1600的2G内存条,可以一起用么联想G470处理器有奔腾的吗求助卡基,联想G470

2024年12月3日 18:40

乐视被谁收购了(贾跃亭同意60.41亿出售乐视网1.71亿股无限售流通股了吗)

乐视被谁收购了(贾跃亭同意60.41亿出售乐视网1.71亿股无限售流通股了吗)

贾跃亭同意60.41亿出售乐视网1.71亿股无限售流通股了吗8月31日消息,融创中国晚间发布公告称贾跃亭同意向天津嘉睿出售乐视网1.71亿股无限售流通股,应付代价合计为人民币60.41亿元。早在今年1月13日,贾跃亭在引入战略投资者融创时,

2024年12月21日 18:10

我想知道风力发电公司例如(歌美飒,丹麦vestas)中工作常用的英文词汇?麻烦问一下歌美飒(天津)有限公司的总经理叫什么,如果有英文名也要还有他们的老板叫什么

我想知道风力发电公司例如(歌美飒,丹麦vestas)中工作常用的英文词汇?麻烦问一下歌美飒(天津)有限公司的总经理叫什么,如果有英文名也要还有他们的老板叫什么

本文目录我想知道风力发电公司例如(歌美飒,丹麦vestas)中工作常用的英文词汇麻烦问一下歌美飒(天津)有限公司的总经理叫什么,如果有英文名也要还有他们的老板叫什么我想知道风力发电公司例如(歌美飒,丹麦vestas)中工作常用的英文词汇看你

2024年6月8日 02:40

老式三星数码相机型号价格(三星i8数码相机现在要多少人民币)

老式三星数码相机型号价格(三星i8数码相机现在要多少人民币)

三星i8数码相机现在要多少人民币三星i85参考价格:1800元商家报价:1780至2320元三星I8参考价格:1780元商家报价:1680至1800元三星i70参考价格:1590元商家报价:1510至2450元三星i7参考价格:1700元商

2024年12月14日 21:30

mx940相当于什么显卡(笔记本电脑独显940MX是什么级别的显卡)

mx940相当于什么显卡(笔记本电脑独显940MX是什么级别的显卡)

本文目录笔记本电脑独显940MX是什么级别的显卡nvidia geforce 940mx是独显还是集显小米笔记本的gt940mx是什么显卡,英伟达出过这款笔记本显卡吗,x是什么NvIDIAGeForce940M相当什么显卡笔电显卡gefor

2024年10月23日 23:30

500元性价比之王(500元的显卡推荐)

500元性价比之王(500元的显卡推荐)

本文目录500元的显卡推荐500元以内有哪些酒值得送礼500元左右的礼物有哪些岳父爱喝白酒,五百块以内送什么酒性价比高又不失面子500左右可以买什么样的智能手机用500元买什么白酒比较好500左右的实战篮球鞋该如何选择想买个跑鞋,500左右

2024年10月18日 10:50

二手努比亚z17多少钱(努比亚Z17价格多少钱 努比亚Z17什么时候上市)

二手努比亚z17多少钱(努比亚Z17价格多少钱 努比亚Z17什么时候上市)

本文目录努比亚Z17价格多少钱 努比亚Z17什么时候上市努比亚Z17畅享版多少钱努比亚z17价格是多少努比亚z178g版多少钱努比亚Z17现在卖价格多少钱 努比亚Z17现价多少努比亚z17多少钱怎么样 努比亚z17评测最新消息努比亚 z17

2024年4月7日 05:10

iphone7发热已解决(iPhone发烫是什么原因 怎样解决)

iphone7发热已解决(iPhone发烫是什么原因 怎样解决)

iPhone发烫是什么原因 怎样解决一、iPhone发烫是什么原因我们先来了解一下iPhone发烫的原因:CPU运行被众多垃圾占满,导致CPU温度升高。手机高运转高输入数据,也会导致发热,状态是越来越热的。据新闻报道手持式装置的表面温度最高

2025年2月5日 11:30

乐2刷机包下载官方(乐视2手机怎么刷miui官方系统)

乐2刷机包下载官方(乐视2手机怎么刷miui官方系统)

本文目录乐视2手机怎么刷miui官方系统乐视手机2变砖怎么办 乐2官方recovery刷机救砖升级教程乐视手机2 官方固件刷机包在哪儿下载谁有下载地址发一个吧 谢谢 要官方原版 无root的乐视max2怎么恢复官方recovery乐视超级手

2024年4月18日 22:10

齐心考勤机mt620修改时间(齐心牌mt620t打卡机怎么调整日期)

齐心考勤机mt620修改时间(齐心牌mt620t打卡机怎么调整日期)

齐心牌mt620t打卡机怎么调整日期把左边下方的设置键拨到右边,就可以进行设置了。第一组参数是年,左边加减号是调整按钮,选择好就第三个按钮“确定”分别设置,年月日时分秒,然后设置到了上午上、下班时间,下午、夜班。(我设置到夜班就把左边下方的

2024年12月30日 11:40