We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Vue.nextTick([callback, context])
官方定义:在下次DOM更新循环结束后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的DOM。
nextTick是Vue提供的一个全局api,由于vue的异步跟新策略导致我们对数据的修改不会立刻体现在dom变化,此时如果想立即获取更新后的dom状态,就需要使用这个方法。
Vue在更新DOM时是异步执行的,只要侦听到数据变化,Vue将开启一个队列,并缓冲在同一事件循环(eventloop)中发生的所有数据变更。nextTick方法会在队列加入一个回调函数,确保该函数在前面的dom操作完成后才调用。 nextTick源码主要分为两块:能力检测和根据能力检测使用不同方式执行回调队列。
/* globals MutationObserver */ import { noop } from 'shared/util' import { handleError } from './error' // 是否是IE、ios、原生内置函数 import { isIE, isIOS, isNative } from './env' export let isUsingMicroTask = false const callbacks = [] let pending = false function flushCallbacks () { pending = false const copies = callbacks.slice(0) callbacks.length = 0 for (let i = 0; i < copies.length; i++) { copies[i]() } } let timerFunc // 检测promise浏览器是否支持,优先使用promise if (typeof Promise !== 'undefined' && isNative(Promise)) { const p = Promise.resolve() timerFunc = () => { p.then(flushCallbacks) // In problematic UIWebViews, Promise.then doesn't completely break, but // it can get stuck in a weird state where callbacks are pushed into the // microtask queue but the queue isn't being flushed, until the browser // needs to do some other work, e.g. handle a timer. Therefore we can // "force" the microtask queue to be flushed by adding an empty timer. if (isIOS) setTimeout(noop) } isUsingMicroTask = true } else if (!isIE && typeof MutationObserver !== 'undefined' && ( isNative(MutationObserver) || // PhantomJS and iOS 7.x MutationObserver.toString() === '[object MutationObserverConstructor]' )) { // 原生promise不可用时,使用原生MutationObserver // Use MutationObserver where native Promise is not available, // e.g. PhantomJS, iOS7, Android 4.4 // (#6466 MutationObserver is unreliable in IE11) let counter = 1 const observer = new MutationObserver(flushCallbacks) const textNode = document.createTextNode(String(counter)) observer.observe(textNode, { characterData: true }) timerFunc = () => { counter = (counter + 1) % 2 textNode.data = String(counter) } isUsingMicroTask = true } else if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) { // Fallback to setImmediate. // Technically it leverages the (macro) task queue, // but it is still a better choice than setTimeout. timerFunc = () => { setImmediate(flushCallbacks) } } else { // Fallback to setTimeout. timerFunc = () => { setTimeout(flushCallbacks, 0) } } export function nextTick (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 => { _resolve = resolve }) } }
延迟调用优先级:Promise > MutationObserver > setImmediate > setTimeout
The text was updated successfully, but these errors were encountered:
No branches or pull requests
一、nextTick是干什么的?
Vue.nextTick([callback, context])
nextTick是Vue提供的一个全局api,由于vue的异步跟新策略导致我们对数据的修改不会立刻体现在dom变化,此时如果想立即获取更新后的dom状态,就需要使用这个方法。
二、nextTick原理
Vue在更新DOM时是异步执行的,只要侦听到数据变化,Vue将开启一个队列,并缓冲在同一事件循环(eventloop)中发生的所有数据变更。nextTick方法会在队列加入一个回调函数,确保该函数在前面的dom操作完成后才调用。
nextTick源码主要分为两块:能力检测和根据能力检测使用不同方式执行回调队列。
由于宏任务耗费的时间是大于微任务的,所以在浏览器支持的情况下,优先使用微任务。如果浏览器不支持微任务,再使用宏任务。
源码具体如下:
src/core/util/next-tick.js
The text was updated successfully, but these errors were encountered: