互联网寒冬的来袭,如何在面试之前更高效的做好面试准备,是程序员共同关注的问题。
现在面试门槛越来越高,很多开发者对于 Vue 底层的一些知识了解的不是很多,遇到这些面试题会手足无措。
在本文中,会结合面试过程中的一些问题带你剖析 Vue.js 内部的整个流程,总共分为四个模块:
- 响应式原理以及依赖收集
- 异步更新策略及 nextTick 原理
- 虚拟(Virtual )DOM 和 Diff 算法
- 数据状态管理 Vuex 工作原理
当你全部掌握这些知识后,足可以应对所有的前端 Vue 技术面试。
响应式原理以及依赖收集
这一章节应该是在 Vue 面试中出现频率最多,也是面试官最喜欢问的一个话题,当然在实际面试中不会直接问你什么是 Vue 的响应式原理以及依赖收集,这里列举了一些可能会出现的问题:
- Vue 是如何实现双向绑定的,什么是 MVVM?
- 你了解过 Object.defineProperty 这个 API 吗,和 Proxy 有啥区别?
- Vue 是如何深度监听并且对数组进行监听?
- Vue 的依赖收集是做啥的,实现的过程有哪些?
面对这类问题,可谓万变不离其宗。考察的重点当然也是对 Vue 响应式原理的理解。用下面这句话来概括何为响应式:
当一个状态改变之后,与这个状态相关的事务也立即随之改变,从前端来看就是数据状态改变后相关 DOM 也随之改变。
要做到这一点,Vue 借助 Object.defineProperty() 这个 api 去实现,用它来对数据进行劫持操作。在我们访问或者修改某个对象的某个属性的时候,通过一段代码进行拦截,然后再进行额外的操作,返回结果。Vue3 改为 Proxy()后文会在详细讲解,这里我们的关注点是 Object.defineProperty()。在 MDN 中它是这样定义的:
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
Object.defineProperty(obj, prop, descriptor)
- obj:要定义属性的对象;
- prop:要定义或修改的属性名称;
- descriptor:要定义或修改的属性描述符。
下面的代码是 Object.defineProperty 的一个简单的案例,从代码中可以看到当改变 name 的值在 set 中会进行拦截,加入一些额外的操作,在执行结果。
const data = {}
const name = 'zhangsan'
Object.defineProperty(data, 'name', {
get: function () {
console.log('get')
return name
},
set: function (newVal) {
console.log('set')
name = newVal
}
})
data.name = 'lisi' // 打印'set'
Vue 也是如此,当把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 property,并使用 Object.defineProperty 把这些 property 全部转为 getter/setter。简单理解就是在 data 和用户之间做了一层代理中间层,在 vue initData 的时候,将_data 上面的数据代理到 vm 上,通过 observer 类将所有的 data 变成可观察的,及对 data 定义的每一个属性进行 getter\setter 操作,这就是 Vue 实现响应式的基础。