vue3面试知识点十大问

1.vue2中的响应式与vue3中有什么不同 vue2中响应式采用Object.defineProperty对对象中的属性进行getset拦截。创建observer类,为每个数据创建一个数组来管理依赖,在getter中收集依赖,在setter中通知依赖更新。所以每当属性进行读写操作时就会触发getset,从而实现对属性的监听。
vue2中对对象属性的访问需要先知道特定的key,所以对于对象中新增的属性、数组中通过下标新增数据会有些不足。
vue2中的全局的$set方法的本质就是给新增的属性手动observer

Object.defineProperty(car, 'price', { get() {}, set() {} })

vue3中的响应式则是借助Proxytarget是目标对象可以是数组甚至是另一个代理,handler通常是用来定制拦截行为,通常含有 hasgetsetdeleteProperty等方法。可以看到vue3对对象的代理不依赖对象属性,所以可以很好的解决vue2中的不足。
const proxy = new Proxy(target, { get: function(target, propKey, receiver) { return '10' } })

2.vue3比vue2优化了哪些地方
  • 全局API的修改:vue2中是导出全局的vue对象,在单元测试中,很容易污染全局环境以及带来冲突。vue3中通过createApp 创建app实例,一切操作修改从直接操作Vue全局对象,转变成了操作vue实例
  • 一些全局的api支持了tree-shaking,变成了具名的导出,从vue对象中脱离。如nextTick的引用方式从Vue.nextTicke变成了import {nextTick, observable} from vue
  • 通过Composition API以逻辑来划分代码,更好的重用代码,vue2中对代码的抽离可以通过mixins,但是mixins存在命名冲突、暴露出来的变量来源不清晰等问题。composition api可以进行重命名,避免了命名冲突。
  • 对typescript更好的支持
  • 新增了一些其他的特性,比如teleportsuspense
3.vue3中的suspense组件 vue3中使用defineAsyncCompoent方法,方法接受返回promise的工厂函数,动态加载组件
const AsyncComp = defineAsyncComopent( () => new Promise((resolve, reject) => { resolve({ template: 'test' }) }) )

vue2中则是直接通过import导入。
4.vue3中的teleport组件 teleport像是一个传送门,允许我们控制在哪个dom节点下呈现html。to属性接受一个querySelector,设置父级节点。
实现原理:通过createBlock生成一个vnode,创建teleport组件,通过调用Teleport.process,选中父节点,mountChildren方法挂在到dom中。

5.说说虚拟dom及vue3中对虚拟dom对优化 虚拟dom就是一个js对象来描述dom节点,当数据发生变化时,对比变化前后的虚拟dom节点,通过dom-diff算法计算出需要更新的地方,然后来更新需要的视图。
vue中通过VNode类来实例化出不同类型的虚拟dom,比如注释节点通过isComment来表示是否是注释节点,text表示具体的注释信息。
export const createEmptyVNode = (text: string = '') => { const node = new VNode(); node.text = text; node.isComment = true; return node; }

优化前,在一个默认的Virtual Dom的diff中,需要遍历所有节点,去比较旧的props和新的props有没有变化
【vue3面试知识点十大问】而优化之后,创建的vnode多了patch flag标记该节点的可变属性,当 diff 算法走到 _createBlock 函数的时候,会忽略所有的静态节点,只对有标记的动态节点进行对比,而且在多层的嵌套下依然有效。
6.vue3中的生命周期 vue3面试知识点十大问
文章图片

beforeCreate和create几乎是同时在setup函数中进行触发的。生命周期函数的书写OnBeforeMount、OnMounted、onUpdated
vue3中多了两个调试钩子函数onRenderTracked onRenderTriggered,顾名思义就是在render重新绘制时进行触
7.vue中的key有什么作用
  • dom-diff中标识Vnode,标识变化前后是否是同一个组件
  • 通过key复用元素,所以修改某一个元素的key可以重新渲染该元素
8.vue3 的 watch 与 vue2 中有哪些不同
  • vue3 中的 watch 函数第一个参数为响应式对象、有 getter/settereffect 函数、或者这些类型数组;第二个参数为数据变化时的回调;第三个参数为 watchOption,提供是否立即监听和是否深度监听的配置。
  • vue3 可以多次使用 watch 方法
    watch(data, () => {}) watch(() => data.name, () => {}) watch([data, name], () => {})

  • vue3 的 setup 中不存在 this 对象,监听路由需要使用 vue-router 提供的 userRoute,vue2 则是在 watch 对象里添加'$route'进行监听
    import { useRoute } from "vue-router"; // setup const route = useRoute(); const userData = https://www.it610.com/article/ref(); // 当参数更改时获取用户信息 watch(() => route.params, () => {});

9.vue3中watchEffect与watch的异同 不同点:
  • watchEffect立即执行传入的函数,在初始化时自动收集依赖,并在其依赖变更时重新运行该函数
  • watchEffect无法获取原值,只能得到变化后的值
相同点:两者都可通过StopHandle.stop()函数手动停止监听
const stopHandle = watchEffect(); handle.stop();

10.v-model的原理及vue3中v-model的改变 v-model通过在数据修改时,通知父级节点实现数据的双向绑定。其实是一个语法糖当满足以下两个条件时,可实现自定义组件的v-model:
  • 子组件受控接收prop
  • 数据修改时触发event把新的数据提交给父组件
props: { value: String }, model: { prop: 'value', event: 'change' }

vue3中升级了v-mode的用法,通过update:modelValue来触发事件,prop也被更改为modelValue。还在一个组件上支持多个v-model,如新增v-model:lastName等。
props: { modelValue: String, } emits: ['update:modelValue'], methods: { changeTitle() { this.$emit('update:modelValue', title) } }

参考链接
  • 抄笔记:尤雨溪在Vue3.0 Beta直播里聊到了这些
  • Vue原理解析(八):一起搞明白令人头疼的diff算法

    推荐阅读