Meituan-Dianping/mpvue · warning

method "${key}" has already been defined as a prop.

Error message

method "${key}" has already been defined as a prop.

What it means

Vue dev-mode warning from initMethods when a method name is also declared in the props option. Since methods are bound to the instance after props, the method assignment would overwrite the prop, so Vue warns about the conflict (the method still binds to the instance key).

Source

Thrown at src/core/instance/state.js:249

    }
  }
}

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. ` +
          `Did you reference the function correctly?`,
          vm
        )
      }
      if (props && hasOwn(props, key)) {
        warn(
          `method "${key}" has already been defined as a prop.`,
          vm
        )
      }
    }
  }
}

function initWatch (vm: Component, watch: Object) {
  process.env.NODE_ENV !== 'production' && checkOptionType(vm, 'watch')
  for (const key in watch) {
    const handler = watch[key]
    if (Array.isArray(handler)) {
      for (let i = 0; i < handler.length; i++) {
        createWatcher(vm, key, handler[i])
      }
    } else {
      createWatcher(vm, key, handler)

View on GitHub (pinned to 6c5d78ee04)

Solutions

  1. Rename the method to a non-colliding name
  2. Rename the prop if it is internal-only and not part of the public API
  3. Invoke the prop callback from a differently named method instead of replacing it

Example fix

// before
export default {
  props: ['submit'],
  methods: { submit() { this.submit && this.submit(this.value) } }
}
// after
export default {
  props: ['submit'],
  methods: { handleSubmit() { this.$emit('submit', this.value) } }
}
Defensive patterns

Strategy: validation

Validate before calling

function checkMethodPropsCollision(options) {
  const propKeys = (options.props || []).concat(Object.keys(options.props || {}))
  return Object.keys(options.methods || {}).filter(k => propKeys.includes(k))
}

Type guard

function hasNoMethodPropsCollision(options) { return checkMethodPropsCollision(options).length === 0 }

Prevention

When it happens

Trigger: Declaring the same key in props and methods, e.g. props:['submit'] plus methods:{submit(){...}}; mixin merge adding a method that collides with an existing prop.

Common situations: Generic prop names like 'change', 'submit', 'open' colliding with handler methods of the same name; converting a callback prop into an internal method without renaming.

Related errors


AI-assisted analysis of Meituan-Dianping/mpvue@6c5d78ee04 (2026-09-02). Data as JSON: /api/errors/387aee52086e825b. Report an issue: GitHub.