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

do not warn instantiation data that overlap with props

Evan You 10 лет назад
Родитель
Сommit
93c1a50b89

+ 7 - 0
src/instance/internal/init.js

@@ -81,6 +81,13 @@ export default function (Vue) {
       this.$parent.$children.push(this)
     }
 
+    // save raw constructor data before merge
+    // so that we know which properties are provided at
+    // instantiation.
+    if (process.env.NODE_ENV !== 'production') {
+      this._runtimeData = options.data
+    }
+
     // merge options.
     options = this.$options = mergeOptions(
       this.constructor.options,

+ 9 - 1
src/instance/internal/state.js

@@ -80,11 +80,19 @@ export default function (Vue) {
     var propsData = this._data
     var optionsDataFn = this.$options.data
     var optionsData = optionsDataFn && optionsDataFn()
+    var runtimeData
+    if (process.env.NODE_ENV !== 'production') {
+      runtimeData = (typeof this._runtimeData === 'function'
+        ? this._runtimeData()
+        : this._runtimeData) || {}
+      this._runtimeData = null
+    }
     if (optionsData) {
       this._data = optionsData
       for (var prop in propsData) {
         if (process.env.NODE_ENV !== 'production' &&
-            hasOwn(optionsData, prop)) {
+            hasOwn(optionsData, prop) &&
+            !hasOwn(runtimeData, prop)) {
           warn(
             'Data field "' + prop + '" is already defined ' +
             'as a prop. Use prop default value instead.'

+ 22 - 2
test/unit/specs/directives/internal/prop_spec.js

@@ -562,16 +562,36 @@ describe('prop', function () {
   })
 
   it('should warn data fields already defined as a prop', function () {
+    var Comp = Vue.extend({
+      data: function () {
+        return { a: 123 }
+      },
+      props: {
+        a: null
+      }
+    })
     new Vue({
+      el: el,
+      template: '<comp a="1"></comp>',
+      components: {
+        comp: Comp
+      }
+    })
+    expect(hasWarned('already defined as a prop')).toBe(true)
+  })
+
+  it('should not warn data fields already defined as a prop if it is from instantiation call', function () {
+    var vm = new Vue({
       el: el,
       props: {
         a: null
       },
       data: {
-        a: 1
+        a: 123
       }
     })
-    expect(hasWarned('already defined as a prop')).toBe(true)
+    expect(getWarnCount()).toBe(0)
+    expect(vm.a).toBe(123)
   })
 
   it('should not warn for non-required, absent prop', function () {