From ad765ac771b8feeb1dc7a9d8412345a8198ae321 Mon Sep 17 00:00:00 2001 From: Anton Korzunov Date: Fri, 25 May 2018 17:47:40 +1000 Subject: [PATCH] add a new option to control element comparison (#1007) --- src/options.js | 11 +++++++++++ src/vdom/component.js | 6 +++--- src/vdom/diff.js | 1 - src/vdom/index.js | 13 ++++++++++++- 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/options.js b/src/options.js index 86c1b08b4d..f90febf605 100644 --- a/src/options.js +++ b/src/options.js @@ -18,6 +18,17 @@ export default { */ //vnode(vnode) { } + /** + * Compares two Components + * @param {Component} component1 First Component to compare + * @param {Component} component2 Second Component to compare + * @returns Boolean, true if components are equal + */ + areComponentsEqual(component1, component2) { + // default implementation is 4x times faster than optional object property access + return component1 === component2; + } + /** Hook invoked after a component is mounted. */ // afterMount(component) { } diff --git a/src/vdom/component.js b/src/vdom/component.js index aa534358b2..72f2f9ea63 100644 --- a/src/vdom/component.js +++ b/src/vdom/component.js @@ -2,7 +2,7 @@ import { SYNC_RENDER, NO_RENDER, FORCE_RENDER, ASYNC_RENDER, ATTR_KEY } from '.. import options from '../options'; import { extend } from '../util'; import { enqueueRender } from '../render-queue'; -import { getNodeProps } from './index'; +import { areComponentsEqual, getNodeProps } from './index'; import { diff, mounts, diffLevel, flushMounts, recollectNodeTree, removeChildren } from './diff'; import { createComponent, collectComponent } from './component-recycler'; import { removeNode } from '../dom/index'; @@ -212,11 +212,11 @@ export function buildComponentFromVNode(dom, vnode, context, mountAll) { let c = dom && dom._component, originalComponent = c, oldDom = dom, - isDirectOwner = c && dom._componentConstructor===vnode.nodeName, + isDirectOwner = c && areComponentsEqual(dom._componentConstructor, vnode.nodeName), isOwner = isDirectOwner, props = getNodeProps(vnode); while (c && !isOwner && (c=c._parentComponent)) { - isOwner = c.constructor===vnode.nodeName; + isOwner = areComponentsEqual(c.constructor, vnode.nodeName); } if (c && isOwner && (!mountAll || c._component)) { diff --git a/src/vdom/diff.js b/src/vdom/diff.js index 8f740ea510..11f198012e 100644 --- a/src/vdom/diff.js +++ b/src/vdom/diff.js @@ -29,7 +29,6 @@ export function flushMounts() { } } - /** * Apply differences in a given vnode (and it's deep children) to a real DOM Node. * @param {Element} [dom=null] A DOM node to mutate into the shape of the `vnode` diff --git a/src/vdom/index.js b/src/vdom/index.js index d3a6e8199e..e4df3c6f27 100644 --- a/src/vdom/index.js +++ b/src/vdom/index.js @@ -1,5 +1,16 @@ import { extend } from '../util'; +import options from '../options'; +/** + * Checks that two components are equal + * @param {Component} component1 First component to compare + * @param {Component} component2 Second component to compare + * @return {boolean} + * @private + */ +export function areComponentsEqual(component1, component2) { + return options.areComponentsEqual(component1, component2); +} /** * Check if two nodes are equivalent. @@ -16,7 +27,7 @@ export function isSameNodeType(node, vnode, hydrating) { if (typeof vnode.nodeName==='string') { return !node._componentConstructor && isNamedNode(node, vnode.nodeName); } - return hydrating || node._componentConstructor===vnode.nodeName; + return hydrating || areComponentsEqual(node._componentConstructor, vnode.nodeName); }