Add docs for renderless components
Nobody has claimed this yet.
- Dominant language
- Vue
- Stars
- 3.2k
- Forks
- 5k
- Avg merge
- 14d 17h
- Merged PRs (30d)
- 1
Description
With the arrival of the composition API, renderless components have become a bit less useful—IMO, composition functions are more versatile, easier to author, and easier to consume than renderless components.
That said, renderless components are still useful in some scenarios, and there are a few tricks to setting them up in Vue 3. Proper docs would explain the use case for renderless components, and have code examples for implementation in Vue. We can look to the React render props docs for inspiration.
There's also a question of where these docs should go. They definitely fit in with the Reusability & Composition section, but could also fit as one of the last guides in the Components In-Depth section.
I'll draft these docs in the near future, but meanwhile, below is some example code for anyone who might be looking. Here's an SFC playground for it.
Couple things to note in the code below:
- It's now possible to make renderless components without render functions, by rendering a slot as the only element in a Vue template. This wasn't possible in Vue 2, which forced you to use render functions.
- You can still use render functions to make renderless components, and the experience is improved by the
setupfunction. Write all your component logic insetupwith the composition API, then return your render function fromsetupat the end. - Render functions are not compatible with
script setup, as far as I can tell. Probably not that much of a downside, since people using render functions are usually writing components in plain.jsor.tsfiles instead of.vuefiles.
Rendering a normal slot with a Vue template
<!-- Renderless_NormalSlot_Template.vue -->
<script setup>
import { onMounted, onBeforeUnmount } from 'vue'
const clickEffect = () => console.log('Page was clicked!')
onMounted(() => document.addEventListener('click', clickEffect))
onBeforeUnmount(() => document.removeEventListener('click', clickEffect))
</script>
<template>
<slot></slot>
</template>
Rendering a scoped slot with a Vue template
<!-- Renderless_ScopedSlot_Template.vue -->
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
const count = ref(0)
const clickEffect = () => count.value++
onMounted(() => document.addEventListener('click', clickEffect))
onBeforeUnmount(() => document.removeEventListener('click', clickEffect))
</script>
<template>
<slot :count="count"></slot>
</template>
Rendering a normal slot with a render function returned from setup
<!-- Renderless_NormalSlot_RenderFn.vue -->
<script>
import { onMounted, onBeforeUnmount } from 'vue'
export default {
setup (props, { slots }) {
const clickEffect = () => console.log('Page was clicked by normal slot render function')
onMounted(() => document.addEventListener('click', clickEffect))
onBeforeUnmount(() => document.removeEventListener('click', clickEffect))
return slots.default
}
}
</script>
Rendering a scoped slot with a render function returned from setup
<!-- Renderless_NormalSlot_RenderFn.vue -->
<script>
import { ref, onMounted, onBeforeUnmount } from 'vue'
export default {
setup (props, { slots }) {
const count = ref(0)
const clickEffect = () => count.value++
onMounted(() => document.addEventListener('click', clickEffect))
onBeforeUnmount(() => document.removeEventListener('click', clickEffect))
return () => slots.default({ count: count.value })
}
}
</script>
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the issue's Renderless_NormalSlot_Template.vue, Renderless_ScopedSlot_Template.vue, and render-function examples, along with the linked SFC playground. Decide whether the page belongs in Reusability & Composition or Components In-Depth, then document the use case and Vue 3 template and setup-based patterns with working examples.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- documentation
- Issue type
- Documentation
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100