VUE3 使用VueUse实现复用模板片段

VUE 复用模板片段介绍

介绍

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>

注意事项

  1. 作用域:直接访问组件内变量,无需 props 透传。
  2. 渲染顺序:DefineTemplate 必须在 ReuseTemplate 之前。
  3. 布尔值:传布尔值需用 v-bind(如 :disabled="true")。
  4. TypeScript:支持泛型,可约束参数类型。

原文出处:/show_1GW3L2KTQc9Q.html