Просмотр исходного кода

fix(provide/inject): Merges symbol provides (#7926)

Hiroki Osame 7 лет назад
Родитель
Сommit
1933ee80ff
2 измененных файлов с 34 добавлено и 1 удалено
  1. 8 1
      src/core/util/options.js
  2. 26 0
      test/unit/features/options/inject.spec.js

+ 8 - 1
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,9 +49,15 @@ 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)
+    : 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)) {

+ 26 - 0
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: `<span/>`,
+        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