Vue常见题解--待写完

161 阅读4分钟

1.那你能讲一讲MVVM吗?

MVVM是Model-ViewModel-View的缩写,是把MVC中的Controller拆成了View-Model,Model代表数据模型,View代表UI界面,ViewModel是view和model的桥梁。数据会绑定到ViewModel并自动渲染到View中,视图变化的时候通过ViewModel层更新数据。

2.简单说一下Vue2.x响应式数据原理?

Vue在初始化数据时,会通过Object.defineProperty重新定义data中的所有属性。当页面使用对应属性时,首先会进行依赖收集(收集当前组件的Watcher),如果属性发生变化,会通知相关依赖进行更新操作。

3.那你知道Vue3.x响应式数据原理吗?

Vue3使用Proxy替代Object.defineProperty。同时Proxy可以监听对象和数组的变化,并且有多达13种拦截方法。

3.1 Proxy只会代理对象的第一层,那么Vue3又是怎样处理这个问题的呢?--需要提问

判断当前Reflect.get的返回值是否是Object,如果是再通过Reactive方法做代理,实现深度监测。

3.2 监测数组的时候可能触发多次get/set,那么如何防止触发多次呢?--需要提问

我们可以判断key是否为当前被代理对象target自身属性,也可以判断旧值与新值是否相等,只有满足以上两个条件之一时,才有可能执行trigger。

4.再说一下vue2.x中如何监测数组变化?

使用了函数劫持的方式,重写了数组的方法。Vue将Data中的数组进行了原型链重写,将其指向了自己定义的数组原型链方法。这样当调用数组的Api时,就可以通知依赖进行更新。如果数组包含着引用类型,会对数组中的引用类型再次遍历进行监控,这样就实现了监测数组变化。

5.nextTick知道吗,实现原理是什么?--需要提问

在下次Dom更新循环结束之后执行延迟回调。nextTick主要使用了宏任务和微任务。根据执行环境分别采用

  • Promise
  • MutationObserver
  • setImmediate
  • 如果以上都不行则采用setTimeout

定义了一个异步方法,多次调用nextTick会将方法存入队列中,通过这个异步方法清空当前队列。

6.说一下Vue的生命周期?

  • beforeCreate是new Vue()后执行的第一个钩子,在当前阶段,data,pros,methods,computed以及watch上的数据和方法均不能被访问。

  • created在实例创建完后执行,当前阶段已经完成了数据注入及监测,也就是可以使用数据,更改数据。在这里修改数据并不会触发updated函数,可以做一些初始数据的获取,在当前阶段无法与Dom交互,如果非要想,可以通过vm.$nextTick来访问Dom。

  • beforeMount发生在挂载之前,在之前template模板已导入渲染函数编译。当前阶段虚拟dom已经创建完成,即将开始渲染。在此时可以对数据进行更改,不会触发updated函数。

  • mounted在挂在完成后发生,在当前阶段,真实的dom挂载完毕,数据完成双向绑定,可以访问Dom节点,使用$refs属性对Dom进行操作。

  • beforeUpdate发生在更新之前,也就是响应式数据发生更新,虚拟dom重新渲染之前被触发,你可以在当前阶段进行更改数据,不会造成重渲染。

  • updated发生在更新完成之后,当前阶段组件Dom已完成更新。要注意的是避免在此期间更改数据,因为这可能会导致无限循环的更新。

  • beforeDestroy发生在实例销毁之前,在当前阶段实例完全可以被使用,我们可以在这时进行善后收尾工作,比如清除计时器。

  • destroyed发生在实例销毁之后,这个时候只剩下了dom空壳。组件已被拆解,数据绑定被卸除,监听被移出,子实例也统统被销毁。

7.你的接口请求一般放在哪个生命周期中?

8.再说一下Computed和Watch?

9.说一下v-if和v-show的区别?

10.组件中的data为什么是一个函数?

11.说一下v-model的原理?

12.Vue事件绑定原理说一下?

13.Vue模版编译原理知道吗,能简单说一下吗?

14.Vue2.x和Vue3.x渲染器的diff算法分别说一下?

15.再说一下虚拟Dom以及key属性的作用?

16.keep-alive了解吗?

17.Vue中组件生命周期调用顺序说一下?

18.Vue2.x组件通信有哪些方式?

19.SSR了解吗?

20.你都做过哪些Vue的性能优化?

21.Vue Mixin实现方式?

它的实现实际上非常简单,就是把要混入的对象通过 mergeOptions 合并到 Vue 的 options 中,由于每个组件的构造函数都会在 extend 阶段合并 Vue.options 到自身的 options 中,所以也就相当于每个组件都定义了 mixin 定义的选项。

export function initMixin (Vue: GlobalAPI) {
  Vue.mixin = function (mixin: Object) {
    this.options = mergeOptions(this.options, mixin)
    return this
  }
}

附录一些感觉不错的文字性总结

  • Vue.js 2.x 中通过 Object.defineProperty() 来劫持对象中的属性,给属性添加 setter,getter,每一个属性创建一个 dep 对象,dep 负责收集依赖,在数据变动时 dep 对象通知 watcher 对象,watcher 内部负责更新视图

参考