---
category: Component
outline: deep
---
# createReusableTemplate
Define and reuse template inside the component scope.
## Motivation
It's common to have the need to reuse some part of the template. For example:
```vue
```
We'd like to reuse our code as much as possible. So normally we might need to extract those duplicated parts into a component. However, in a separated component you lose the ability to access the local bindings. Defining props and emits for them can be tedious sometimes.
So this function is made to provide a way for defining and reusing templates inside the component scope.
## Usage
In the previous example, we could refactor it to:
```vue
```
- `` will register the template and renders nothing.
- `` will render the template provided by ``.
- `` must be used before ``.
> **Note**: It's recommended to extract as separate components whenever possible. Abusing this function might lead to bad practices for your codebase.
### Options API
When using with [Options API](https://vuejs.org/guide/introduction.html#api-styles), you will need to define `createReusableTemplate` outside of the component setup and pass to the `components` option in order to use them in the template.
```vue
{{ data }} passed from usage
```
### Passing Data
You can also pass data to the template using slots:
- Use `v-slot="..."` to access the data on ``
- Directly bind the data on `` to pass them to the template
```vue
{{ data }} passed from usage
```
### TypeScript Support
`createReusableTemplate` accepts a generic type to provide type support for the data passed to the template:
```vue
Hello {{ msg.toUpperCase() }}
```
Optionally, if you are not a fan of array destructuring, the following usages are also legal:
```vue
Hello {{ msg.toUpperCase() }}
```
```vue
Hello {{ msg.toUpperCase() }}
```
::: warning
Passing boolean props without `v-bind` is not supported. See the [Caveats](#boolean-props) section for more details.
:::
### Props and Attributes
By default, all props and attributes passed to `` will be passed to the template. If you don't want certain props to be passed to the DOM, you need to define the runtime props:
```ts
import { createReusableTemplate } from '@vueuse/core'
const [DefineTemplate, ReuseTemplate] = createReusableTemplate({
props: {
msg: String,
enable: Boolean,
}
})
```
If you don't want to pass any props to the template, you can pass the `inheritAttrs` option:
```ts
import { createReusableTemplate } from '@vueuse/core'
const [DefineTemplate, ReuseTemplate] = createReusableTemplate({
inheritAttrs: false,
})
```
### Passing Slots
It's also possible to pass slots back from ``. You can access the slots on `` from `$slots`:
```vue
Some content
Another content
```
## Caveats
### Boolean props
As opposed to Vue's behavior, props defined as `boolean` that were passed without `v-bind` or absent will be resolved into an empty string or `undefined` respectively:
```vue
{{ typeof value }}: {{ value }}
```
## References
This function is migrated from [vue-reuse-template](https://github.com/antfu/vue-reuse-template).
Existing Vue discussions/issues about reusing template:
- [Discussion on Reusing Templates](https://github.com/vuejs/core/discussions/6898)
Alternative Approaches:
- [Vue Macros - `namedTemplate`](https://vue-macros.sxzz.moe/features/named-template.html)
- [`unplugin-vue-reuse-template`](https://github.com/liulinboyi/unplugin-vue-reuse-template)
## Type Declarations
```ts
type ObjectLiteralWithPotentialObjectLiterals = Record<
string,
Record | undefined
>
type GenerateSlotsFromSlotMap<
T extends ObjectLiteralWithPotentialObjectLiterals,
> = {
[K in keyof T]: Slot
}
export type DefineTemplateComponent<
Bindings extends Record,
MapSlotNameToSlotProps extends ObjectLiteralWithPotentialObjectLiterals,
> = DefineComponent & {
new (): {
$slots: {
default: (
_: Bindings & {
$slots: GenerateSlotsFromSlotMap
},
) => any
}
}
}
export type ReuseTemplateComponent<
Bindings extends Record,
MapSlotNameToSlotProps extends ObjectLiteralWithPotentialObjectLiterals,
> = DefineComponent & {
new (): {
$slots: GenerateSlotsFromSlotMap
}
}
export type ReusableTemplatePair<
Bindings extends Record,
MapSlotNameToSlotProps extends ObjectLiteralWithPotentialObjectLiterals,
> = [
DefineTemplateComponent,
ReuseTemplateComponent,
] & {
define: DefineTemplateComponent
reuse: ReuseTemplateComponent
}
export interface CreateReusableTemplateOptions<
Props extends Record,
> {
/**
* Inherit attrs from reuse component.
*
* @default true
*/
inheritAttrs?: boolean
/**
* Props definition for reuse component.
*/
props?: ComponentObjectPropsOptions
}
/**
* This function creates `define` and `reuse` components in pair,
* It also allow to pass a generic to bind with type.
*
* @see https://vueuse.org/createReusableTemplate
*
* @__NO_SIDE_EFFECTS__
*/
export declare function createReusableTemplate<
Bindings extends Record,
MapSlotNameToSlotProps extends
ObjectLiteralWithPotentialObjectLiterals = Record<"default", undefined>,
>(
options?: CreateReusableTemplateOptions,
): ReusableTemplatePair
```