Meituan-Dianping/mpvue · warning

The computed property "${key}" is already defined in data.

Error message

The computed property "${key}" is already defined in data.

What it means

Vue dev-mode warning thrown by initComputed when a computed property name collides with a key already present in the instance's data. Since data is initialized before computed, the computed would shadow or be shadowed by the data property, creating ambiguous reactivity. Vue refuses to define the computed and warns instead.

Source

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

      if (getter === undefined) {
        warn(
          `No getter function has been defined for computed property "${key}".`,
          vm
        )
        getter = noop
      }
    }
    // create internal watcher for the computed property.
    watchers[key] = new Watcher(vm, getter, noop, computedWatcherOptions)

    // component-defined computed properties are already defined on the
    // component prototype. We only need to define computed properties defined
    // at instantiation here.
    if (!(key in vm)) {
      defineComputed(vm, key, userDef)
    } else if (process.env.NODE_ENV !== 'production') {
      if (key in vm.$data) {
        warn(`The computed property "${key}" is already defined in data.`, vm)
      } else if (vm.$options.props && key in vm.$options.props) {
        warn(`The computed property "${key}" is already defined as a prop.`, vm)
      }
    }
  }
}

export function defineComputed (target: any, key: string, userDef: Object | Function) {
  if (typeof userDef === 'function') {
    sharedPropertyDefinition.get = createComputedGetter(key)
    sharedPropertyDefinition.set = noop
  } else {
    sharedPropertyDefinition.get = userDef.get
      ? userDef.cache !== false
        ? createComputedGetter(key)
        : userDef.get
      : noop
    sharedPropertyDefinition.set = userDef.set

View on GitHub (pinned to 6c5d78ee04)

Solutions

  1. Rename the computed property so it no longer collides with the data key
  2. Remove the data field if the computed fully replaces it
  3. If the data field is needed raw, expose the computed under a derived name
  4. Check merged mixins for overlapping computed/data keys

Example fix

// before
export default {
  data() { return { total: 0 } },
  computed: { total() { return this.items.length } }
}
// after
export default {
  computed: { totalCount() { return this.items.length } }
}
Defensive patterns

Strategy: validation

Validate before calling

function checkComputedDataCollision(options) {
  const dataKeys = typeof options.data === 'function' ? Object.keys(options.data()) : Object.keys(options.data || {})
  return Object.keys(options.computed || {}).filter(k => dataKeys.includes(k))
}
// if (checkComputedDataCollision(myOptions).length) fix names before mounting

Type guard

function hasNoComputedDataCollision(options) { return checkComputedDataCollision(options).length === 0 }

Prevention

When it happens

Trigger: Declaring the same key in both the data option and the computed option of a component or root instance; e.g. data(){return{total:0}} plus computed:{total(){...}}. Also occurs when a mixin or plugin merges in a computed that clashes with existing data.

Common situations: Renaming refactors that leave a stale data field; merging mixins where each side defines overlapping keys; adding a computed with a name matching a common data field like 'loading' or 'items'.

Related errors


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