Przeglądaj źródła

props: call default value functions with vm as the context (close #1382)

Evan You 10 lat temu
rodzic
commit
e421cb6042

+ 4 - 3
src/compiler/compile-props.js

@@ -131,7 +131,7 @@ function makePropsLinkFn (props) {
       vm._props[path] = prop
       if (raw === null) {
         // initialize absent prop
-        _.initProp(vm, prop, getDefault(options))
+        _.initProp(vm, prop, getDefault(vm, options))
       } else if (prop.dynamic) {
         // dynamic prop
         if (vm._context) {
@@ -174,11 +174,12 @@ function makePropsLinkFn (props) {
 /**
  * Get the default value of a prop.
  *
+ * @param {Vue} vm
  * @param {Object} options
  * @return {*}
  */
 
-function getDefault (options) {
+function getDefault (vm, options) {
   // no default, return undefined
   if (!options.hasOwnProperty('default')) {
     // absent boolean value defaults to false
@@ -197,6 +198,6 @@ function getDefault (options) {
   }
   // call factory function for non-Function types
   return typeof def === 'function' && options.type !== Function
-    ? def()
+    ? def.call(vm)
     : def
 }

+ 10 - 0
test/unit/specs/directives/internal/prop_spec.js

@@ -496,6 +496,12 @@ if (_.inBrowser) {
               prop: {
                 type: String,
                 default: 'hello'
+              },
+              prop2: {
+                type: Object,
+                default: function () {
+                  return { vm: this }
+                }
               }
             },
             data: function () {
@@ -508,6 +514,10 @@ if (_.inBrowser) {
         }
       })
       expect(vm.$el.textContent).toBe('hello world')
+      // object/array default value initializers should be
+      // called with the correct `this` context
+      var child = vm.$children[0]
+      expect(child.prop2.vm).toBe(child)
       vm.$children[0].prop = 'bye'
       _.nextTick(function () {
         expect(vm.$el.textContent).toBe('bye world')