From e392ec37ff3e0918675da20233e475e89a843253 Mon Sep 17 00:00:00 2001 From: Hiroki Osame Date: Thu, 29 Mar 2018 17:38:56 +0700 Subject: [PATCH 1/3] fix(provide): Merges symbol provides Fixes merging multiple provides using Symbols fix #7923 --- src/core/util/options.js | 10 ++++++++- test/unit/features/options/inject.spec.js | 26 +++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/core/util/options.js b/src/core/util/options.js index 5f0d10d3361..eaad8daf7a5 100644 --- a/src/core/util/options.js +++ b/src/core/util/options.js @@ -4,6 +4,7 @@ import config from '../config' import { warn } from './debug' import { nativeWatch } from './env' import { set } from '../observer/index' +import { hasSymbol } from '../util/index' import { ASSET_TYPES, @@ -48,7 +49,14 @@ if (process.env.NODE_ENV !== 'production') { function mergeData (to: Object, from: ?Object): Object { if (!from) return to let key, toVal, fromVal - const keys = Object.keys(from) + + const keys = hasSymbol + ? Reflect.ownKeys(from).filter(key => { + /* istanbul ignore next */ + return Object.getOwnPropertyDescriptor(from, key).enumerable + }) + : Object.keys(from) + for (let i = 0; i < keys.length; i++) { key = keys[i] toVal = to[key] diff --git a/test/unit/features/options/inject.spec.js b/test/unit/features/options/inject.spec.js index 53f55e1ecf2..131eae63910 100644 --- a/test/unit/features/options/inject.spec.js +++ b/test/unit/features/options/inject.spec.js @@ -473,6 +473,32 @@ describe('Options provide/inject', () => { expect(injected).toEqual(['foo', 'bar']) }) + it('should merge symbol provide from mixins (functions)', () => { + const keyA = Symbol('foo') + const keyB = Symbol('bar') + + const mixinA = { provide: () => ({ [keyA]: 'foo' }) } + const mixinB = { provide: () => ({ [keyB]: 'bar' }) } + const child = { + inject: { + foo: keyA, + bar: keyB + }, + template: ``, + created () { + injected = [this.foo, this.bar] + } + } + new Vue({ + mixins: [mixinA, mixinB], + render (h) { + return h(child) + } + }).$mount() + + expect(injected).toEqual(['foo', 'bar']) + }) + it('should merge provide from mixins (mix of objects and functions)', () => { const mixinA = { provide: { foo: 'foo' }} const mixinB = { provide: () => ({ bar: 'bar' }) } From cb4014f5dd91998a1d7e36b1a1bc2848c26bc734 Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Thu, 26 Apr 2018 09:24:57 +0200 Subject: [PATCH 2/3] test: avoid Symbol test when unsupported --- test/unit/features/options/inject.spec.js | 52 +++++++++++------------ 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/test/unit/features/options/inject.spec.js b/test/unit/features/options/inject.spec.js index 131eae63910..3b47ef566f0 100644 --- a/test/unit/features/options/inject.spec.js +++ b/test/unit/features/options/inject.spec.js @@ -188,6 +188,32 @@ describe('Options provide/inject', () => { }).$mount() expect(vm.$el.textContent).toBe('123') }) + + it('should merge symbol provide from mixins (functions)', () => { + const keyA = Symbol('foo') + const keyB = Symbol('bar') + + const mixinA = { provide: () => ({ [keyA]: 'foo' }) } + const mixinB = { provide: () => ({ [keyB]: 'bar' }) } + const child = { + inject: { + foo: keyA, + bar: keyB + }, + template: ``, + created () { + injected = [this.foo, this.bar] + } + } + new Vue({ + mixins: [mixinA, mixinB], + render (h) { + return h(child) + } + }).$mount() + + expect(injected).toEqual(['foo', 'bar']) + }) } // GitHub issue #5223 @@ -473,32 +499,6 @@ describe('Options provide/inject', () => { expect(injected).toEqual(['foo', 'bar']) }) - it('should merge symbol provide from mixins (functions)', () => { - const keyA = Symbol('foo') - const keyB = Symbol('bar') - - const mixinA = { provide: () => ({ [keyA]: 'foo' }) } - const mixinB = { provide: () => ({ [keyB]: 'bar' }) } - const child = { - inject: { - foo: keyA, - bar: keyB - }, - template: ``, - created () { - injected = [this.foo, this.bar] - } - } - new Vue({ - mixins: [mixinA, mixinB], - render (h) { - return h(child) - } - }).$mount() - - expect(injected).toEqual(['foo', 'bar']) - }) - it('should merge provide from mixins (mix of objects and functions)', () => { const mixinA = { provide: { foo: 'foo' }} const mixinB = { provide: () => ({ bar: 'bar' }) } From d0115a457dc7fc5a9595d44c443fca7bc2569f88 Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 21 Dec 2018 12:27:49 -0500 Subject: [PATCH 3/3] Update options.js --- src/core/util/options.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/core/util/options.js b/src/core/util/options.js index eaad8daf7a5..3cc1dc36827 100644 --- a/src/core/util/options.js +++ b/src/core/util/options.js @@ -51,14 +51,13 @@ function mergeData (to: Object, from: ?Object): Object { let key, toVal, fromVal const keys = hasSymbol - ? Reflect.ownKeys(from).filter(key => { - /* istanbul ignore next */ - return Object.getOwnPropertyDescriptor(from, key).enumerable - }) + ? Reflect.ownKeys(from) : Object.keys(from) for (let i = 0; i < keys.length; i++) { key = keys[i] + // in case the object is already observed... + if (key === '__ob__') continue toVal = to[key] fromVal = from[key] if (!hasOwn(to, key)) {