面试官问:vue3相关的面试题

432 阅读8分钟

vue3 响应式原理

1、 Vue 3 基于 ES6 的 Proxy 特性来拦截对象的读取(get)和设置(set)操作Proxy 可以拦截对象的任意操作,不仅仅是属性访问。

2、 Vue 3 使用 ref 和 reactive 来创建响应式引用:

  • ref: 用于创建一个响应式的原始值(如字符串、数字)或响应式对象。
  • reactive: 用于创建一个响应式对象,它会对对象的所有属性进行代理。

3、 Vue 3 使用 effect 函数来跟踪响应式数据的变化。当响应式数据发生变化时,与之相关的副作用(通常是组件的渲染函数或其他观察者)会被重新执行。

vue3和vue2的区别

1.主要区别是响应式原理不同

vue2的defineProperty无法响应新增属性(可以通过this.$set解决)而vue3的Proxy不存在该缺陷。 vue2会把整个data进行递归数据劫持,而vue3只有在用到某个对象时,才进行数据劫持,所以响应式更快并且占内存更小。

虚拟dom优化:Vue3 相比于 Vue2 虚拟DOM 上增加patchFlag字段。

Diff 优化:patchFlag字段帮助 diff 时区分静态节点,以及不同类型的动态节点。一定程度地减少节点本身及其属性的比对。 vue3 和 vue2的虚拟dom的diff算法有什么不同 ? Vue3 的快速 Diff 算法比 Vue2 的双端 Diff 算法效率高,Vue3 提升 Diff 算法性能的关键是根据新旧 dom 序列位置的变化,构造了一个最长递增子序列,从而找到更新前后相对位置不变的节点的位置,最大限度地降低了 dom 移动的次数,从而提升了 Diff 算法的性能。

2.其他api不同

比如生命周期api不同(beforeCreate、created都在setup执行),生命周期名字大部分需要+on

3.写法上的区别

vue3支持ts, vue3可以多根节点。声明响应式变量使用了ref和reactive。

4.异步组件

Vue3 提供Suspense组件,允许程序在等待异步组件时渲染兜底的内容,如 loading ,使用户体验更平滑。使用它,需在模板中声明,并包括两个命名插槽:defaultfallbackSuspense确保加载完异步内容时显示默认插槽,并将fallback插槽用作加载状态。 若想在 setup 中调用异步请求,需在 setup 前加async关键字。这时,会受到警告async setup() is used without a suspense boundary。 解决方案:在父页面调用当前组件外包裹一层Suspense组件。(使用场景骨架屏)

生命周期api

对于生命周期来说,整体上变化不大,只是大部分生命周期钩子名称上 + “on”,功能上是类似的。不过有一点需要注意,Vue3 在组合式API(Composition API,下面展开)中使用生命周期钩子时需要先引入,而 Vue2 在选项API(Options API)中可以直接调用生命周期钩子,如下所示。

vue2vue3说明
beforeCreatesetup组件创建之前,执行初始化任务
createdsetup组件创建完成,访问数据、获取接口数据
beforeMountonBeforeMount组件挂载之前
mountedonMounted组件挂载完成,DOM已创建,访问数据或DOM元素,访问子组件
beforeUpdateonBeforeUpdate未更新,获取更新前所有状态
updatedonUpdated组件挂载完成,DOM已创建,访问数据或DOM元素,访问子组件
beforeDestroyonBeforeUnmount未更新,获取更新前所有状态
destroyedonUnmounted组件销毁之后

Tips: setup 是围绕 beforeCreate 和 created 生命周期钩子运行的,所以不需要显式地去定义。

vue3的值传递

defineProps:子组件接收父组件传来的
defineEmits:子组件接收父组件传来的方法
defineExpose:子组件暴露自己的属性或方法

  • 七种Vue3传值方式 props emit v-model refs provide/inject eventBus vuex/pinia(状态管理工具) Vue3中移除了事件总线,但是可以借助于第三方工具来完成,Vue官方推荐mitt[2]或tiny-emitter[3]

ref和reactive的区别

  1. 类型支持:

    • reactive 主要用于对象和数组,不支持基本数据类型。
    • ref 可以用于基本数据类型和对象/数组。
  2. 内部处理:

    • reactive 直接代理整个对象,使其所有属性都是响应式的。
    • ref 创建一个包含 value 属性的对象,只有 value 属性是响应式的。
  3. 模板中使用:

    • 在模板中,reactive 对象的属性可以直接使用,不需要额外的操作。
    • ref 在模板中会自动解构,不需要写 .value,但在 JavaScript 中访问 ref 的值时需要加上 .value
  4. 响应式检测:

    • 检测 reactive 对象使用 isReactive
    • 检测 ref 使用 isRef
  5. 类型推断:

    • reactive 对象的类型推断更为直接,因为它直接操作对象本身。
    • ref 需要类型断言来帮助 TypeScript 正确推断类型。
  6. 性能:

    • reactive 对象的性能开销相对较小,因为它只需要一次代理。
    • ref 对象在每次访问或修改值时都需要通过 value 属性,可能会有轻微的性能开销。

在实际应用中,根据数据的使用场景和类型选择 reactive 或 ref。对于对象和数组,通常使用 reactive;对于基本数据类型,或者需要在 JavaScript 和模板中一致地处理的数据,使用 ref

总结来说这种设计允许Vue更好地管理其视图更新,确保当数据变化时,视图能够得到相应的更新。

vue3如何检测一个对象是否是响应式的?

import { reactive, isReactive } from 'vue';
const obj = reactive({ count: 0 });
console.log(isReactive(obj)); // 输出: true
const nonReactiveObj = { count: 0 };
console.log(isReactive(nonReactiveObj)); // 输出: false

在这个例子中,obj 是一个响应式对象,所以 isReactive(obj) 返回 true。而 nonReactiveObj 是一个普通对象,不是响应式的,所以 isReactive(nonReactiveObj) 返回 false

请注意,isReactive 只适用于检测通过 reactive 函数创建的响应式对象。如果你想要检测一个对象是否是由 ref 创建的响应式引用,你应该使用 isRef 函数。如果你想要检测一个对象是否是响应式的(无论是通过 reactive 还是 ref 创建的),你可以使用 isProxy 函数。

import { reactive, isProxy } from 'vue';
const state = reactive({ count: 0 });
console.log(isProxy(state)); // 输出: true
console.log(isProxy({ count: 0 })); // 输出: false

vue3如何获取this

在Vue 3中,获取组件实例的方法有以下几种:

  1. 在Vue 3中,可以使用getCurrentInstance函数来获取当前组件的实例。这个函数返回一个ComponentPublicInstance类型的对象,我们可以通过访问这个对象的属性和方法来操作组件。例如:const instance = getCurrentInstance();
  2. 可以使用Vue 3中的ref函数来创建一个响应式的变量,然后将组件实例赋值给这个变量。这样可以通过访问这个变量来获取组件实例。例如:const instance = ref(null);,然后在组件的setup函数中使用instance.value = this;来将组件实例赋值给变量。

Vue3中虚拟DOM的diff算法有哪些优化

  1. Fiber节点:  Vue 3引入了Fiber节点树,用于支持异步可中断的渲染。这意味着在更新组件时,Vue可以在执行过程中进行中断,并在需要时继续渲染。(引入Fiber节点树支持异步可中断的渲染)
  2. 新的diff算法:  Vue 3中的diff算法采用了基于键的优化策略,这意味着Vue会尝试复用同一层级内具有相同键的元素。(基于键的优化策略)
  3. Patch flag:  Vue 3为每个组件指定了一个bitmask,用于在diff过程中标记哪些属性发生了变化,这使得Vue可以直接修改那些需要变更的属性,而不是每次都重新渲染整个组件。(指定了一个bitmask标记属性发生了变化)
  4. Fragment支持:  Vue 3支持渲染多个元素或组件而无需包裹在一个外层元素中,这通过Fragment实现。(增加了Fragment抽象组件实现支持多根节点)
  5. ssr

vue3 有哪些watch 区别是什么

  • ‌watch可以精确地监听一个或多个响应式数据

watchEffect:

  • 自动监听所有响应式数据‌:不需要指定具体的数据,所有响应式数据的变化都会触发回调函数。
  • 无返回值‌:回调函数不接受新值和旧值作为参数。
  • 执行时机‌:在组件初始化时立即执行一次,之后在响应式数据变化时再次执行

Vue3,setup()函数与< script setup >到底有什么本质区别

  • setup() 自动暴露组件的公共方法和属性
  • < script setup > 是语法躺最终还是会转换为setup()
  • (插件vite-plugin-inspect可以看穿vue 背后做的事情)