Vue Render Functions: Trading Templates for JS Power
Render functions trade Vue's declarative templates for the full programmatic power of JavaScript. Use them for highly dynamic components where logic is too complex for templates. The footgun is losing template optimizations and readability for imperative code.
WHY IT EXISTS Vue templates are excellent for most scenarios, offering a declarative and optimized way to describe UI. However, some components require a level of dynamic structure and logic that is awkward or impossible to express cleanly within the constraints of template syntax. Render functions provide an escape hatch to use the full power of JavaScript for these complex cases.
THE MENTAL MODEL Think of a Vue template as a high-level blueprint that gets compiled into low-level instructions. A render function is you writing those low-level instructions directly. Instead of declaring , you call a function h('div', { class: myClass }). You trade the declarative convenience and optimizations of templates for direct, programmatic control over the virtual DOM nodes your component generates.
HOW IT WORKS Vue provides a function, h(), which stands for "hyperscript" (JavaScript that creates HTML). You call h() with up to three arguments: the element type (a string for HTML tags or a component object), an object of props (attributes, event listeners), and the children (a string or an array of other h() calls). In a component's setup function, you can return this render function directly. Vue will then execute it during the render cycle to get the vnodes needed to update the DOM. JSX is syntactic sugar over this; a JSX tag like <MyComponent/> is transpiled into an h(MyComponent) call by a build tool.
WHEN TO USE IT Use render functions for components where the structure is highly dynamic and determined by complex logic. A prime example is a library component that needs to render different layouts based on its props, such as a custom data grid with configurable columns or a form builder that generates fields from a JSON schema. When template v-if and v-for chains become deeply nested and hard to read, a render function is often a cleaner solution.
WHEN NOT TO USE IT For the vast majority of application components, stick with templates. Templates are easier to read, write, and reason about. They also allow Vue's compiler to perform static analysis and apply optimizations (like hoisting static content) that are not possible with render functions. Using a render function for a simple static component is overkill and makes the code less approachable.
ONE CANONICAL EXAMPLE To conditionally render a heading, a template would use v-if. A render function achieves this with a plain JavaScript if statement. Inside a component's setup function, you would return another function that contains the logic: return () => { if (someCondition) { return h('h1', 'Title'); } else { return h('h2', 'Subtitle'); } }. This shows how template directives map directly to basic JavaScript control flow.
Read the original → vuejs.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.