开发提速?Vue3模板隐藏技巧来了

🤔 为什么需要"模板函数"

在 Vue 2 Options API 时代,复用一段 纯 UI 片段 只有两条路:

  1. 💼 抽成组件 → 为了三五行模板写 .vue、props、emits,重;

  2. 📋 直接复制粘贴 → 维护地狱,一改全改。

Vue 3 带来了 组合式 API ,让逻辑可以"组合",但 <template> 依旧只能"整块"复用。

vue-reuse-template(已并入 VueUse)把"组合"思想延伸到模板层,让你:

  • 🎯 把模板当函数定义(define)

  • 🔁 在原地多次调用(reuse)

  • 🚫 不创建额外组件实例 、不破坏作用域 、不传 props


⚙️ 核心概念:一对"模板 Hook"

typescript 复制代码
const [DefineTemplate, ReuseTemplate] = createReusableTemplate()

| 名称 | 作用 | 是否渲染 |

| --- | --- | --- |

| DefineTemplate | 📝 声明模板片段 | ❌(占位) |

| ReuseTemplate | ▶️ 调用模板片段 | ✅(真正渲染) |


📦 安装与引入

bash 复制代码
# 推荐直接装 VueUse

npm i @vueuse/core
vue 复制代码
<script setup>

import { createReusableTemplate } from '@vueuse/core'

</script>

  

🚀 最小可运行示例

vue 复制代码
<script setup>

import { createReusableTemplate } from '@vueuse/core'

  


// 1. 创建一对模板 Hook

const [DefineCard, ReuseCard] = createReusableTemplate()

</script>

<template>

  <!-- 2. 定义:不会渲染,只是注册 -->

  <DefineCard v-slot="{ title, content }">

    <div class="card">

      <h3>{{ title }}</h3>

      <p>{{ content }}</p>

    </div>

  </DefineCard>

  <!-- 3. 复用:真正渲染 -->

  <ReuseCard title="文章 1" content="今天学了 vue-reuse-template" />

  <ReuseCard title="文章 2" content="模板也能当函数用" />

</template>

<style scoped>

.card { border: 1px solid #ccc; padding: 12px; margin: 8px 0; }

</style>

  

🎯** 效果**:两张卡片,零组件文件,零 props。


🔧 进阶技巧

解构命名 & 多次定义

typescript 复制代码
const { define: DefineChip, reuse: ReuseChip } = createReusableTemplate()

  


const [DefineBadge, ReuseBadge] = createReusableTemplate()

在循环里复用

vue 复制代码
<ReuseCard

  v-for="post in posts"

  :key="post.id"

  :title="post.title"

  :content="post.body"

/>

与组件作用域无缝衔接

模板内部可直接使用当前组件的变量、注入、Router、Store:

vue 复制代码
<script setup>

import { useUserStore } from '@/stores/user'

const userStore = useUserStore()

</script>

<DefineCard v-slot="{ title }">

  <h3>{{ title }}</h3>

  <p>当前用户:{{ userStore.name }}</p>

</DefineCard>

  

具名插槽 + 默认插槽

vue 复制代码
<DefineComplex v-slot="{ title }">

  <header>{{ title }}</header>

  <slot name="extra" />

</DefineComplex>

<ReuseComplex title="标题">

  <template #extra><button>更多</button></template>

</ReuseComplex>

  

🎯 TypeScript 泛型推导(可选)

typescript 复制代码
const [Define, Reuse] = createReusableTemplate<{

  title: string

  done: boolean

}>()

  


// 如果写 :title="123" 会立即报错

📊 与"全局注册"插件的区别

| 方案 | 跨组件 | 是否需插件 | 是否运行时 | 插槽传参 |

| --- | --- | --- | --- | --- |

| createReusableTemplate | ❌(仅当前组件) | 否 | 否 | ✅ |

| unplugin-vue-reuse-template | ✅ | 是(编译) | 否 | ✅(实验) |

💡 80% 场景 单组件内复用 已够用;如需 任意组件 调用,再考虑插件。


💡 示例:低代码表单渲染器

vue 复制代码
<script setup>

import { createReusableTemplate } from '@vueuse/core'

  


const [DefineField, ReuseField] = createReusableTemplate()

  


const schema = [

  { type: 'input', label: '姓名', key: 'name' },

  { type: 'select', label: '城市', key: 'city', options: ['北京', '上海'] }

]

  


const form = reactive({})

</script>

<template>

  <!-- 定义:一行通用字段 -->

  <DefineField v-slot="{ field }">

    <label>{{ field.label }}

      <input v-if="field.type==='input'" v-model="form[field.key]" />

      <select v-else v-model="form[field.key]">

        <option v-for="o in field.options" :key="o">{{ o }}</option>

      </select>

    </label>

  </DefineField>

  <!-- 渲染 -->

  <ReuseField v-for="f in schema" :key="f.key" :field="f" />

  


  <pre>{{ form }}</pre>

</template>

  

✨** 亮点**

  • 🚫 没有为"字段"创建额外组件

  • 🔗 仍能访问 form 响应式对象

  • 📖 模板即函数,可读性高


⚡ 性能与原理

  1. ⏱️ 编译期 :DefineTemplate 被编译成 渲染函数块并缓存

  2. ▶️ 运行时 :ReuseTemplate 直接 调用该函数块,不生成新的组件实例

  3. 🔗 作用链 :通过 Vue 3 的 作用域插槽 保持变量访问

  4. 🧹 零内存泄漏:随组件卸载自动回收


⚠️ 常见坑与最佳实践

| 问题 | 解决方案 |

| --- | --- |

| 🚨 模板未定义 | 保证 Define* 在 Reuse* 之前渲染(同一组件内) |

| 🌐 跨组件复用 | 目前 做不到,请改用插件或抽正式组件 |

| 🪆 大量嵌套 | 模板函数也能"组合"------在 DefineA 内部再 ReuseB |

| 🏷️ 命名冲突 | 统一前缀:DefineUserCard、DefineProductCard |

📋 何时用 & 何时不用

✅ 适合

  • 🎯 同组件内 重复 UI 结构(卡片、按钮组、表单项)

  • 🚫 逻辑简单,不值得为 props 写接口

  • 🔗 需要 访问父组件变量(不想层层传递)

❌ 不适合

  • 🌐 跨组件复用(目前做不到)

  • 🧠 业务逻辑复杂(应抽独立组件)

  • ⚡ 需要 keep-alive 、生命周期 、name 等组件特性


🎯 小结

vue-reuse-template 让 模板也能像函数一样被定义和调用,不写 props、不创组件、不打断作用域------是 Vue 3 组合式时代里,最轻量的"模板函数"方案。


🚀 快速上手(单组件)

vue 复制代码
<script setup>

import { createReusableTemplate } from '@vueuse/core'

const [Def, Reuse] = createReusableTemplate()

</script>

<template>

  <Def v-slot="{ txt }"><p>{{ txt }}</p></Def>

  <Reuse txt="Hello" />

  <Reuse txt="World" />

</template>

  

🌍 全局注册(任意 .vue 可用)

① 安装插件

bash 复制代码
npm i -D unplugin-vue-reuse-template

② Vite 配置

typescript 复制代码
// vite.config.js

import vueReuse from 'unplugin-vue-reuse-template/vite'

  


export default {

  plugins: [vue(), vueReuse()]

}

③ 定义全局模板

vue 复制代码
<!-- src/components/TemplateBank.vue -->

<template>

  <template $btn>

    <button class="btn"><slot /></button>

  </template>

  <template $card>

    <div class="card"><slot name="title"/><slot/></div>

  </template>

</template>

<style>

.btn{@apply px-4 py-2 bg-blue-500 text-white rounded}

.card{@apply border rounded p-4 shadow}

</style>

  

在 main.js 里确保被预加载

javascript 复制代码
import '@/components/TemplateBank.vue'

④ 任意组件直接调用

vue 复制代码
<template>

  <template $use="$btn">提交</template>

  <template $use="$card">

    <template #title><h3>标题</h3></template>

    <p>内容</p>

  </template>

</template>

  

📊 小结

| 方式 | 范围 | 语法 | 插件 |

| --- | --- | --- | --- |

| createReusableTemplate | 当前组件 | Def/Reuse | 不需要 |

| unplugin-vue-reuse-template | 全局 | <template $use> | 需要

相关推荐
Sammyyyyy4 分钟前
jev-ultrafast 实战:浏览器操作代理加本地 AI 网关,把云控制台配置做成自动化流水线
运维·人工智能·自动化·ai编程·servbay
狂师5 分钟前
爆火!新一代e2e AI测试框架,单日狂揽1500 star
前端·人工智能·测试
啵啵啵鱼13 分钟前
对数据的增删改查
数据库·mysql·ai·idea·ai编程·navicat·obsidian
恋猫de小郭26 分钟前
Flitz ,一个把 Flutter 玩成热插拔 Preview 的有趣项目,不错的思路
android·前端·flutter
闭包不眠27 分钟前
Word转HTML后体积不对,裁掉的截图原图还在
前端·图像处理·人工智能·计算机视觉·html·word
言乐634 分钟前
PythonLOLM自动生成复盘报告模型
开发语言·前端·数据库·人工智能·python
tryCbest1 小时前
第二篇:CSS3 全部知识点全解 + 项目样式实现
前端·css·css3
一木 之林1 小时前
Agent智能体学习总结:从一次调用到模型自主规划、工具调用与 ReAct 循环的项目实战-6/6
前端·人工智能·学习·react.js
程序员大阳1 小时前
副队长CSS教程(36)–移动布局与响应式
前端·css·响应式·媒体查询·移动布局
程序员Sunday1 小时前
React 的 useEffect 怎么工作?依赖数组、清理函数和重复执行如何理解?
前端·javascript