patch的基础函数:
function createRmCb (childElm, listeners) { function remove () { if (--remove.listeners === 0) { removeNode(childElm); } } remove.listeners = listeners; return remove return function patch (oldVnode, vnode, hydrating, removeOnly) { //oldVode一般是原生dom, vnode 是虚拟dom // 把oldVnode转换成虚拟dom. oldVnode = emptyNodeAt(oldVnode) // 获取虚拟dom对原生dom的引用 var oldElm = oldVnode.elm; }
}
once函数:
// 对通过once包装的fn,仅仅调用一次 once (fn) { var called = false; return function () { if (!called) { called = true; fn.apply(this, arguments); } } }
cbs.remove函数
remove: function remove (vnode, rm) { /* istanbul ignore else */ if (vnode.data.show !== true) { leave(vnode, rm); } else { rm(); // createRmCb中的回调中的remove。
} }
leave函数:
function leave (vnode, rm) { var el = vnode.elm; // call enter callback now if (isDef(el._enterCb)) { el._enterCb.cancelled = true; el._enterCb(); } var data = resolveTransition(vnode.data.transition); if (isUndef(data) || el.nodeType !== 1) { return rm() } /* istanbul ignore if */ if (isDef(el._leaveCb)) { return } var css = data.css; var type = data.type; var leaveClass = data.leaveClass; var leaveToClass = data.leaveToClass; var leaveActiveClass = data.leaveActiveClass; var beforeLeave = data.beforeLeave; var leave = data.leave; var afterLeave = data.afterLeave; var leaveCancelled = data.leaveCancelled; var delayLeave = data.delayLeave; var duration = data.duration; var expectsCSS = css !== false && !isIE9; var userWantsControl = getHookArgumentsLength(leave); var explicitLeaveDuration = toNumber( isObject(duration) ? duration.leave : duration ); if ( isDef(explicitLeaveDuration)) { checkDuration(explicitLeaveDuration, 'leave', vnode); } var cb = el._leaveCb = once(function () { if (el.parentNode && el.parentNode._pending) { el.parentNode._pending[vnode.key] = null; } if (expectsCSS) { removeTransitionClass(el, leaveToClass); removeTransitionClass(el, leaveActiveClass); } if (cb.cancelled) { if (expectsCSS) { removeTransitionClass(el, leaveClass); } leaveCancelled && leaveCancelled(el); } else { rm(); afterLeave && afterLeave(el); } el._leaveCb = null; }); if (delayLeave) { delayLeave(performLeave); } else { performLeave(); }