0
0
Vueframework~5 mins

Renderless components in Vue

Choose your learning style9 modes available
Introduction

Renderless components let you share logic without deciding how the UI looks. They give you control to design the interface yourself.

You want to reuse behavior like toggling or fetching data but customize the look.
You need to separate logic from appearance for easier maintenance.
You want to build flexible UI parts that others can style differently.
You want to avoid repeating the same code in many components.
You want to keep your components simple and focused on one job.
Syntax
Vue
<template>
  <slot :isOpen="isOpen" :toggle="toggle" />
</template>

<script setup>
import { ref } from 'vue'

const isOpen = ref(false)
function toggle() {
  isOpen.value = !isOpen.value
}
</script>
The component does not render any HTML itself, it only provides data and functions via slots.
Use with props to pass state and methods to the parent component.
Examples
This renderless component shares a counter and a function to increase it.
Vue
<template>
  <slot :count="count" :increment="increment" />
</template>

<script setup>
import { ref } from 'vue'
const count = ref(0)
function increment() {
  count.value++
}
</script>
This component shares a list of items but does not render them.
Vue
<template>
  <slot :items="items" />
</template>

<script setup>
const items = ['apple', 'banana', 'cherry']
</script>
Sample Program

This example shows a renderless toggle component. It shares the toggle logic and state. The parent decides how to show the button and details.

Vue
<!-- ToggleRenderless.vue -->
<template>
  <slot :isOpen="isOpen" :toggle="toggle" />
</template>

<script setup>
import { ref } from 'vue'
const isOpen = ref(false)
function toggle() {
  isOpen.value = !isOpen.value
}
</script>

<!-- App.vue -->
<template>
  <ToggleRenderless v-slot="{ isOpen, toggle }">
    <button @click="toggle" :aria-expanded="isOpen.toString()" aria-controls="details">
      {{ isOpen ? 'Hide' : 'Show' }} details
    </button>
    <section v-if="isOpen" id="details">
      <p>Here are some important details you can toggle.</p>
    </section>
  </ToggleRenderless>
</template>

<script setup>
import ToggleRenderless from './ToggleRenderless.vue'
</script>
OutputSuccess
Important Notes

Renderless components help keep your UI flexible and logic reusable.

Always pass needed state and functions via slots using v-slot.

Use ARIA attributes like aria-expanded for accessibility when toggling content.

Summary

Renderless components share logic without rendering UI.

They use slots to pass data and methods to the parent.

This pattern helps build flexible and reusable Vue components.