Meituan-Dianping/mpvue · warning

Avoid mutating a prop directly since the value will be overw

Error message

Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "${key}"

What it means

Vue warns when you assign directly to a prop (e.g. this.myProp = x) because props are reactive values owned by the parent; any parent re-render overwrites the mutation. In dev mode, defineReactive installs a setter watcher on each prop that fires this warning when the component's own code writes to it.

Source

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

  // instead of dynamic object key enumeration.
  var keys = vm.$options._propKeys = [];
  var isRoot = !vm.$parent;
  // root instance props should be converted
  observerState.shouldConvert = isRoot;
  var loop = function ( key ) {
    keys.push(key);
    var value = validateProp(key, propsOptions, propsData, vm);
    /* istanbul ignore else */
    if (process.env.NODE_ENV !== 'production') {
      if (isReservedAttribute(key) || config.isReservedAttr(key)) {
        warn(
          ("\"" + key + "\" is a reserved attribute and cannot be used as component prop."),
          vm
        );
      }
      defineReactive$$1(props, key, value, function () {
        if (vm.$parent && !isUpdatingChildComponent) {
          warn(
            "Avoid mutating a prop directly since the value will be " +
            "overwritten whenever the parent component re-renders. " +
            "Instead, use a data or computed property based on the prop's " +
            "value. Prop being mutated: \"" + key + "\"",
            vm
          );
        }
      });
    } else {
      defineReactive$$1(props, key, value);
    }
    // static props are already proxied on the component's prototype
    // during Vue.extend(). We only need to proxy props defined at
    // instantiation here.
    if (!(key in vm)) {
      proxy(vm, "_props", key);
    }
  };

View on GitHub (pinned to 6c5d78ee04)

Solutions

  1. Use a local data property initialized from the prop and mutate that instead
  2. Define a computed property with a getter on the prop and a setter that emits an event to the parent
  3. Emit an event ($emit('input', val)) and let the parent update the prop via v-model or explicit binding
  4. If mutating an object/array prop's contents is intentional, suppress via a local deep copy or document the mutation

Example fix

// before
props: ['count'],
created() { this.count = 10; }
// after
props: ['count'],
data() { return { localCount: this.count }; },
created() { this.localCount = 10; }
Defensive patterns

Strategy: validation

Validate before calling

function assertNoPropMutation(component, props) {
  props.forEach(p => {
    if (component[p] !== undefined) {
      console.warn(`Avoid writing to prop '${p}'; use a local data copy.`);
    }
  });
}

Prevention

When it happens

Trigger: Assigning to a declared prop inside the child component, e.g. this.title = 'new' in a lifecycle hook, method, watcher, or v-model on a prop without a local proxy.

Common situations: Trying to make a prop two-way bindable, mutating an object/array prop's reference, v-model="someProp" in the child's template, or migrating Vue 1 code that allowed two-way prop binding.

Related errors


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