This is an excerpt from my upcoming course Reusable Components

There are different kinds of props that we use in Vue, each with their own unique characteristics.

Sometimes we use props to pass data into a component — these are state props.

Other props change how a component works, whether it's a small change or a drastic one — these are configuration props.

In this article I'm going to explore what template props are, why they're useful, and what we can do with them.

Template Props

Template props are props that are only used inside of the template.

They aren't used in methods, computed props, or for anything else. They're only interpolated into the template:

<template>
  <button @click="$emit('click')">
    {{ text }}
  </button>
</template>
export default {
  name: 'Button',
  props: {
    text: {
      type: String,
      required: true,
    },
  },
};

This makes them one of the simpler props, but they're still used quite often.

But here is why they're unique:

Because they're used directly in the template, they are equivalent to slots.

That is, we can very simply replace a template prop with a slot.

Converting to a Slot

With our Button example, we can see that the text prop can be replaced with a default slot:

<template>
  <button @click="$emit('click')">
    <slot />
  </button>
</template>
export default {
  name: 'Button',
};

This slightly changes how we use the component, but the change is fairly minimal. Initially we would pass the text as a prop:

<Button text="Click me" @click="handleClick" />

But now we're using the slot, which in this particular case feels a lot more natural:

<Button @click="handleClick">
  Click me
</Button>

Converting to a Template Prop

While we can convert from a template prop to a slot, going the other way is a lot more difficult.

This is because a slot allows a superset of a what a prop does — more can be done with a slot than with a prop.

Anything that can be passed as a prop can be put inside of a slot, but HTML and components can't be passed as props.

(Technically this isn't true. You can pass components through props and pass HTML as a string. But just because it's possible doesn't mean you should do it.)

Why would we even do this?

Knowing that this equivalence exists is useful when refactoring, or even when building out components initially.

Here are the key benefits:

  1. Simplicity: If you find that your props are getting out of control, converting some of the template props to slots can simplify your implementation slightly.
  2. Flexibility: Slots provide more flexibility than props do. Converting a template prop to a slot makes your component more reusable by making it adaptable.

If you enjoyed this article, I'm working on a new video course where I go into much more depth about component reusability, including different patterns and more insights like this one.