Changes in the render function API
Changes in the Render Function API
The render function API in Vue.js has undergone multiple adjustments during version iterations, from createElement
to the shorthand h
function, and further to the integration with the setup
context in the Composition API. These changes directly impact how developers write rendering logic.
Basics of Render Functions in Vue 2.x
In Vue 2.x, render functions are defined via the render
option, receiving createElement
as the first parameter:
export default {
render(createElement) {
return createElement('div', {
attrs: {
id: 'container'
}
}, [
createElement('span', 'Hello World')
])
}
}
The parameter structure consists of three parts:
- HTML tag name or component options object
- Data object (containing props, attrs, domProps, etc.)
- Array of child nodes or text content
Shorthand h
Function in Vue 3.x
Vue 3.x introduced the more concise h
function alias and adjusted the parameter structure:
import { h } from 'vue'
export default {
render() {
return h('div', {
id: 'container'
}, [
h('span', null, 'Hello World')
])
}
}
Key changes include:
- Attributes are now flattened and no longer nested under
attrs
ordomProps
class
andstyle
handling aligns with template syntax- The
.native
modifier is removed; all events are bound via theon
prefix
Render Functions in the Composition API
When using render functions in setup()
, h
can be directly destructured from the context parameter:
import { defineComponent } from 'vue'
export default defineComponent({
setup(props, { h }) {
return () => h('div', [
h('button', {
onClick: () => console.log('Clicked')
}, 'Submit')
])
}
})
Or more commonly via module import:
import { h } from 'vue'
export default {
setup() {
const count = ref(0)
return () => h('div', [
h('p', `Count: ${count.value}`),
h('button', {
onClick: () => count.value++
}, 'Increment')
])
}
}
Major Changes in VNode Props Structure
Vue 3 comprehensively refactored the VNode props structure:
// Vue 2.x style
h('div', {
attrs: { id: 'box' },
domProps: { innerHTML: '' },
on: { click: handler }
})
// Vue 3.x style
h('div', {
id: 'box',
innerHTML: '',
onClick: handler
})
Specific changes include:
- Removal of
attrs
anddomProps
namespaces; all DOM attributes are now flat - Event listeners uniformly use the
onXxx
format class
andstyle
support the same array/object syntax as templates
Changes in Functional Components
The definition of functional components has completely changed in Vue 3:
// Vue 2.x functional component
export default {
functional: true,
render(h, { props }) {
return h('div', `Message: ${props.text}`)
}
}
// Vue 3.x functional component
import { h } from 'vue'
function FunctionalComp(props, { slots }) {
return h('div', slots.default?.())
}
FunctionalComp.props = ['text']
Key differences:
- The
functional: true
option is no longer needed - Receives
props
andcontext
as parameters context
contains properties likeslots
,attrs
, andemit
Evolution of Slot Handling
The way slots are handled in render functions has also changed significantly:
// Vue 2.x slots
h('Layout', {
scopedSlots: {
default: props => h('span', props.text)
}
})
// Vue 3.x slots
h(Layout, {}, {
default: props => h('span', props.text)
})
Improvements in Vue 3:
- Scoped slots are now passed as an object in the third parameter
- Regular slots and scoped slots are handled uniformly
this.$slots
in render functions becomescontext.slots
Fragment and Portal Support
Vue 3 added native support for multi-root nodes and Portals:
// Fragment example
h('div', [
h('header', 'Header'),
h('main', 'Main content'),
h('footer', 'Footer')
])
// Portal example
import { h, Teleport } from 'vue'
h(Teleport, { to: '#modals' }, [
h('div', 'This will render in #modals')
])
Adjustments to Custom Directives
The usage of custom directives in render functions has changed:
// Vue 2.x
h('div', {
directives: [
{ name: 'focus', value: true }
]
})
// Vue 3.x
h('div', {
vFocus: true
})
Main changes:
- Directives are now passed as properties prefixed with
v
- Directive lifecycle hook names align with components
- The
inserted
hook is removed and replaced withmounted
Improvements in Type Support
Vue 3's render function API has been fully optimized for TypeScript:
import { defineComponent, VNode } from 'vue'
interface Props {
title: string
}
export default defineComponent({
setup(props: Props): () => VNode {
return () => h('div', props.title)
}
})
The type system can now:
- Infer
h
function parameter types - Validate VNode properties
- Provide complete context type hints
Performance-Related Changes
The render function implementation includes multiple performance optimizations:
- VNode objects are lighter, with unnecessary properties removed
- Static node hoisting is completed at compile time
- Event caching mechanisms reduce unnecessary updates
// Compiled static nodes are hoisted
const _hoisted = h('div', { class: 'static' })
function render() {
return h('div', [
_hoisted,
h('p', dynamicContent)
])
}
Relationship with Template Compilation Output
Understanding template compilation results helps in grasping render functions:
<!-- Template -->
<div :id="containerId">
<slot name="header" />
</div>
<!-- Compiled render function -->
function render(_ctx, _cache) {
return h('div', { id: _ctx.containerId }, [
_ctx.$slots.header?.()
])
}
The template compiler now generates code closer to handwritten render functions, further narrowing the differences between the two.
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn