Skip to content

Instantly share code, notes, and snippets.

@ThomasKientz
Created March 10, 2022 18:07
Show Gist options
  • Save ThomasKientz/e7305970ef04da575962abc957a44e9b to your computer and use it in GitHub Desktop.
Save ThomasKientz/e7305970ef04da575962abc957a44e9b to your computer and use it in GitHub Desktop.
Pass a render function as a slot prop

Providing a template to a child component to be rendered into.

We have a <CountryList/> component which list some countries.

  • France
  • Spain
  • Italy

We have a some slots.

<CountryList >
  <template #header="{ add }">
    <button @click="add">Add +</button>
  </template>
  <template #footer="{ add }">
    <button @click="add">Add +</button>
  </template>
<CountryList>

Render :

Add +
France
Spain
Italy
Add +

We want to display this list inside of a card component :

<v-card>
  <v-card-title>Countries</v-card-title>
  <v-card-text>
    <CountryList />
  </v-card-text>
  <v-card-actions>
    <button @click="add">Add country</button>
  </v-card-actions>
</v-card>

But now the button doesn't have access to the add() method, because it is not part of a slot anymore.

One way of coping with this is to access the add method through a ref:

<v-card>
  <v-card-title>Countries</v-card-title>
  <v-card-text>
    <CountryList ref="list" />
  </v-card-text>
  <v-card-actions>
    <button @click="$refs.list.add">Add country</button>
  </v-card-actions>
</v-card>

It works but it is not easy to maintain. If you rename the add() to addCountry(), you will not get any warnings.

Instead we can pass use a slot prop to pass a render function to the parent.

<CountryList v-slot="{add, renderList}">
  <v-card>
    <v-card-title>Countries</v-card-title>
    <v-card-text>
      <component :is="{ render: renderList }" />
    </v-card-text>
    <v-card-actions>
      <button @click="add">Add country</button>
    </v-card-actions>
  </v-card>
</CountryList>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment