高内聚低耦合的 vue 组件设计核心在于接口与边界设计,而非语法本身:通过 defineprops/defineemits 显式约束输入输出,用组合函数抽离业务逻辑,插槽替代条件渲染,样式与行为严格隔离。

用 <script setup></script> 编写高内聚低耦合的 Vue 组件,核心不是“怎么写语法”,而是“怎么设计接口与边界”。语法糖只是让这个目标更容易落地——它天然鼓励显式声明、逻辑聚拢、依赖外显。
明确组件职责,只暴露必要接口
一个组件只做一件事,并通过 defineProps 和 defineEmits 严格约束输入输出。不接收无关 props,不触发未声明的事件。
- 用类型标注定义 props,避免隐式传值:
const props = defineProps() - 事件必须提前声明,禁止随意
emit('xxx'):const emit = defineEmits() - 内部状态不暴露给父组件,如需读取,用
defineExpose显式控制:defineExpose({ focus: () => inputRef.value?.focus() })
逻辑按功能拆分,不混杂 UI 与业务
把数据获取、校验、格式化等逻辑抽成独立的组合函数(composable),组件内只负责调度和渲染。
- 例如表单字段封装:把验证规则、错误提示、重置逻辑都放在
useFormField.ts中,组件只调用const { value, error, validate } = useFormField(props) - 避免在组件里直接写
fetch或操作 localStorage,统一交给useApi或useStorage - 计算属性、watch、副作用都集中在相关逻辑块中,不散落在
setup顶部
用插槽替代条件渲染,提升可组合性
当组件需要支持多种内容结构时,优先用具名插槽或作用域插槽,而不是一堆 v-if 切换模板分支。
- 比如卡片组件:默认插槽放主体内容,
#header和#footer插槽交由使用者决定是否渲染、如何渲染 - 避免写
v-if="type === 'detail'"+ 大段结构,改用<slot name="detail"></slot>,让父组件决定“是什么”而非组件自己判断 - 插槽参数尽量精简,只传递必要上下文(如
{ item, index }),不传整个 store 或 API 实例
样式与行为隔离,不越界操作
组件不主动修改外部样式、不访问非自身 props 的全局状态、不手动操作其他组件 DOM。
- 使用
<style scoped></style>或 CSS Modules,确保样式影响范围可控 - 需要联动其他组件时,走
emit→ 父组件协调 →props下发,而不是用ref强引用或provide/inject跨多层传递状态 - 动画、焦点、滚动等行为,封装在子组件内部完成,对外只暴露控制开关(如
autoFocusprop)
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










