# VUE面试题

外链:
前端面试·Vue.js (opens new window)
🐮化身面试官出30+Vue面试题,超级干货(附答案) (opens new window)

# 1.说一下Vue的优点

  • 体积小
    • 压缩后只有33K;
  • 更高的运行效率
    • 基于虚拟DOM, 一种可以预选通过JavaScript进行各种计算, 把最终的DOM操作计算出来并优化的技术,由于这个DOM操作属于预处理操作, 并没有真正地操作DOM, 所以叫虚拟DOM。
  • 双向数据绑定
    • 让开发者不用再去操作DOM对象, 把更多的精力投入到业务逻辑上。

# 2.说一下Vue的生命周期

Vue 实例有一个完整的生命周期,也就是从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。通俗说就是 Vue 实例从创建到销毁的过程,就是生命周期。

Vue生命周期可以分为三个阶段:创建阶段、运行阶段、销毁阶段

  • 创建阶段的生命周期方法
  1. beforeCreate
    在调用beforeCreate的时候, 仅仅表示Vue实例刚刚被创建出来
    此时此刻还没有初始化好Vue实例中的数据和方法, 所以还不能访问Vue实例中保存的数据和方法

  2. created
    在调用created的时候, 是我们最早能够访问Vue实例中保存的数据和方法的地方

  3. beforeMount
    在调用beforeMount的时候, 表示Vue已经编译好了最终模板, 但是还没有将最终的模板渲染到界面上

  4. mounted
    在调用mounted的时候, 表示Vue已经完成了模板的渲染, 我们已经可以拿到界面上渲染之后的内容了

  • 运行阶段的生命周期方法
  1. beforeUpdate
    在调用beforeUpdate的时候, 表示Vue实例中保存的数据被修改了
    只有保存的数据被修改了才会调用beforeUpdate, 否则不会调用
    在调用beforeUpdate的时候, 数据已经更新了, 但是界面还没有更新

  2. updated
    在调用updated的时候, 表示Vue实例中保存的数据被修改了, 并且界面也同步了修改的数据了
    也就是说: 数据和界面都同步更新之后就会调用updated

  • 销毁阶段的生命周期方法
  1. beforeDestroy
    在调用beforeDestroy的时候, 表示当前组件即将被销毁了
    只要组件不被销毁, 那么beforeDestroy就不会调用。beforeDestroy函数是我们最后能够访问到组件数据和方法的函数

  2. destroyed
    在调用destroyed的时候, 表示当前组件已经被销毁了
    只要组件不被销毁, 那么destroyed就不会调用。在这个生命周期方法中无法再去操作组件中数据和方法

# 3.Vue2是如何实现双向数据绑定的(Vue双向数据绑定原理)

mvvm 双向绑定,采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的 setter、getter,在数据变动时发布消息给订阅者,触发相应的监听回调。

Vue主要通过以下4个步骤实现数据双向绑定:
1、实现一个数据监听器 Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者
2、实现一个指令解析器 Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数
3、实现一个订阅者 Watcher,作为连接 Observer 和 Compile 的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图
4、最后实现 MVVM 作为数据绑定的入口,整合监听器、解析器和订阅者

# 4.为什么需要使用Key(Vue 中 key 值的作用?)

需要使用 key 来给每个节点做一个唯一标识,Diff 算法就可以正确的识别此节点,找到正确的位置区插入新的节点,所以简单的说,key 的作用主要是为了高效的更新虚拟 DOM

比如渲染一堆input框,中间删除一个就会产生问题,下面的input会被顶上来,vue会选择复用节点(Vue的就地更新策略),导致之前节点的状态被保留,从而产生一系列的bug

# 5. vue3 新特性,影响

  • 性能提升
  • 更小巧。更快捷支持自定义渲染器支持摇树优化
  • 一种在打包时去除无用代码的优化手段,支持fragments和跨组件渲染
  • api 变动
  • 语法模板99%保持不变,原生支持class的组件,并无需借助任何编译及各种stage阶段的特性,在设计时也考虑Typescript的类型推断特性重写虚拟dom可以期待更多的编译时提示减少运行的开销优化插槽可以单独渲染父组件和子组件,静态树提升降低渲染成本,基于proxy的观察者机制节省内存开销
  • 不兼容ie11
  • 检测机制更见全面、精准、高校,更具有调试的相应跟踪

# 6. 实现双向绑定Proxy与Object.defineProperty相比优劣如何?

  • Object.defineProperty的作用时劫持一个对象的属性,劫持属性的getter和setter方法,在对象的属性发生变化时进行特定的操作。而Proxy劫持的时整个对象

  • Proxy会返回一个代理对象,我们只需要操作新的对象即可。而Object.defineProperty只能遍历对象属性直接修改

  • Object.defineProperty不支持数组,更准确的说时不支持数组的各种api,因为如果仅仅考虑arr[i] = value这种情况,是可以的,但是这种劫持意义不大。而Proxy可以支持数组的各种Api

  • 尽管Object.defineProperty有诸多缺陷,但其兼容性要好于Proxy

Last Updated: 8/5/2021, 6:16:29 PM