Vue八股问题
组合式和选项式api
vue和react的区别
虚拟dom的概念和作用
概念
在 JavaScript 中,虚拟 DOM(Virtual DOM) 是一个用 JavaScript 对象描述真实 DOM 结构的轻量级副本。它不直接操作浏览器的 DOM 树,而是通过抽象层模拟 DOM 的结构和属性,最终通过特定算法与真实 DOM 进行高效同步。
虚拟 DOM 本质上是一个嵌套的 JavaScript 对象,每个对象对应真实 DOM 中的一个节点,包含以下关键信息:
- 节点类型(如标签名、文本节点)
- 属性(如
class、id、style) - 子节点列表
- 其他特性(如事件绑定)
// 真实DOM
<div class="container"><p>Hello World</p>
</div>// 对应的虚拟DOM对象
const vdom = {tag: 'div',props: { class: 'container' },children: [{ tag: 'p', props: {}, children: ['Hello World'] }]
};作用
1.提升渲染性能
真实 DOM 操作(如增删改)会触发浏览器的重排(Layout)和重绘(Paint),成本高昂。虚拟 DOM 通过以下方式优化:
- 先在内存中对比新旧虚拟 DOM 的差异(称为 “Diff 算法”)
- 只将变化的部分批量更新到真实 DOM,减少不必要的操作
2.跨平台渲染
虚拟 DOM 是与平台无关的抽象描述,同一套虚拟 DOM 可以被渲染到不同平台:
- 浏览器(转为真实 DOM)
- 移动端(如 React Native 转为原生组件)
- 服务端(如 SSR 生成 HTML 字符串)
3.优化开发体验
框架(如 React、Vue)基于虚拟 DOM 提供了声明式编程范式,开发者只需描述 “UI 应该是什么样子”,无需手动操作 DOM,降低了复杂度。
diff算法的流程
Diff 算法是虚拟 DOM 核心技术之一,用于比较新旧虚拟 DOM 树的差异,最终只更新变化的部分到真实 DOM,从而提升性能
核心原则:
1.同级比较:只对比同一层级的节点
2.标签/类型优先:如果节点标签或类型不同,直接判定为 “不同节点”,销毁旧节点并创建新节点。
3.key辅助识别:通过key属性标识节点唯一性,帮助快速匹配相同节点(避免误判)。
详细流程:
vue2和vue3的双向绑定机制
vue的生命周期
Vue 的生命周期是指组件从创建到销毁的整个过程,每个阶段都有对应的钩子函数(生命周期钩子),允许开发者在特定阶段执行代码。理解生命周期有助于更好地控制组件行为(如数据请求、DOM 操作、资源清理等)。
vue2的生命周期
创建(beforeCreate|created)-->挂载(beforeMount|mounted)--->更新(beforeUpdate|updated)-->销毁(beforeDestroy|destroyed)
vue3的生命周期
1.选项式API钩子(与vue2类似)
创建(setup)-->挂载(beforeMount|mounted)--->更新(beforeUpdate|updated)-->销毁(beforeUnmount|unmounted)
2.组合式API钩子(在setup中使用)
先要导入import { onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted} from 'vue'
v-if,v-for,v-show
computed和watch的区别
vue组件通信的方式
如何封装vue组件
vuex和pinia的区别
响应式原理(vue2 vue3)
Vue 的响应式原理是其核心特性之一,它能够自动追踪数据变化并更新视图
vue2的响应式原理
Vue 2 基于object.defineProperty实现响应式,核心是对数据对象的属性进行劫持,并通过依赖收集和派发更新完成视图同步。
1.数据劫持(Observer)Watcher
对data中的所有属性递归遍历,使用Object.defineProperty重写getter和setter
getter:当属性被访问时触发,用于收集依赖(记录使用该属性的组件/Watcher)
setter:当属性被修改时触发,用于派发更新(通知所有依赖该属性的组件重新渲染)
2.依赖收集(Dep)
每一个响应式属性对应一个Dep实例,用于管理依赖该属性的watcher集合。
当组件渲染时,会创建一个Watcher实例,此时的Dep.target指向该Watcher,访问属性时便会将Watcher加入Dep的依赖列表。
3.派发更新(Watcher)
Watcher是连接数据和视图的桥梁,当属性变化(setter触发)时,Dep会调用所有依赖的 Watcher.update()方法。
Watcher会触发组件的重新渲染(updateComponent),最终更新视图。
vue2的响应式原理
1.代理对象(Proxy)
使用Proxy对数据对象创建代理,拦截对象的读取、修改、新增、删除等操作。
支持拦截的操作有get(读取) set(修改) deleteProperty(删除) has(in 操作符)等
2.依赖收集与触发(Track 和 Trigger)
track:在get拦截时调用,记录当前活跃的副作用函数(effect)与属性的关联
trigger:在set/deleteProperty 拦截时调用,触发所有关联的副作用函数(eg组件更新)
3.副作用函数(Effect)
替代Vue2的Watcher,用于包裹需要响应式执行的代码(如组件渲染逻辑)。当依赖的属性变化时,自动重新执行副作用函数。
Vue 2 vs Vue 3 响应式对比
| 特性 | Vue 2(Object.defineProperty) | Vue 3(Proxy) |
|---|---|---|
| 核心 API | Object.defineProperty | Proxy |
| 新属性 / 删除属性 | 不支持(需 Vue.set) | 原生支持 |
| 数组索引 / 长度变化 | 不支持(需数组方法) | 支持 |
| 深层对象处理 | 初始化递归劫持(性能损耗) | 懒劫持(访问时才处理,性能更优) |
| 支持数据类型 | 对象、数组 | 对象、数组、Map、Set 等 |
| 依赖收集粒度 | 基于属性 | 基于属性(更精细) |
