介绍
VueUse 的 createReusableTemplate 让你在同一个组件内复用模板片段,无需抽离子组件,直接共享当前作用域,支持传参与插槽。
概念
调用 createReusableTemplate 得到一对组件:
- DefineTemplate:定义模板,不渲染,仅注册。
- ReuseTemplate:复用模板,真正渲染,可多次调用。
import { createReusableTemplate } from '@vueuse/core'
const [DefineTemplate, ReuseTemplate] = createReusableTemplate()
安装
npm安装
npm install @vueuse/core
pnpm安装
pnpm add @vueuse/core
用法
基础用法
同一组件内重复渲染相同结构:
<template>
<!-- 定义:只写一次,不渲染 -->
<DefineTemplate>
<div class="box">Hello Reusable Template</div>
</DefineTemplate>
<!-- 复用:多处渲染 -->
<ReuseTemplate />
<ReuseTemplate />
</template>
<script setup>
import { createReusableTemplate } from '@vueuse/core'
const [DefineTemplate, ReuseTemplate] = createReusableTemplate()
</script>
传参(Props)
通过 v-slot 接收参数,ReuseTemplate 传值:
<template>
<!-- 定义:声明参数 -->
<DefineTemplate v-slot="{ title, content }">
<div class="card">
<h3>{{ title }}</h3>
<p>{{ content }}</p>
</div>
</DefineTemplate>
<!-- 复用:传入不同值 -->
<ReuseTemplate title="标题1" content="内容1" />
<ReuseTemplate title="标题2" content="内容2" />
</template>
<script setup>
import { createReusableTemplate } from '@vueuse/core'
const [DefineTemplate, ReuseTemplate] = createReusableTemplate()
</script>
插槽(Slots)
支持默认插槽与具名插槽:
<template>
<!-- 定义:接收插槽 -->
<DefineTemplate v-slot="{ $slots }">
<div class="wrapper">
<component :is="$slots.default" />
</div>
</DefineTemplate>
<!-- 复用:传入插槽内容 -->
<ReuseTemplate>
<p>插槽内容A</p>
</ReuseTemplate>
<ReuseTemplate>
<p>插槽内容B</p>
</ReuseTemplate>
</template>
案例
场景1:条件复用(if/else)
避免重复写弹窗与内容区:
<template>
<DefineTemplate>
<div class="content">公共内容</div>
</DefineTemplate>
<dialog v-if="showDialog">
<ReuseTemplate />
</dialog>
<div v-else>
<ReuseTemplate />
</div>
</template>
场景2:列表项复用
简化 v-for 内重复结构:
<template>
<DefineTemplate v-slot="{ item }">
<div class="item">{{ item.name }}</div>
</DefineTemplate>
<div v-for="item in list" :key="item.id">
<ReuseTemplate :item="item" />
</div>
</template>
注意事项
- 作用域:直接访问组件内变量,无需 props 透传。
- 渲染顺序:
DefineTemplate必须在ReuseTemplate之前。 - 布尔值:传布尔值需用
v-bind(如:disabled="true")。 - TypeScript:支持泛型,可约束参数类型。