{"record":{"id":"23bb705bce1403d1","repo":"Meituan-Dianping/mpvue","slug":"props-is-readonly","errorCode":null,"errorMessage":"$props is readonly.","messagePattern":"\\$props is readonly\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/weex-vue-framework/factory.js","lineNumber":3315,"sourceCode":"\nfunction stateMixin (Vue) {\n  // flow somehow has problems with directly declared definition object\n  // when using Object.defineProperty, so we have to procedurally build up\n  // the object here.\n  var dataDef = {};\n  dataDef.get = function () { return this._data };\n  var propsDef = {};\n  propsDef.get = function () { return this._props };\n  if (process.env.NODE_ENV !== 'production') {\n    dataDef.set = function (newData) {\n      warn(\n        'Avoid replacing instance root $data. ' +\n        'Use nested data properties instead.',\n        this\n      );\n    };\n    propsDef.set = function () {\n      warn(\"$props is readonly.\", this);\n    };\n  }\n  Object.defineProperty(Vue.prototype, '$data', dataDef);\n  Object.defineProperty(Vue.prototype, '$props', propsDef);\n\n  Vue.prototype.$set = set;\n  Vue.prototype.$delete = del;\n\n  Vue.prototype.$watch = function (\n    expOrFn,\n    cb,\n    options\n  ) {\n    var vm = this;\n    if (isPlainObject(cb)) {\n      return createWatcher(vm, expOrFn, cb, options)\n    }\n    options = options || {};","sourceCodeStart":3297,"sourceCodeEnd":3333,"githubUrl":"https://github.com/Meituan-Dianping/mpvue/blob/6c5d78ee04f58c6d782c456dfcf0fe63c0b7f89b/packages/weex-vue-framework/factory.js#L3297-L3333","documentation":"Vue exposes the component's props as a read-only `$props` object on the instance. In development builds, a setter is defined on `$props` that fires this warning if any code attempts to assign to it. Props are owned by the parent component, so mutating them from the child would break one-way data flow.","triggerScenarios":"Any assignment like `this.$props = {...}`, `vm.$props.foo = x` triggering the setter (only the wholesale assignment triggers the setter), or destructuring-and-reassigning `$props` inside a component method, lifecycle hook, or mixin.","commonSituations":"Developers trying to 'reset' props after a parent update, old Vue 1.x code migrated to Vue 2 that mutated props directly, or generated/compiled render code accidentally writing to `$props`.","solutions":["Remove the assignment to `this.$props`; treat it as strictly read-only.","If you need local editable state seeded from props, copy into `data` (e.g. `data() { return { local: this.someProp } }`).","To change a prop's value, emit an event to the parent (`this.$emit('update:x', v)`) or use `v-model`/`.sync` so the parent updates it."],"exampleFix":"// before\nthis.$props = { ...this.$props, title: 'new' };\n// after\nthis.$emit('update:title', 'new');","handlingStrategy":"validation","validationCode":"if (import.meta.env.MODE !== 'production' && myCodeAssignsToProps) {\n  throw new Error('Never assign to this.$props; emit an event instead');\n}","typeGuard":"function isReadOnlyPropsRef(target) {\n  return target && target.$props !== undefined && Object.getOwnPropertyDescriptor(Vue.prototype, '$props').set !== undefined;\n}","tryCatchPattern":null,"preventionTips":["Treat $props as immutable; lint with eslint-plugin-vue's no-mutating-props rule.","Copy props into data for local editing.","Communicate changes upward with $emit."],"tags":["vue","props","reactivity","dev-warning"],"backgroundTag":"readonly-props-mutation","analyzedSha":"6c5d78ee04f58c6d782c456dfcf0fe63c0b7f89b","analyzedAt":"2026-09-02T05:17:40.946Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T11:17:12.671Z"}