Files
agent-skills/skills/vue-best-practices/reference/rendering-render-function-h-import-vue3.md
Jason Woltje f5792c40be feat: Complete fleet — 94 skills across 10+ domains
Pulled ALL skills from 15 source repositories:
- anthropics/skills: 16 (docs, design, MCP, testing)
- obra/superpowers: 14 (TDD, debugging, agents, planning)
- coreyhaines31/marketingskills: 25 (marketing, CRO, SEO, growth)
- better-auth/skills: 5 (auth patterns)
- vercel-labs/agent-skills: 5 (React, design, Vercel)
- antfu/skills: 16 (Vue, Vite, Vitest, pnpm, Turborepo)
- Plus 13 individual skills from various repos

Mosaic Stack is not limited to coding — the Orchestrator and
subagents serve coding, business, design, marketing, writing,
logistics, analysis, and more.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 16:27:42 -06:00

3.3 KiB

title, impact, impactDescription, type, tags
title impact impactDescription type tags
Import h Globally in Vue 3 Render Functions HIGH Vue 3 requires explicit h import; using Vue 2 patterns causes runtime errors gotcha
vue3
render-function
migration
h
vnode
breaking-change

Import h Globally in Vue 3 Render Functions

Impact: HIGH - In Vue 2, the h function (createElement) was passed as an argument to render functions. In Vue 3, h must be explicitly imported from 'vue'. Using Vue 2 patterns causes runtime errors.

Task Checklist

  • Import h from 'vue' at the top of files using render functions
  • Remove the h parameter from render function signatures
  • Update all render functions when migrating from Vue 2

Incorrect (Vue 2 pattern - broken in Vue 3):

// WRONG: Vue 2 pattern - h is not passed as argument in Vue 3
export default {
  render(h) {  // h is undefined in Vue 3!
    return h('div', [
      h('span', 'Hello')
    ])
  }
}

// WRONG: Using createElement alias from Vue 2
export default {
  render(createElement) {  // Also undefined
    return createElement('div', 'Hello')
  }
}

Correct (Vue 3 pattern):

// CORRECT: Import h from vue
import { h } from 'vue'

export default {
  render() {
    return h('div', [
      h('span', 'Hello')
    ])
  }
}

With Composition API

import { h, ref } from 'vue'

export default {
  setup() {
    const count = ref(0)

    // Return a render function from setup
    return () => h('div', [
      h('button', { onClick: () => count.value++ }, `Count: ${count.value}`)
    ])
  }
}
<script setup>
import { h, ref } from 'vue'

const count = ref(0)

// Cannot return render function from script setup
// Must use a separate render option or template
</script>

<!-- script setup typically uses templates, not render functions -->
<template>
  <div>
    <button @click="count++">Count: {{ count }}</button>
  </div>
</template>

If you need render functions with <script setup>, use the render option:

<script>
import { h, ref } from 'vue'

export default {
  setup() {
    const count = ref(0)
    return () => h('button', { onClick: () => count.value++ }, count.value)
  }
}
</script>

Component Resolution Change

In Vue 3, you must also explicitly resolve components:

Incorrect:

// Vue 2: Could use string names for registered components
render(h) {
  return h('my-component', { props: { value: 1 } })
}

Correct:

import { h, resolveComponent } from 'vue'

export default {
  render() {
    // Must resolve component by name
    const MyComponent = resolveComponent('my-component')
    return h(MyComponent, { value: 1 })
  }
}

// Or import the component directly (preferred)
import { h } from 'vue'
import MyComponent from './MyComponent.vue'

export default {
  render() {
    return h(MyComponent, { value: 1 })
  }
}

Why This Changed

Vue 3's h is globally importable to:

  1. Enable tree-shaking (unused features can be removed)
  2. Support better TypeScript inference
  3. Allow use outside of component context

Reference