1、Vue3兼容Vue2写法的情况?
- vue3支持向下兼容,vue2中的data、methods配置项在vue3中都能够使用,但是尽量不要将vue3中的配置项和vue2.x配置项混用;
- vue2.x配置(data、methods、computed等)中可以访问setup中的属性、方法,但是在setup中不能访问vue2.x配置(data、methods、computed等);
- 如果vue2.x配置与vue3配置存在重名,则以setup优先;
- setup不能是一个async函数,因为返回值不再是return的对象,而是promise,模板看不到return对象中的属性;
2、ref和reactive的区别?
- 数据类型不同:ref用于包装JavaScript基本类型的数据(如字符串、数字、布尔值等),而reactive可以用于包装JavaScript对象和数组等复杂类型的数据。
- 使用方式不同:ref需要通过在模板中使用ref指令以及在JavaScript代码中使用ref函数进行创建和使用,而reactive则需要通过调用Vue.js提供的reactive函数进行包装和创建。
- 访问方式不同:对于通过ref函数创建的响应式数据,我们可以通过.value属性来访问其实际值;而对于通过reactive函数创建的响应式对象,我们可以直接访问其属性或调用其方法。
- 设计理念不同:ref主要是为了解决单一元素/数据的响应式问题,而reactive则是为了解决JavaScript对象和数组等复杂数据结构的响应式问题。
- ref和reactive都是用于实现Vue.js组件的数据响应式更新,但是它们的使用方法、适用范围和设计理念等方面略有不同,需要根据具体的应用场景选择合适的API进行使用。
3、ref和reactive如何选择?
- ref()主要用于创建一个响应式数据,它会将一个普通的JavaScript对象转换为一个响应式的对象,从而使数据的变化可以被Vue实例所追踪,当数据发生变化时,Vue会自动更新相关视图。ref()创建的响应式数据可以通过.value属性来访问和修改。
- reactive()则主要用于创建一个响应式对象,可以用作包含多个值的状态对象,通常用于管理复杂的状态。它可以将一个普通的JavaScript对象转换为一个响应式对象,并且支持嵌套属性,即使嵌套属性发生变化也会被Vue实例所追踪。当响应式对象中有任何一个属性发生变化时,Vue也会自动更新相关的视图。
- 明确知道需要包裹的是一个对象,那么推荐使用 reactive,其他情况使用 ref 即可。
4、toRef和toRefs的作用?
- toRef 函数可以将一个响应式对象的属性转换为一个独立的 ref 对象。返回的是一个指向源对象属性的 ref 引用,任何对该引用的修改都会同步到源对象属性上。使用 toRef 时需要传入源对象和属性名作为参数。
- toRefs 函数可以将一个响应式对象转换为一个普通的对象,该对象的每个属性都是独立的 ref 对象。返回的对象可以进行解构,每个属性都可以像普通的 ref 对象一样访问和修改,而且会保持响应式的关联。toRefs 的使用场景主要是在将响应式对象作为属性传递给子组件时,确保子组件可以正确地访问和更新这些属性。
5、toRef和toRefs的相同点和不同点?
相同点:
- toRef 和 toRefs 都用于将响应式对象的属性转换为 ref 对象。
- 转换后的属性仍然保持响应式,对属性的修改会反映到源对象上。
- 不管是使用 toRef 还是 toRefs 将响应式对象转成普通对象,在 script 中修改和访问其值都需要通过 .value 进行。
-
不同点:
- toRef 修改的是对象的某个属性,生成一个单独的 ref 对象。
- toRefs 修改的是整个对象,生成多个独立的 ref 对象集合。
- toRefs 适用于在组件传递属性或解构时使用,更加方便灵活,而 toRef 更适合提取单个属性进行操作。
6、事件机制原理?
- Vue.js 的事件机制基于发布-订阅模式(Publish-Subscribe Pattern),也称为观察者模式(Observer Pattern)。它主要由以下几个核心组件构成:
- 事件触发器(Event Emitter):Vue 实例中的 $emit 方法用于触发事件。当某个事件被触发时,它会发送消息给注册了该事件的监听器。
- 事件监听器(Event Listener):Vue 实例中的 $on 方法用于监听特定的事件。当事件被触发时,注册了该事件的监听器会接收到通知,并执行相应的回调函数。
- 事件中心(Event Bus):Vue 实例中的 $emit 和 $on 方法的底层实现依赖于一个事件中心,用于管理事件的注册和触发。在 Vue 中,可以通过 new Vue() 创建一个全局事件中心,也可以创建多个局部事件中心。
- 事件对象(Event Object):当事件被触发时,可以传递一个事件对象作为参数,其中包含了关于事件的相关信息。事件对象可以携带额外的数据,以便监听器在接收到事件时进行处理。
7、Vue2和Vue3的diff算法有何不同?
- vue2中的diff算法
- 遍历每一个虚拟节点,进行虚拟节点对比,并返回一个patch对象,用来存储两个节点不同的地方。用patch记录的消息去更新dom
- 缺点:比较每一个节点,而对于一些不参与更新的元素,进行比较是有点消耗性能的。特点:特别要提一下Vue的patch是即时的,并不是打包所有修改最后一起操作DOM,也就是在vue中边记录变更新。(React则是将更新放入队列后集中处理)。
- vue3中的diff算法
- 在初始化的时候会给每一个虚拟节点添加一个patchFlags,是一种优化的标识。只会比较patchFlags发生变化的节点,进行识图更新。而对于patchFlags没有变化的元素作静态标记,在渲染的时候直接复用。
8、vue页面(组件)销毁时,哪些东西会自动销毁,哪些需要手动销毁?
- 自动销毁:
1. 数据和方法:组件的所有响应式数据和方法都会被销毁,这包括"data"函数中返回的所有属性和在组件中定义的方法
2. 侦听器:组件内部使用"watch"创建的侦听器会被自动移除
3. 子组件:当前组件的所有子组件也会经历同样的销毁过程
4. 事件监听器:如果在组件内部使用"this.$on"等方法绑定的事件监听器,它们通常在组件销毁时会被自动移除,然而,如果在外部(如在"mounted"生命周期钩子中)手动添加到DOM元素上的事件监听器,需要在"beforeDestroy"或"unmounted"生命周期钩子中手动移除它们
5. DOM元素:组件的DOM元素及其子元素会被从文档对象模型中移除
6. 指令:自定义指令将调用其"unbind"钩子函数
7. Ref引用:与该组件关联的所有Ref引用将失效
- 手动销毁
1. 全局事件监听器和定时器:window、document、定时器
2. 全局状态或单例:vuex、pinia等
3. 外部引用:如果该组件被外部变量引用,比如被添加到一个全局数组或对象中,这种引用关系不会自动解除
9、什么是虚拟 DOM?
- 虚拟dom本质就是一个js对象,用来描述真正dom是什么样的,这个对象就称为虚拟dom
10、虚拟 DOM 的好处?
- 虚拟 DOM 就是为了解决浏览器性能问题而被设计出来的。
- 若一次操作中有 10 次更新 DOM 的动作,虚拟 DOM 不会立即操作 DOM,而是将这 10 次更新的 diff 内容保存到本地一个 JS 对象中,最终将这个 JS 对象一次性 attch 到 DOM 树上
- 再进行后续操作,避免大量无谓的计算量
- 所以,用 JS 对象模拟 DOM 节点的好处是,页面的更新可以先全部反映在 JS 对象(虚拟 DOM )上,操作内存中的 JS 对象的速度显然要更快,等更新完成后,再将最终的 JS 对象映射成真实的 DOM,交由浏览器去绘制。