关键是要将逻辑与渲染彻底分离:1、使用renderless components暴露逻辑不渲染ui;2、采用容器组件+展示组件分层,前者管行为后者管样式;3、提取可复用逻辑为composable函数;4、保持展示组件纯净,避免掺杂判断和副作用。

大型 Vue 组件要避免臃肿、难维护,关键不是写得“全”,而是拆得“清”——把逻辑和渲染彻底分开。这不是可选项,而是中大型项目维持可测试性、可复用性和协作效率的底线。
Renderless Components:只暴露逻辑,不画 UI
无渲染组件本身不返回任何 DOM,只通过作用域插槽(scoped slots)把状态、方法、事件回调等“能力”交出去。父组件拿到这些,再决定怎么渲染、用什么样式、是否加动画。
- 适合封装通用行为:表单校验、分页控制、搜索过滤、拖拽排序、权限判断等
- 组件内不写 template,只保留 setup / script setup 中的 reactive、computed、methods 和 expose
- 使用时用 v-slot="{ data, submit, isLoading }" 接收,然后自由组合 HTML 或第三方 UI 库元素
- 好处是同一套逻辑,既可配 Element Plus 表单,也能套 Tailwind 的极简风格,甚至用于 SSR 或小程序端
容器组件 + 展示组件:职责划清,各司其职
这是更贴近业务组织的分层方式。容器组件管“做什么”,展示组件管“长什么样”。
分析 Vue 3 Composition API 使用情况——审计响应式模式、可组合函数设计、ref 与 reactive 的选择、计算属性、watcher 使用及组件……
- 容器组件负责:API 请求、状态管理(如 useUserStore)、事件监听、参数解析、副作用处理(如页面 title 更新)
- 展示组件只接收 props,纯函数式渲染,不调 API、不读 store、不发事件(除 emit 用户交互外)
- 二者通过 props / emit 或 provide / inject 连接;复杂场景下,容器可封装多个展示组件形成业务视图
- 典型例子:用户列表页 → UserListContainer(拉数据、分页、筛选) + UserCard(只渲染头像、昵称、状态)
逻辑提取到 Composable:让逻辑真正可复用
把业务逻辑从组件中抽出来,封装成独立的组合式函数(composable),是 Vue 3 最自然的解耦方式。
- 命名建议带 use 前缀,如 useSearch、usePagination、useFormValidation
- 内部用 ref / reactive 管理状态,用 watch / onMounted 处理副作用,最后 return 可被消费的变量和函数
- 同一个 useXXX 可在多个组件中 import 使用,也可在测试中单独 import 并 mock 依赖
- 避免“逻辑组件化陷阱”:不要为了抽而抽,只抽那些确实跨组件、有明确输入输出、且可能被重用的部分
UI 层保持 dumb:展示组件不掺杂判断逻辑
展示组件的模板里,应尽量避免复杂表达式、嵌套 v-if/v-for、直接访问 store 或调用 API。
- v-if 条件应来自 props,而不是 this.$store.state 或 computed 中的深层判断
- 样式类名用对象语法绑定,如 :class="{ active: isActive }",而非拼接字符串或三元运算符
- 事件处理只 emit,不执行业务动作;例如 @click="$emit('edit', item)",而非 this.updateItem(item)
- 需要差异化渲染时,优先用插槽(slot)或 scoped slot,而不是传一堆布尔 props 控制分支
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!









