Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Vue 3 debugging reference for reactivity issues, computed errors, watcher bugs, async failures, and SSR hydration problems.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
reference/render-function-avoid-internal-vnode-properties.md
1---2title: Do Not Rely on Internal VNode Properties3impact: MEDIUM4impactDescription: Using undocumented vnode properties causes code to break on Vue updates5type: gotcha6tags: [vue3, render-function, vnode, internal-api]7---89# Do Not Rely on Internal VNode Properties1011**Impact: MEDIUM** - The `VNode` interface contains many internal properties used by Vue's rendering system. Relying on any properties other than the documented public ones will cause your code to break when Vue's internal implementation changes.1213Only use the documented vnode properties: `type`, `props`, `children`, and `key`. All other properties are internal implementation details that may change without notice between Vue versions.1415## Task Checklist1617- [ ] Only access documented vnode properties: `type`, `props`, `children`, `key`18- [ ] Never access properties like `el`, `component`, `shapeFlag`, `patchFlag`, etc.19- [ ] If you need DOM element access, use template refs instead20- [ ] Treat vnodes as opaque data structures for rendering, not inspection2122**Incorrect:**23```javascript24import { h } from 'vue'2526export default {27setup(props, { slots }) {28return () => {29const slotContent = slots.default?.()3031// WRONG: Accessing internal properties32if (slotContent?.[0]?.el) {33// el is an internal property34console.log(slotContent[0].el.tagName)35}3637// WRONG: Using shapeFlag internal property38if (slotContent?.[0]?.shapeFlag & 1) {39// This is internal implementation40}4142return h('div', slotContent)43}44}45}46```4748```javascript49// WRONG: Inspecting component instance via vnode50const vnode = h(MyComponent)51console.log(vnode.component) // Internal property52console.log(vnode.appContext) // Internal property53```5455**Correct:**56```javascript57import { h } from 'vue'5859export default {60setup(props, { slots }) {61return () => {62const slotContent = slots.default?.()6364// CORRECT: Only use documented properties65if (slotContent?.[0]) {66const vnode = slotContent[0]67console.log(vnode.type) // Safe: element type or component68console.log(vnode.props) // Safe: props object69console.log(vnode.children) // Safe: children70console.log(vnode.key) // Safe: key prop71}7273return h('div', slotContent)74}75}76}77```7879```javascript80import { h, ref, onMounted } from 'vue'8182export default {83setup() {84// CORRECT: Use template refs for DOM access85const divRef = ref(null)8687onMounted(() => {88// Safe way to access DOM element89console.log(divRef.value.tagName)90})9192return () => h('div', { ref: divRef }, 'Content')93}94}95```9697## Documented VNode Properties9899| Property | Type | Description |100|----------|------|-------------|101| `type` | `string \| Component` | Element tag name or component definition |102| `props` | `object \| null` | Props passed to the vnode |103| `children` | `any` | Child vnodes, text, or slots |104| `key` | `string \| number \| null` | Key for list rendering |105106## Safe VNode Inspection Patterns107108```javascript109import { h, isVNode } from 'vue'110111export default {112setup(props, { slots }) {113return () => {114const children = slots.default?.() || []115116// Safe: Check if something is a vnode117children.forEach(child => {118if (isVNode(child)) {119// Safe: Check vnode type120if (typeof child.type === 'string') {121console.log('Element:', child.type)122} else if (typeof child.type === 'object') {123console.log('Component:', child.type.name)124}125126// Safe: Read props127if (child.props?.class) {128console.log('Has class:', child.props.class)129}130}131})132133return h('div', children)134}135}136}137```138139## Why This Matters140141Vue's internal vnode structure may change for:142- Performance optimizations143- New feature implementations144- Bug fixes145- Tree-shaking improvements146147Code relying on internal properties will break silently or throw errors when upgrading Vue versions. The documented properties are part of Vue's public API and are guaranteed to remain stable.148149## Reference150- [Vue.js Render Function APIs](https://vuejs.org/api/render-function.html)151- [Vue.js Render Functions - The Virtual DOM](https://vuejs.org/guide/extras/render-function.html#the-virtual-dom)152