面试题

46 阅读4分钟

4.谈一谈对 MVVM 的理解? MVVM是Model-View-ViewModel缩写,也就是把MVC中的Controller演变成ViewModel。Model层代表数据模型,View代表UI组件,ViewModel是View和Model层的桥梁,数据会绑定到viewModel层并自动将数据渲染到页面中,视图变化的时候会通知viewModel层更新数据。

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

6.v-model 双向绑定的原理是什么? v-model本质就是一个语法糖,可以看成是value + input方法的语法糖。 可以通过model属性的prop和event属性来进行自定义。原生的v-model,会根据标签的不同生成不同的事件和属性 。

7.vue2.x 和 vuex3.x 渲染器的 diff 算法分别说一下? 简单来说,diff算法有以下过程

同级比较,再比较子节点 先判断一方有子节点一方没有子节点的情况(如果新的children没有子节点,将旧的子节点移除) 比较都有子节点的情况(核心diff) 递归比较子节点 正常Diff两个树的时间复杂度是O(n^3),但实际情况下我们很少会进行跨层级的移动DOM,所以Vue将Diff进行了优化,从O(n^3) -> O(n),只有当新旧children都为多个子节点时才需要用核心的Diff算法进行同层级比较。

Vue2的核心Diff算法采用了双端比较的算法,同时从新旧children的两端开始进行比较,借助key值找到可复用的节点,再进行相关操作。相比React的Diff算法,同样情况下可以减少移动节点次数,减少不必要的性能损耗,更加的优雅。

Vue3.x借鉴了 ivi算法和 inferno算法

在创建VNode时就确定其类型,以及在mount/patch的过程中采用位运算来判断一个VNode的类型,在这个基础之上再配合核心的Diff算法,使得性能上较Vue2.x有了提升。(实际的实现可以结合Vue3.x源码看。)

该算法中还运用了动态规划的思想求解最长递归子序列。

8.vue组件通信方式有哪些及原理 父子组件通信

父->子props,子->父 onon、emit

获取父子组件实例 parentparent、children

Ref 获取实例的方式调用组件的属性或者方法

Provide、inject 官方不推荐使用,但是写组件库时很常用

兄弟组件通信

Event Bus实现跨组件通信Vue.prototype.$bus = new Vue Vuex 跨级组件通信

Vuex attrsattrs、listeners 9. Vue的路由实现, hash路由和history路由实现原理说一下 location.hash的值实际就是URL中#后面的东西。 history实际采用了HTML5中提供的API来实现,主要有history.pushState()和history.replaceState()。

  1. 说一下 v-if 与 v-show 的区别 当条件不成立时,v-if不会渲染DOM元素,v-show操作的是样式(display),切换当前DOM的显示和隐藏。

  2. keep-alive的常用属性有哪些及实现原理 keep-alive可以实现组件缓存,当组件切换时不会对当前组件进行卸载。

常用的两个属性include/exclude,允许组件有条件的进行缓存。

两个生命周期activated/deactivated,用来得知当前组件是否处于活跃状态。

keep-alive的中还运用了LRU(Least Recently Used)算法。

  1. nextTick 的作用是什么?他的实现原理是什么? 在下次 DOM 更新循环结束之后执行延迟回调。nextTick主要使用了宏任务和微任务。根据执行环境分别尝试采用

Promise MutationObserver setImmediate 如果以上都不行则采用setTimeout 定义了一个异步方法,多次调用nextTick会将方法存入队列中,通过这个异步方法清空当前队列。