Meituan-Dianping/mpvue · warning

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

Error message

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

What it means

Vue iterates data keys and warns if a key collides with an existing method name. The method and reactive data property would fight over the same instance property, so Vue flags the ambiguity; the data proxy still wins on the instance.

Source

Thrown at packages/weex-vue-framework/factory.js:3148

    : data || {};
  if (!isPlainObject(data)) {
    data = {};
    process.env.NODE_ENV !== 'production' && warn(
      'data functions should return an object:\n' +
      'https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function',
      vm
    );
  }
  // proxy data on instance
  var keys = Object.keys(data);
  var props = vm.$options.props;
  var methods = vm.$options.methods;
  var i = keys.length;
  while (i--) {
    var key = keys[i];
    if (process.env.NODE_ENV !== 'production') {
      if (methods && hasOwn(methods, key)) {
        warn(
          ("method \"" + key + "\" has already been defined as a data property."),
          vm
        );
      }
    }
    if (props && hasOwn(props, key)) {
      process.env.NODE_ENV !== 'production' && warn(
        "The data property \"" + key + "\" is already declared as a prop. " +
        "Use prop default value instead.",
        vm
      );
    } else if (!isReserved(key)) {
      proxy(vm, "_data", key);
    }
  }
  // observe data
  observe(data, true /* asRootData */);
}

View on GitHub (pinned to 6c5d78ee04)

Solutions

  1. Rename the data property or the method so names are unique
  2. Check merged mixins/extends for name collisions
  3. If the value should be stateful, delete the methods entry; if derived, use computed instead of data

Example fix

// before
methods: { load() {} },
data() { return { load: true }; }
// after
methods: { load() {} },
data() { return { isLoading: true }; }
Defensive patterns

Strategy: validation

Validate before calling

function checkDataMethodCollisions(options) {
  const methods = options.methods || {};
  const dataKeys = Object.keys(typeof options.data === 'function' ? options.data() : (options.data || {}));
  return dataKeys.filter(k => k in methods);
}

Prevention

When it happens

Trigger: A component defines methods.foo and data() { return { foo: ... } } at the same time — checkKeys is populated with data keys and hasOwn(methods, key) matches.

Common situations: Refactoring data into methods (or vice versa) and leaving the old declaration, mixin merge introducing a method that shares a name with a data key, or inheritance of a base component's methods.

Related errors


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