{"record":{"id":"68e522fc0a2aed37","repo":"Meituan-Dianping/mpvue","slug":"avoid-using-observed-data-object-as-vnode-data","errorCode":null,"errorMessage":"Avoid using observed data object as vnode data: ${JSON.stringify(data)}\nAlways create fresh vnode data objects in each render!","messagePattern":"Avoid using observed data object as vnode data: (.+?)\nAlways create fresh vnode data objects in each render!","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/weex-vue-framework/factory.js","lineNumber":3713,"sourceCode":"    normalizationType = children;\n    children = data;\n    data = undefined;\n  }\n  if (isTrue(alwaysNormalize)) {\n    normalizationType = ALWAYS_NORMALIZE;\n  }\n  return _createElement(context, tag, data, children, normalizationType)\n}\n\nfunction _createElement (\n  context,\n  tag,\n  data,\n  children,\n  normalizationType\n) {\n  if (isDef(data) && isDef((data).__ob__)) {\n    process.env.NODE_ENV !== 'production' && warn(\n      \"Avoid using observed data object as vnode data: \" + (JSON.stringify(data)) + \"\\n\" +\n      'Always create fresh vnode data objects in each render!',\n      context\n    );\n    return createEmptyVNode()\n  }\n  // object syntax in v-bind\n  if (isDef(data) && isDef(data.is)) {\n    tag = data.is;\n  }\n  if (!tag) {\n    // in case of component :is set to falsy value\n    return createEmptyVNode()\n  }\n  // warn against non-primitive key\n  if (process.env.NODE_ENV !== 'production' &&\n    isDef(data) && isDef(data.key) && !isPrimitive(data.key)\n  ) {","sourceCodeStart":3695,"sourceCodeEnd":3731,"githubUrl":"https://github.com/Meituan-Dianping/mpvue/blob/6c5d78ee04f58c6d782c456dfcf0fe63c0b7f89b/packages/weex-vue-framework/factory.js#L3695-L3731","documentation":"Vue's `createElement` (the `h` function) expects a fresh plain object as the vnode's `data` argument. If the object passed is an observed reactive object (it has an `__ob__` property), Vue warns and renders an empty vnode instead, because reusing observed objects as vnode data corrupts patching.","triggerScenarios":"Returning a piece of reactive `data` (e.g. `h('div', this.someDataObject)`) or a store/props object that has been made reactive directly into the second argument of `h()`/`createElement`.","commonSituations":"Storing vnode-data templates in component data for reuse; passing Vuex state objects straight as vnode data; caching render metadata in reactive state after a refactor.","solutions":["Create a fresh object literal in each render: `h('div', { attrs: {...} })`.","Clone the needed values: `h('div', { ...this.cachedData })` or `JSON.parse(JSON.stringify(...))` for deep copies.","Move the cached config out of reactive `data` into a non-reactive property or module-level constant.","Use `Object.freeze` on configuration objects so Vue never observes them (frozen objects get no `__ob__`)."],"exampleFix":"// before\nh('div', this.nodeData)\n// after\nh('div', { attrs: { ...this.nodeData.attrs } })","handlingStrategy":"validation","validationCode":"function assertFreshVnodeData(data) {\n  if (data != null && data.__ob__) {\n    throw new Error('Observed object passed as vnode data; create a fresh object');\n  }\n}","typeGuard":"function isObserved(obj) {\n  return obj != null && typeof obj === 'object' && '__ob__' in obj;\n}","tryCatchPattern":null,"preventionTips":["Never pass reactive data/props/store objects directly as the `h()` data argument.","Spread or reconstruct vnode data inside render.","Freeze static config objects with Object.freeze so Vue cannot observe them."],"tags":["vue","vdom","reactivity","render-function","dev-warning"],"backgroundTag":"observed-object-as-vnode-data","analyzedSha":"6c5d78ee04f58c6d782c456dfcf0fe63c0b7f89b","analyzedAt":"2026-09-02T05:17:40.946Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T11:17:12.671Z"}