a

2026-05-071a

1. 什么是 Vue 组件

Vue 组件本质上是一个 可复用的 UI 和逻辑单元,它把模板、数据、行为、样式等封装在一起,用来构建页面。

组件化的好处

  • 提高复用性
  • 提高可维护性
  • 提高开发效率
  • 方便拆分复杂页面

2. 常见组件通信方式

  • props:父传子
  • emit:子传父
  • v-model:父子之间核心状态同步
  • provide / inject:跨层级通信
  • ref + defineExpose:父组件主动调用子组件方法
  • Pinia / Vuex:全局状态共享
  • slot:内容分发

3. props 高频回答

props 是什么

props 是父组件向子组件传递数据的方式。

为什么是单向数据流

因为数据只能从父组件流向子组件,子组件只能使用,不能直接修改。

为什么不能直接修改 props

因为 props 的所有权在父组件。如果子组件直接修改:

  • 会违背单向数据流
  • 父组件重新渲染时可能会覆盖掉子组件修改
  • 容易造成状态混乱

子组件想改怎么办

  • props 拷贝成内部状态再改
  • 通过 emit 通知父组件修改

4. emit 高频回答

emit 的本质是:

子组件触发一个自定义事件,把数据或变更意图传给父组件,父组件监听后决定是否修改状态。

它不是子组件直接改父组件数据,而是 通知父组件去改


5. v-model 高频回答

v-model 本质上是 props + emit 的语法糖

Vue2

  • value
  • input

Vue3

  • modelValue
  • update:modelValue

适用场景

当组件有一个核心状态需要和父组件保持同步时,适合用 v-model

例如:

  • 输入框值
  • 开关状态
  • 弹窗显示隐藏

6. 插槽 slot 高频回答

什么是插槽

插槽是 Vue 提供的 内容分发机制,子组件通过 slot 预留位置,父组件在使用时把内容插入进去。

插槽的作用

  • 提高组件灵活性
  • 结构复用,内容可定制

具名插槽

给插槽起名字,用来区分多个插槽位置。

作用域插槽

子组件把内部数据作为 slot props 传给父组件,父组件接收这些数据后决定怎么渲染。

一句话总结:

作用域插槽不是父组件直接访问子组件内部数据,而是子组件主动把数据传给父组件。


7. provide / inject 高频回答

provide / inject 是 Vue 提供的跨层级通信方式。

适用场景

  • 祖先组件给深层后代传值
  • 避免一层层 props 透传
  • 表单组件、主题组件上下文共享

优点

  • 减少中间层传值
  • 适合深层嵌套组件通信

缺点

  • 依赖关系不够显式
  • 不如 props 清晰

是否响应式

provide / inject 本身不是自动响应式机制,是否响应式取决于提供的数据本身是不是响应式对象,比如 refreactive


8. keep-alive 高频回答

keep-alive 是 Vue 的内置组件,用来缓存动态组件或路由组件实例,避免组件切换时被重复销毁和创建。

作用

  • 保留组件状态
  • 减少重复挂载
  • 提升切换性能

场景

  • tab 切换
  • 动态组件切换
  • 路由返回后保留页面状态

多出的生命周期

  • activated
  • deactivated

使用不当的问题

  • 内存占用增加
  • 旧状态残留
  • 副作用未清理

9. 异步组件 高频回答

异步组件是指组件不会在初始化时立即加载,而是在真正渲染时才加载。

作用

  • 减少首屏资源体积
  • 优化首屏性能

Vue3 写法

js
1const AsyncComp = defineAsyncComponent(() => import("./AsyncComp.vue"));

和路由懒加载的区别

  • 异步组件:组件级别懒加载
  • 路由懒加载:页面级别懒加载

10. 动态组件 高频回答

动态组件指的是:

在同一个挂载位置,根据条件动态切换不同组件进行渲染。

实现方式

vue
1<component :is="currentComponent" />

和 v-if / v-show 的区别

  • 动态组件:切换不同组件
  • v-if:控制是否创建和销毁
  • v-show:控制显示隐藏,不销毁

常搭配什么使用

通常搭配 keep-alive 使用,因为动态组件切换时默认会销毁实例,而 keep-alive 可以缓存组件状态。


11. 生命周期执行顺序 高频回答

挂载时

  • created
  • created
  • mounted
  • mounted

总结:

先创建父,再创建子;先挂载子,再挂载父。

更新时

  • beforeUpdate
  • beforeUpdate
  • updated
  • updated

总结:

父先开始更新,子先更新完成,父最后 updated


12. $attrs 和 inheritAttrs 高频回答

$attrs 是什么

$attrs 表示父组件传进来、但没有被当前组件通过 propsemits 显式声明接收的属性集合。

inheritAttrs: false 的作用

阻止这些属性默认挂到组件根元素上,从而让开发者手动决定把它们绑定到哪个元素。

为什么封装组件经常用到

因为封装组件时,不可能把所有原生属性都写成 props,使用 $attrs 可以把额外属性继续透传给内部元素或子组件,提高灵活性。


13. ref + defineExpose 高频回答

ref 在 DOM 上和组件上的区别

  • 用在 DOM 上:拿到真实 DOM 节点
  • 用在组件上:拿到组件实例

为什么配合 defineExpose

因为 <script setup> 中内部变量和方法默认不会暴露给父组件,所以需要通过 defineExpose 显式暴露。

适用场景

  • 打开/关闭弹窗
  • 表单校验
  • 输入框聚焦

为什么不能滥用

因为会增加父子组件耦合,不适合作为常规数据通信方案。


14. 组件设计思想 高频回答

为什么要高内聚、低耦合

因为这样可以让组件职责更单一、边界更清晰,提高复用性、可维护性和扩展性。

一个好的 Vue 组件应该具备哪些特点

  • 职责单一
  • 接口清晰
  • 可复用
  • 易维护
  • 易扩展
  • 状态边界明确

15. Dialog 封装题速背

常见 props

  • modelValue
  • title
  • width
  • showClose
  • closeOnClickModal
  • closeOnPressEscape

常见事件

  • update:modelValue
  • open
  • close
  • confirm
  • cancel

常见插槽

  • header
  • 默认插槽
  • footer

显示隐藏怎么设计

一般采用 v-model

vue
1<Dialog v-model="visible" />

本质等价于:

vue
1<Dialog :modelValue="visible" @update:modelValue="visible = $event" />

子组件通过 props 接收 modelValue,通过 emit("update:modelValue", false) 通知父组件关闭。


16. data、props、computed、watch 怎么分

props

适合父组件传入、当前组件只使用不拥有的数据。

内部状态

适合只服务于当前组件实现的局部状态,比如:

  • 聚焦状态
  • 展开收起
  • loading

computed

适合做 派生数据,根据已有状态计算新值,有缓存。

watch

适合做 副作用逻辑,比如:

  • 发请求
  • 做校验
  • 同步存储
  • 操作 DOM

为什么要分清谁拥有数据

因为这样可以让数据流更清晰,避免多个地方同时维护同一份状态,减少混乱。


17. props + emit、v-model、ref 的适用场景

props + emit

适合最常规的父子通信。

v-model

适合组件某个核心状态需要和父组件保持同步的场景。

ref

适合命令式调用子组件方法,不适合做常规数据传递。


18. 最后总背诵

Vue 组件本质上是可复用的 UI 和逻辑单元。常见通信方式有 props、emit、v-model、provide/inject、ref + defineExpose、Pinia,以及 slot。props 适合父传子,emit 适合子传父,v-model 适合组件核心状态同步,provide/inject 适合跨层级通信,ref 适合命令式调用子组件方法。组件设计时要注意高内聚、低耦合,尽量做到职责单一、接口清晰、状态边界明确,这样组件才更容易复用、维护和扩展。

0 个表情
0 条评论·0 条回复
Aa
0/2000

评论加载中...