From 6a78acc72c5f2059421a1af295ce527079c24848 Mon Sep 17 00:00:00 2001 From: Kuitos Date: Thu, 2 Aug 2018 16:57:04 +0800 Subject: [PATCH] fix: reconcile the overridden prototype of component with _Vue mixins --- packages/create-instance/create-instance.js | 18 ++++++++++++++++-- test/specs/mount.spec.js | 4 ++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/packages/create-instance/create-instance.js b/packages/create-instance/create-instance.js index b67629514..a18e681fe 100644 --- a/packages/create-instance/create-instance.js +++ b/packages/create-instance/create-instance.js @@ -126,9 +126,23 @@ export default function createInstance ( component.options._base = _Vue } + function getExtendedComponent (component, instanceOptions) { + const extendedComponent = component.extend(instanceOptions) + // to keep the possible overridden prototype and _Vue mixins, + // we need change the proto chains manually + // @see https://github.com/vuejs/vue-test-utils/pull/856 + // code below equals to + // `extendedComponent.prototype.__proto__.__proto__ = _Vue.prototype` + const extendedComponentProto = + Object.getPrototypeOf(extendedComponent.prototype) + Object.setPrototypeOf(extendedComponentProto, _Vue.prototype) + + return extendedComponent + } + // extend component from _Vue to add properties and mixins - const Constructor = typeof component === 'function' && vueVersion < 2.3 - ? component.extend(instanceOptions) + const Constructor = typeof component === 'function' + ? getExtendedComponent(component, instanceOptions) : _Vue.extend(component).extend(instanceOptions) Object.keys(instanceOptions.components || {}).forEach(key => { diff --git a/test/specs/mount.spec.js b/test/specs/mount.spec.js index 955f107a7..f033f8e78 100644 --- a/test/specs/mount.spec.js +++ b/test/specs/mount.spec.js @@ -153,14 +153,14 @@ describeRunIf(process.env.TEST_ENV !== 'node', 'mount', () => { expect(stub).not.called }) - it.skip('overrides component prototype', () => { + it('overrides component prototype', () => { const mountSpy = sinon.spy() const destroySpy = sinon.spy() const Component = Vue.extend({}) const { $mount: originalMount, $destroy: originalDestroy } = Component.prototype Component.prototype.$mount = function (...args) { - mountSpy() originalMount.apply(this, args) + mountSpy() return this } Component.prototype.$destroy = function () {