Procházet zdrojové kódy

chore: warn methods that conflict with internals

close #6312
Evan You před 8 roky
rodič
revize
8fc6bc8827

+ 10 - 4
src/core/instance/state.js

@@ -137,7 +137,7 @@ function initData (vm: Component) {
     if (process.env.NODE_ENV !== 'production') {
       if (methods && hasOwn(methods, key)) {
         warn(
-          `method "${key}" has already been defined as a data property.`,
+          `Method "${key}" has already been defined as a data property.`,
           vm
         )
       }
@@ -260,22 +260,28 @@ function initMethods (vm: Component, methods: Object) {
   process.env.NODE_ENV !== 'production' && checkOptionType(vm, 'methods')
   const props = vm.$options.props
   for (const key in methods) {
-    vm[key] = methods[key] == null ? noop : bind(methods[key], vm)
     if (process.env.NODE_ENV !== 'production') {
       if (methods[key] == null) {
         warn(
-          `method "${key}" has an undefined value in the component definition. ` +
+          `Method "${key}" has an undefined value in the component definition. ` +
           `Did you reference the function correctly?`,
           vm
         )
       }
       if (props && hasOwn(props, key)) {
         warn(
-          `method "${key}" has already been defined as a prop.`,
+          `Method "${key}" has already been defined as a prop.`,
           vm
         )
       }
+      if ((key in vm) && isReserved(key)) {
+        warn(
+          `Method "${key}" conflicts with an existing Vue instance method. ` +
+          `Avoid defining component methods that start with _ or $.`
+        )
+      }
     }
+    vm[key] = methods[key] == null ? noop : bind(methods[key], vm)
   }
 }
 

+ 11 - 2
test/unit/features/options/methods.spec.js

@@ -25,7 +25,7 @@ describe('Options methods', () => {
         hello: undefined
       }
     })
-    expect(`method "hello" has an undefined value in the component definition`).toHaveBeenWarned()
+    expect(`Method "hello" has an undefined value in the component definition`).toHaveBeenWarned()
   })
 
   it('should warn methods conflicting with data', () => {
@@ -37,6 +37,15 @@ describe('Options methods', () => {
         foo () {}
       }
     })
-    expect(`method "foo" has already been defined as a data property`).toHaveBeenWarned()
+    expect(`Method "foo" has already been defined as a data property`).toHaveBeenWarned()
+  })
+
+  it('should warn methods conflicting with internal methods', () => {
+    new Vue({
+      methods: {
+        _update () {}
+      }
+    })
+    expect(`Method "_update" conflicts with an existing Vue instance method`).toHaveBeenWarned()
   })
 })

+ 1 - 1
test/unit/features/options/props.spec.js

@@ -333,7 +333,7 @@ describe('Options props', () => {
         }
       }
     }).$mount()
-    expect(`method "a" has already been defined as a prop`).toHaveBeenWarned()
+    expect(`Method "a" has already been defined as a prop`).toHaveBeenWarned()
     expect(`Avoid mutating a prop directly`).toHaveBeenWarned()
   })