深色模式
基础 API 与组件机制
8. Options API 与 Composition API 如何选择?
展开答案与追问
参考答案: Options API 按 data、methods、computed 等选项组织;Composition API 按业务能力组合状态、派生值与副作用,便于提取 composable 和类型推断。Vue 3 仍支持 Options API,Composition API 也不意味着没有模板。
追问与易错点: 追问:Vue 2.7 已内置部分 Composition API 能力,但其响应式底层仍不同于 Vue 3。
9. setup 与 script setup 有什么区别?
展开答案与追问
参考答案: setup 是组件初始化入口,可接收 props 与上下文,通常返回模板要用的绑定;script setup 是单文件组件的编译期语法,顶层绑定可供模板使用,代码按组件实例执行。它没有组件实例 this。
追问与易错点: defineProps、defineEmits 等是编译宏,不应当作普通运行时函数搬到任意 JS 文件调用。script setup
10. defineProps、defineEmits、defineExpose 分别解决什么?
展开答案与追问
参考答案: defineProps 声明输入,defineEmits 声明输出事件,defineExpose 明确父级通过组件 ref 可以访问的能力。script setup 组件默认不会把所有内部绑定作为公共实例暴露。宏的参数存在编译与提升约束。
追问与易错点: 避免把整个内部状态暴露给父级;命令式能力只暴露必要的 focus/reset。
11. ref、reactive、toRef、toRefs 如何协作?
展开答案与追问
参考答案: ref 包装值,reactive 为对象建立代理,toRef 可将某个属性与 ref 建立关联,toRefs 把对象的可枚举属性转成关联 ref。普通解构取得基本值后不会自动继续跟踪原属性。
追问与易错点: Vue 3.5+ 在同一 script setup 中对 defineProps 的解构有编译器支持;不能据此推断所有 reactive 解构都保留响应式。宏说明
12. shallowRef、shallowReactive、markRaw、toRaw 用在哪里?
展开答案与追问
参考答案: shallowRef 仅跟踪 value 替换,适合大型不可变数据或外部实例;shallowReactive 只处理根属性;markRaw 标记对象不转换为代理;toRaw 读取代理背后的原对象。它们是响应式边界工具,不应为了“快”随意混用。
追问与易错点: 浅层结构里修改深层数据可能不通知视图;长期混用 raw/proxy 还容易出现身份比较问题。高级响应式 API
13. computed 与 methods 有什么区别?
展开答案与追问
参考答案: computed 表达同步派生值,按响应式依赖缓存;methods 是函数,模板调用时按需要执行,不提供同样的派生值缓存语义。computed getter 不应用于请求、写状态或 DOM 操作。可写 computed 要显式定义 setter。
追问与易错点: Date.now() 本身不是响应式依赖,不会使 computed 自动持续更新。
14. watch 应如何正确指定数据源?
展开答案与追问
参考答案: 可以监听 ref、getter、响应式对象或多个源数组。监听属性时常用 () => state.count,不能把当前的数字 state.count 直接当监听源。直接 watch 响应式对象会隐式深层观察;getter 返回对象通常只关注返回值替换,除非启用 deep。
追问与易错点: 深层修改时 newValue 与 oldValue 可能指向同一对象,不会自动生成历史深拷贝。watch 指南
15. watch 的 immediate、deep、flush 与清理分别做什么?
展开答案与追问
参考答案: immediate 让回调初始执行;deep 扩展深层依赖观察,深对象会增加成本;flush: post 用于访问组件更新后的 DOM,sync 同步触发且没有普通批处理收益。重跑前清理可取消过期请求。
追问与易错点: Vue 3.5+ 的 onWatcherCleanup 要在同步执行阶段注册;旧写法可使用回调参数 onCleanup。不要在循环写入中滥用 sync。watch 指南
16. 组件 v-model 的本质是什么?
展开答案与追问
参考答案: Vue 3 默认是 modelValue prop 与 update:modelValue 事件的约定,也支持带参数的多组绑定。Vue 3.4+ 可用 defineModel 简化声明;父子仍需明确数据所有权,不是允许子级直接任意修改 prop。
追问与易错点: 父级没传值而子级 defineModel 有默认值时要留意不同步;Vue 2 默认约定见后文对比。组件 v-model
17. props 为什么是单向的?嵌套对象能不能改?
展开答案与追问
参考答案: props 保持父到子的输入方向,子组件通过事件请求变更。顶层 prop 赋值会被限制,但引用类型的嵌套内容可能仍被修改;这会造成隐式耦合,应按组件契约避免。
追问与易错点: 要本地编辑草稿时明确复制策略,不能以“props 只读”推断它是任意深度的冻结对象。
18. 插槽和作用域插槽是什么?
展开答案与追问
参考答案: 插槽让父级提供 UI 内容;插槽内容通常使用父级作用域。作用域插槽由子级提供 slot props,使父级可按子级数据定制内容。Vue 3 中插槽统一为函数形式,具名插槽用名称区分区域。
追问与易错点: 常见场景:表格单元格自定义渲染、列表项渲染和布局组件。
19. provide/inject、attrs 与 emits 有哪些易错点?
展开答案与追问
参考答案: provide/inject 支持跨层提供依赖,传入 ref 等可保留响应式,但建议由提供方集中修改。未声明为 props/emits 的属性或监听可能进入 attrs;多根组件不能总是自动判定透传目标。声明 emits 有助于区分组件事件与原生透传。
追问与易错点: Vue 3 的组件自定义事件不会像 DOM 事件一样自动向祖先逐层冒泡。