Meituan-Dianping/mpvue · warning
$props is readonly.
Error message
$props is readonly.
What it means
Vue dev-mode warning triggered by the $props setter installed in stateMixin. Props are owned by the parent component; mutating or replacing them from the child would break one-way data flow, so Vue makes $props read-only and warns on any assignment.
Source
Thrown at src/core/instance/state.js:305
export function stateMixin (Vue: Class<Component>) {
// flow somehow has problems with directly declared definition object
// when using Object.defineProperty, so we have to procedurally build up
// the object here.
const dataDef = {}
dataDef.get = function () { return this._data }
const propsDef = {}
propsDef.get = function () { return this._props }
if (process.env.NODE_ENV !== 'production') {
dataDef.set = function (newData: Object) {
warn(
'Avoid replacing instance root $data. ' +
'Use nested data properties instead.',
this
)
}
propsDef.set = function () {
warn(`$props is readonly.`, this)
}
}
Object.defineProperty(Vue.prototype, '$data', dataDef)
Object.defineProperty(Vue.prototype, '$props', propsDef)
Vue.prototype.$set = set
Vue.prototype.$delete = del
Vue.prototype.$watch = function (
expOrFn: string | Function,
cb: any,
options?: Object
): Function {
const vm: Component = this
if (isPlainObject(cb)) {
return createWatcher(vm, expOrFn, cb, options)
}
options = options || {}View on GitHub (pinned to 6c5d78ee04)
Solutions
- Assign to a local data property initialized from the prop, then mutate that
- Emit an event to the parent and let the parent update the prop
- Use a computed that transforms the prop instead of writing back to it
Example fix
// before
mounted() { this.$props.count = 0 }
// after
export default {
props: ['count'],
data() { return { localCount: this.count } }
} Defensive patterns
Strategy: fallback
Validate before calling
function isPropWrite(vm, key) { return vm.$options && key in (vm.$options.props || {}) } Type guard
function canAssignToInstance(vm, key) { return !(vm.$options && key in (vm.$options.props || {})) } Prevention
- Treat all props as read-only in child components
- Copy prop values into local data when mutation is needed
- Communicate upward with $emit for prop changes
When it happens
Trigger: this.$props = {...}; vm.$props.someProp = value; or generic code that loops over instance keys and assigns (e.g. deep-cloning state back onto the instance).
Common situations: Trying to 'localize' or edit prop values instead of copying them into data; deserialization/restore routines that blindly assign all collected keys; misunderstanding one-way data flow in child components.
Related errors
- Avoid mutating a prop directly since the value will be overw
- $props is readonly.
- The computed property "${key}" is already defined as a prop.
- The data property "${key}" is already declared as a prop. Us
- The computed property "${key}" is already defined as a prop.
AI-assisted analysis of Meituan-Dianping/mpvue@6c5d78ee04 (2026-09-02).
Data as JSON: /api/errors/3e0ca16bb96d6fd3.
Report an issue: GitHub.