无渲染组件只封装逻辑与状态,不渲染任何dom,通过作用域插槽暴露数据、方法和状态供父组件自由定制ui。典型用于表单控件、数据加载器、交互行为等场景,实现逻辑复用与ui解耦。

无渲染组件不是“不干活”,而是把逻辑和状态管理做到极致,把界面长什么样完全交给使用者决定。它不写一行 DOM 标签,只通过作用域插槽把数据、方法、事件状态等“能力”暴露出去,由父组件按需渲染。
核心设计逻辑:只管逻辑,不管长相
常规组件把模板、脚本、样式打包在一起;无渲染组件只保留脚本部分——响应式状态、计算属性、副作用处理(比如监听鼠标、定时器)、工具方法封装。所有视图输出都通过 <slot></slot> 透出,比如:
-
数据类:如
:items="filteredList"、:loading="isLoading" -
行为类:如
:fetch="loadMore"、:reset="clearFilter" -
状态类:如
:error="lastError"、:canLoadMore="hasNextPage"
典型应用场景
适合那些“功能固定但 UI 差异大”的需求,比如:
- 表单控件逻辑:输入校验、防抖、格式化、错误提示时机,但输入框是圆角还是直角、带图标还是不带,由父组件定
- 数据加载器:封装请求、分页、缓存、重试逻辑,但加载中用骨架屏还是 loading 图标,列表用卡片还是表格,全由调用方控制
- 交互行为封装:鼠标追踪、拖拽状态、键盘快捷键监听、焦点管理等,不渲染任何 UI 元素,只输出坐标、是否拖拽中、当前按键等信息
如何实现一个基础无渲染组件
以 Vue 3 的 <script setup></script> 为例,关键点在于:
- 模板里只写
<slot></slot>,不写任何 div、button、span - 用
defineProps接收配置参数(如 API 地址、初始页码) - 用
ref/computed管理内部状态,用onMounted/onUnmounted处理生命周期副作用 - 把需要暴露的内容组织成对象,传给
<slot></slot>的绑定属性,例如:<slot :data="list" :loading="isLoading" :fetch="load"></slot>
与普通组件的协作方式
父组件使用时,直接用插槽解构接收内容,再自由组合 UI:
<dataloader api="/api/users"><template data loading fetch><div v-if="loading">正在加载...</div>
<ul v-else>
<li v-for="user in data" :key="user.id">{{ user.name }}</li>
</ul>
<button>加载更多</button>
</template></dataloader>
这种写法让逻辑复用和 UI 定制彻底解耦,同一个 DataLoader 可以在后台管理页渲染成表格,在移动端渲染成卡片流,甚至在仪表盘里只取其中的统计数字做图表数据源。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










