By Noxxxx from https://www.noxxxx.com/?post_type=post&p=431
欢迎分享与聚合,尊重版权,可以联系授权
目前为止,自己只在指令中使用到这个方法,贴下源码解读。
"use strict"; var vueFocus = {} vueFocus.config = {} vueFocus.install = function(Vue) { Vue.directive('focus',{ bind: function(el,binding) { }, update: function(el,binding) { if(binding.value && binding.value.flag) { Vue.nextTick(function () { el.focus(); //el.value = binding.value.value //使用后会无法编辑input }); } } }) } module.exports = vueFocus;
源码部分:其实源码上的注释已经讲的比较明白了,首先返回一个闭包函数,它会将 nextTick 传入的函数 缓存进 callback 的数组中,如果没有其它函数
/** * Defer a task to execute it asynchronously. * */ export const nextTick = (function () { const callbacks = [] //缓存回调数组 let pending = false //是否正在执行flag let timerFunc //要执行的函数 function nextTickHandler () { pending = false const copies = callbacks.slice(0) //复制函数 callbacks.length = 0 for (let i = 0; i < copies.length; i++) { copies[i]() //依次执行 } } // 此处做了兼容处理,首先调用promise.then 来达到延迟调用 // the nextTick behavior leverages the microtask queue, which can be accessed // via either native Promise.then or MutationObserver. // MutationObserver has wider support, however it is seriously bugged in // UIWebView in iOS >= 9.3.3 when triggered in touch event handlers. It // completely stops working after triggering a few times... so, if native // Promise is available, we will use it: /* istanbul ignore if */ if (typeof Promise !== 'undefined' && isNative(Promise)) { var p = Promise.resolve() var logError = err => { console.error(err) } timerFunc = () => { p.then(nextTickHandler).catch(logError) // 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) } } else if (typeof MutationObserver !== 'undefined' && ( //其次使用 html5 新增的 MutationObserver 来监听 DOM 操作结束 isNative(MutationObserver) || // PhantomJS and iOS 7.x MutationObserver.toString() === '[object MutationObserverConstructor]' )) { // use MutationObserver where native Promise is not available, // e.g. PhantomJS IE11, iOS7, Android 4.4 var counter = 1 var observer = new MutationObserver(nextTickHandler) var textNode = document.createTextNode(String(counter)) observer.observe(textNode, { characterData: true }) timerFunc = () => { counter = (counter + 1) % 2 textNode.data = String(counter) } } else { //利用setTimeout,setTimeout(func, 0)会将func函数延迟到下一次函数调用栈的开始,也就是当前函数执行完毕后再执行该函数,因此完成了延迟功能。 // fallback to setTimeout /* istanbul ignore next */ 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() } if (!cb && typeof Promise !== 'undefined') { //如果不传函数,则可以使用 $nextTick().then()的这种方法 return new Promise((resolve, reject) => { _resolve = resolve }) } } })()
估计走错方向了 好TM累啊
vue 2.0中我希望一次性渲染数据,之后不进行任何绑定。目前我用render动态生成dom,但是怎样才可以做到类似insertBefore的效果
卡在这里半个月了 好难过啊
@Pang created()方法不能满足你?至于绑定,没有设置v-model这些就不会有绑定一说啊
@vicient 有一个list是异步请求获取保存在data的,我之前是v-for输出到input, 每当data数据改变,input会重新v-for渲染 .我是想v-for之后就不要管以前的数据了 新获取的值在头部插入即可
大大的文章不错,已经收藏,望回访!