面试总结|Vue原理面试题

一、大厂必考原理 1.组件化和MVVM
2.响应式原理
3.vdom和diff算法
4.模板编译
5.组件渲染过程
6.前端路由
1.组件化基础=>(MVVM模型)
传统组件,知识静态渲染,更新依赖于操作DOM
数据驱动视图 - Vue MVVM
MVVM是Model-View-ViewModel缩写,也就是把MVC中的Controller演变成ViewModel。Model代表数据模型,View代表UI组件,ViewModel是View和Model层的桥梁,数据会绑定到ViewModel层并自动将数据渲染到页面中,视图变化的时候通知viewModel层更新数据

2.Vue响应式原理的实现
组件data的数据一旦改变,立马触发视图的更新。
核心API -- Object.defineProperty
Object.defineProperty有缺点(Vue3启用Proxy)
Proxy的兼容性不太好,且无法使用polyfill
Object.defineProperty基本用法
面试总结|Vue原理面试题
文章图片

Object.defineProperty实现响应式

  • 监听对象,监听数组
  • 复杂对象,深度监听
Object.defineProperty的缺点
  • 深度监听需要递归到底,一次性计算量大
  • 无法监听新增属性、删除属性(要使用Vue.setVue.delete)
  • 无法原生监听数组,需要特殊处理
总结;
1.核心API -- Object.defineProperty
2.如何监听对象(深度监听),如何监听数组
3.缺点
// 触发更新视图 function updateView() { console.log('视图更新') }// 重新定义数组原型 const oldArrayProperty = Array.prototype // 创建新对象,原型指向 oldArrayProperty ,再扩展新的方法不会影响原型 const arrProto = Object.create(oldArrayProperty); ['push', 'pop', 'shift', 'unshift', 'splice'].forEach(methodName => { arrProto[methodName] = function () { updateView() // 触发视图更新 oldArrayProperty[methodName].call(this, ...arguments) // Array.prototype.push.call(this, ...arguments) } })// 重新定义属性,监听起来 function defineReactive(target, key, value) { // 深度监听 observer(value)// 核心 API Object.defineProperty(target, key, { get() { return value }, set(newValue) { if (newValue !== value) { // 深度监听 observer(newValue)// 设置新值 // 注意,value 一直在闭包中,此处设置完之后,再 get 时也是会获取最新的值 value = https://www.it610.com/article/newValue// 触发更新视图 updateView() } } }) }// 监听对象属性 function observer(target) { if (typeof target !=='object' || target === null) { // 不是对象或数组 return target }// 污染全局的 Array 原型 // Array.prototype.push = function () { //updateView() //... // }if (Array.isArray(target)) { target.__proto__ = arrProto }// 重新定义各个属性(for in 也可以遍历数组) for (let key in target) { defineReactive(target, key, target[key]) } }// 准备数据 const data = https://www.it610.com/article/{ name:'zhangsan', age: 20, info: { address: '北京' // 需要深度监听 }, nums: [10, 20, 30] }// 监听数据 observer(data)// 测试 // data.name = 'lisi' // data.age = 21 // // console.log('age', data.age) // data.x = '100' // 新增属性,监听不到 —— 所以有 Vue.set // delete data.name // 删除属性,监听不到 —— 所有已 Vue.delete // data.info.address = '上海' // 深度监听 data.nums.push(4) // 监听数组

3.虚拟DOM(vdom)和diff算法
  • DOM操作非常耗费性能
  • 以前用jQuery,可以自行控制DOM操作时机,手动调整
  • vue和react都是数据驱动试图,如何有效控制DOM操作?
解决方案——vdom
  • 有一定的复杂度,想减少计算次数比较难
  • 难不能把计算,更多的转移为JS计算?因为JS执行比较快
  • vdom——用JS模拟DOM结构,计算出最小的变更,操作DOM
面试题:用JS模拟DOM元素
包含三部分:标签tag,附着在标签上的属性、样式、事件props,子元素children
面试总结|Vue原理面试题
文章图片

通过snabbdom 学习vdom
  • vue3重写了vdom的代码,优化了性能
  • 但vdom的理念不变,面试考点不变
h函数、vnode数据结构、patch函数
vdom总结
  • 用js模拟DOM结构(vnode)
  • 新旧vnode对比,得出最小的更新范围,最后更新DOM
  • 数据驱动视图的模式下,有效控制DOM操作
diff算法
两个数做diff,如这里的vdom diff
面试总结|Vue原理面试题
文章图片

vnode->patch ->new vnode
树diff的时间复杂度O(n^3)
  • 第一,遍历tree1;第二,遍历tree2
  • 第三,排序
  • 1000个节点,要计算1亿次,算法不可用
优化时间复杂度到O(n)
  • 只比较同一层级,不跨级比较
  • tag不相同,直接删掉重建,不再深度比较
  • tag和key,两者都相同,则认为是相同的节点,不再深度比较
面试总结|Vue原理面试题
文章图片

面试总结|Vue原理面试题
文章图片

diff算法总结
  • patchVnode
  • addVnodes removeVnodes
  • updateChildren(key的重要性)
vdom和diff总结
  • 细节不重要,updateChildren更新过程也不重要,不要深究
  • vnode核心概念很重要:h vnode patch diff key 等
  • vnode的存在价值更重要:数据驱动试图,控制DOM操作
4.模板编译
面试总结|Vue原理面试题
文章图片

面试总结|Vue原理面试题
文章图片

with语法
面试总结|Vue原理面试题
文章图片

面试总结|Vue原理面试题
文章图片

模板编译
面试总结|Vue原理面试题
文章图片

总结
面试总结|Vue原理面试题
文章图片

vue中使用render代替template
面试总结|Vue原理面试题
文章图片

总结
面试总结|Vue原理面试题
文章图片

5.组件渲染更新过程
vue原理的三大知识点
面试总结|Vue原理面试题
文章图片

组件渲染/更新过程
初次渲染过程
面试总结|Vue原理面试题
文章图片
第二步是因为,执行render函数会触发getter操作
面试总结|Vue原理面试题
文章图片

更新过程
面试总结|Vue原理面试题
文章图片

触发setter,看是修改的data是否在getter中已经被监听,如果是,就执行render函数
patch的diff算法,会计算出最小差异,更新在DOM上
完整流程图
面试总结|Vue原理面试题
文章图片

模板编译完,生成render函数,执行render函数生成vnode (虚拟DOM的树)
执行render函数的时候会touch getter,即执行函数的时候回触发Data里的getter
触发的时候就会收集依赖,即在模板中出发了哪个变量的getter就会把哪个给观察起来(watcher)
在修改Data的时候,看这个Data是否是之前作为依赖被观察起来的
如果是,就重新出发re-render,重新渲染,重新生成vdom tree,重新touch
异步渲染
1.$nextTick:
vue是异步渲染,$nextTick会待Dom渲染完之后调用
页面渲染时会将data的修改做整合,多次data修改只会渲染一次
2.汇总data的修改,一次性更新试图
3.减少DOM操作次数,提高性能
6.前端路由原理
网页url组成部分
面试总结|Vue原理面试题
文章图片

hash的特点
面试总结|Vue原理面试题
文章图片

hash test - 锐客网hash test


H5 history
  • 用url规范的路由,但跳转时不刷新页面
  • history.pushState
  • window.onpopstate
面试总结|Vue原理面试题
文章图片

history API test - 锐客网history API test

总结
面试总结|Vue原理面试题
文章图片

两者选择
面试总结|Vue原理面试题
文章图片


to c的要是不需要管seo、搜索引擎也不需要用H5 history 简单一点就好



【面试总结|Vue原理面试题】

    推荐阅读