Vue3 组件通信分场景对应不同方式,父子组件最常用props + defineEmits,父传子用 props,子传父触发自定义事件。父子还能用ref / $parent直接获取实例调用方法。跨级组件用provide / inject,父级注入数据,后代组件直接接收,不用逐层传递。兄弟组件可通过mitt 事件总线,也可以借助父组件做中间转发。全局共享状态用Pinia,适合复杂项目的全局数据管理。还有 **$attrs / $listeners** 继承父组件属性和事件,这些方式覆盖了所有通信场景,简单场景用 props/emit,复杂跨级用 provide 或 Pinia,灵活适配不同开发需求。
解耦通信核心是让组件不直接依赖对方,减少耦合。首选mitt 轻量事件总线,组件只订阅 / 触发事件,互不引用,适合无关联组件通信。Provide/Inject也是解耦利器,父组件提供数据 / 方法,后代直接注入,不用逐层传 props。全局状态管理Pinia统一管理共享数据,组件只读写状态,无需直接通信。还能抽离组合式函数封装公共逻辑,组件只调用函数,彻底解耦。这些方式让组件独立可复用,修改一个组件不影响其他,大幅降低维护难度,适合中大型项目。
Vue3 单文件组件固定分三大核心模块,结构清晰。template 模板,写 HTML 结构,只能有一个根节点,支持 Vue 指令、插值语法,是组件的视图层。script 脚本,写业务逻辑,Vue3 推荐<script setup>语法糖,简化组合式 API 写法,无需写 setup 函数,直接声明响应式数据、方法。style 样式,写组件 CSS,加scoped属性实现样式隔离,只作用于当前组件,避免样式污染,还能支持 less、scss 预处理器。部分组件可加自定义块,三部分各司其职,让视图、逻辑、样式分离,代码更易维护。
插槽是组件间传递 HTML 内容的核心,分三种用法。默认插槽,子组件用<slot>占位,父组件直接在子组件标签内写内容填充。具名插槽,子组件给 slot 加name属性,父组件用v-slot:名称(简写 #名称)指定填充位置,适合多内容分发。作用域插槽,子组件通过 slot 绑定数据,父组件能接收子组件的数据渲染内容,实现数据传递。插槽让组件更灵活,子组件只负责框架,父组件自定义填充内容,大幅提升组件复用性,适配多种业务场景。
Vue3 自定义事件依靠组合式 API 的defineEmits实现,无需引入直接用。子组件先声明要触发的事件,比如const emit = defineEmits(['change', 'submit']),然后在业务逻辑中通过emit(事件名, 参数)触发事件,把数据传递给父组件。父组件在使用子组件时,用@事件名监听,绑定对应的处理函数接收参数。自定义事件是子传父的核心方式,遵循单向数据流,让组件通信更规范,还能明确组件对外暴露的事件,提升代码可读性。
组件封装复用核心是抽离公共部分,暴露灵活接口。先把重复的 UI、逻辑抽成独立组件,用props定义可配置参数,让父组件传递数据定制组件;用自定义事件暴露交互,让父组件监听处理;用插槽支持自定义内容,扩展组件能力。还能抽离组合式函数封装复用逻辑,比如表单验证、请求封装。封装时遵循单一职责,一个组件只做一件事,配置项简洁明确。复用就是在需要的地方直接引入组件,传入不同 props 即可,大幅减少重复代码,提升开发效率。
动态组件用<component :is="组件名">实现,能动态切换渲染不同组件,不用写多个 v-if,适合 tab 标签页、动态表单等场景,代码更简洁。异步组件通过defineAsyncComponent创建,实现组件懒加载,只有需要渲染时才加载对应的代码文件,不会一次性加载所有组件。好处是大幅减少首屏加载的代码体积,优化页面加载速度,提升用户体验,特别适合大型项目,拆分代码块,按需加载,兼顾功能和性能。
递归组件就是组件自己调用自己,核心是给组件设置name 名称,在模板中直接用这个名称作为标签使用。必须配合条件判断终止递归,否则会无限渲染崩溃,常用于树形菜单、目录层级、评论区嵌套等场景。比如树形组件,判断有子节点就渲染自身,没有就停止。递归组件能高效处理层级不确定的嵌套结构,不用手动写多层嵌套代码,简化复杂层级布局,是处理树形数据的最佳方案。
mixins 是 Vue2 的复用方式,Vue3 兼容使用,它是对象封装公共逻辑,组件引入后会合并选项,实现逻辑复用。但缺点明显,会出现命名冲突,数据来源不清晰。extends是单继承,只能继承一个对象,逻辑和 mixins 类似,优先级比 mixins 低。两者区别:mixins 可混入多个,extends 只能继承一个;合并时同名选项 extends 会被 mixins 覆盖。Vue3 官方不推荐使用,因为逻辑混乱,推荐用组合式函数替代,逻辑更清晰,无冲突问题。
自定义指令用来封装独立的 DOM 操作逻辑,全局 / 局部注册均可,适合复用 DOM 相关功能。常用场景:按钮防抖点击,防止重复提交;图片懒加载,滚动到可视区域再加载图片;权限控制,无权限时隐藏 / 禁用元素;自动聚焦,页面加载输入框自动聚焦;文本复制,一键复制内容;表单格式化,输入内容自动处理格式。指令比组件更轻量,专门处理 DOM 细节,不用在组件里重复写 DOM 操作代码,让业务逻辑更纯粹。
样式封装靠scoped属性,给 style 标签加 scoped,样式只作用于当前组件,通过属性选择器实现隔离,避免全局污染,需要修改子组件样式用:deep()深度选择器。样式复用分三种:抽离公共 CSS 文件,定义通用样式,组件直接引入;用CSS 变量定义主题色、尺寸,全局声明组件调用;用CSS Modules,生成唯一类名,模块化复用。还能结合预处理器嵌套、混合宏,封装公共样式片段。这些方式既保证组件样式独立,又能高效复用公共样式,兼顾封装性和灵活性。