如果不使用key 更新了3次 一次插入操作 使用了key只做了一次插入操作
结论:
1、key的作用主要是为了高效的更新虚拟DOM,其原理是vue在patch过程中通过key可以精准的判断两个节点是否是同一个,从而避免频繁更新不同元素,使得整个patch过程更加高效,减少了dom的操作量,提高性能
2、如果不设置key可能在列表更新时引发一些隐藏的bug 比如说更新和不更新看不出来。
3、vue中在使用相同标签名元素的过渡切换是,也会用到key属性,其目的也是为了让vue可以区分他们,否则vue只会替换其内部属性而不会触发过渡效果。需要用key来作为唯一性的判断。
4、怎么理解vue中的diff算法
总结:
diff算法:并非vue中专用,凡是涉及到虚拟dom中都有diff算法
必要性:diff算法能精确的比较新旧虚拟DOM中的key的变化,从而提高更新效率
执行方式:深度优先,同级比较
高效性:查看源码得知
1、diff算法必要性:
分析:任何一个vue组件实例,再去创建完成之后,去挂载的时候调用的,一个组件调用一次mounted,同时也会调用右侧watcher,在vue中 watcher的实例和vue的实例是一一对应的。
结论:组件中存在多个data中key的使用,怎么确保key发生了变化,执行diff算法就可以比较新旧两次虚拟dom的比较,为了精确的知道
2、diff算法的执行方式
核心源码:586行开始
分析:patchVnode是diff发生的地方,整体策略:深度优先,同层比较, 先开始比较根节点,看看是否有子节点,如果都有,更新子节点 在比较子节点,直到底层。 具体代码 如果找到直接更新子节点,如果没有就看有其他的操作,
3、diff算法的高效性:
就是上面提到的updateChildern()
总结: 1、diff算法是虚拟DOM技术的必然产物:通过新旧虚拟DOM做对比(既diff),将变化的地方更新在真实DOM上,另外,也需要diff高效的执行对比过程,从而降低时间复杂度为O(n)
2、vue2.0x中为了降低watcher粒度,每个组件只有一个watcher与之对应,只有引入diff才能精确的找到发生变化的地方
3、vue中diff执行的时刻是组件实例执行更新函数时,它会对比与上一次渲染结果oldVnode和新的渲染结果,此过程称为patch
4、diff过程整体遵循深度优先,同层次比较的策略,两个节点之间比较会根据他们是否拥有子节点或者文本节点做不同操作,比较两组子节点是算法重点,首先假设头部节点可能相同做4次对比尝试,如果没有找到相同节点才按照通用的方式去进行遍历查找,查找结束再按情况处理剩下的节点,借助key通常可以非常精确找到相同节点,因此整个patch过程非常高效。
5、vue组件化的理解
总体回答思路: 组件化定义,优点,使用场景和注意事项等方面展开称述,同时要强调vue组件化中一些特点
1、源码分析:组件定义
把一些独立的功能单独提出来,有独立的函数,方便复用 vue中常见的定义第一种是全局定义 第二种是单文件组件的定义
源码:src/global/assets.js/
更多面试题请看 web前端面试题库 VS java后端面试题库大全
2、源码分析:组件化优点
源码:lifecycle.js-mountComponent()
组件化优点:维护性 测试性,复用性,从组件 Watcher,渲染函数中去分析
在执行组件的时候,每一个组件会对应一个watcher,组件边变化的时候只会调用组件里面的渲染函数,可以把经常发生数据变化的单独放一个组件中,后期只需要执行这一个函数,起到局部刷新的作用。
3、组件化的实现
构造函数:src/core/global-api/extend.js 实例化及挂载:src/core/vdom、patch.js-createElm()
总结
1、组件是独立和可复用的代码组织单元。组件系统是vue核心特性之一,它使得开发者使用小型,独立和通常可复用的组件构建大型应用
2、组件化开发能大幅度提高应用开发效率,测试性,复用性等
3、组件使用按分类有:页面组件,业务组件,通用组件
4.vue的组件是基于配置的,我们通常编写的组件是组件配置而非组件,框架后续会生成与其构造函数,他们基于vueComponent。扩展与vue
5、vue中常见组件化技术有:属性prop 自定义事件。插槽等,他们主要用于组件通信,扩展等
6、合理的划分组件,有助于提升应用性能
7.组件内应该是高内聚,低耦合的
8、遵循单向数据流的原则
6、vue设计原则的理解
vue的官网上写了定义和特点: vue是一个渐进式的javscript框架 易用,高效,灵活
根据这个两个点去回答 渐进式javascript框架:
跟其他大型框架不同的是, vue被设计为可以自底向上逐层应用。vue的核心库只关注视图层,不仅易于上手,还便于与第三方库活既有的项目整合,另一方面,当现代的工具链以及各种支持类库结合使用的时候。vue也完全能够为复杂的单页面提供驱动 核心库就是一些声明是的渲染,组件系统 只关注视图层 可以作为一个库在其他项目中去用,也能作为一个大型的框架去搭建项目,这就是渐进式 学习过程也是渐进式的,只学习模板语法,基础功能也能开发,后期才学习工程化,
易用性:
vue提供数据响应式,声明式模板语法和基于配置的组件系统等核心特性,这些使我们只需要关注应用的核心业务即可,只要会写js。html和css就能轻松编写vue应用
灵活性:
渐进式框架最大的优点就是灵活性,如果应用足够小,我们可能仅仅需要vue的核心特性就能去完成功能了,随着应用规模的不断扩大,我们才可能追歼引入路由,状态管理,vue-cli等库和工具,不管是应用体积还是学习难度都是一个逐渐增加的平和曲线
高效性:
超快的虚拟DOM和diff算法使我们的应用有最佳的性能表现, 追求更高效的过程还在继续,vue3中引入proxy对数据响应式的改进以及编译器中对于静态内容的改进都会让vue更加高效
7、MVC MVP 和MVVM的理解
答题思路:
涉及的知识点比较多,很难说清楚,说透,因为mvc MVp这些模式我们前端程序员自己都没用过,当时恰恰反应了这些年全从无到有,从有到优的变化过程,沿着这个思路来回答
web1.0时代
在web1.0时代 并没有前端的概念。开发用过web应用多数采用ASP.NET、java PHP 项目通常有多个aspx/jsp/hph的单文件去组成,每个文件都有html css js或者java代码
为了让开发更加便捷,代码易于维护,前后端职责清晰,出现MVC 开发模式和框架。前端展示模板的形式出现的典型的框架就是Spring Structs Hibernate (SSH)
目标就是把数据,视图,业务逻辑控制分层,便于维护和读写,前端只完成后端中的view层 但是还是吧所有代码逻辑放在服务端,
存在问题:1、前端页面开发效率不高,2、前后端职责不清晰
web2.0时代
自从Gmail的出现 ajax技术开始出现。前后端职责就更加清晰了,因为前端可以通过ajax与后端进行整体的数据交互,因此,整体的架构图也变化成了:
前端只需要开发页面内容。数据由后台提供,而且项目能实现ajax可以使得页面实现部分刷新,减少了服务端负载和流量的消耗,很多渲染从服务端变成了客户端,前端也发展了一些库 jquery
存在问题: 缺乏可行的开发模式承载更复杂的业务需求,页面内容都糅杂在一起,一旦应用规模增加,就会导致难以维护,因此,前端的MVC也随之到来
前后端分离的架构演变:MVC MVP MVVM MVC 前端的MVC与后端类似,具备View,Controller和Model Model:负责应用数据的保存。与后端数据进行同步 Contoller:负责业务逻辑,根据用户行为对Model数据进行修改 View:负责视图展示。将model中的数据可视化出来 模型:
理论上是可行的,可是实际上并不方便,然后慢慢演变 (下面这个还是mvc) 这样的模式也可能带来一些问题: 1、数据流混乱 如图 view比较庞大,controller比较单纯,由于很多开发者会在view中写一些逻辑的代码 逐渐导致view中的内容会越来越大,而controller变的越来越单薄 前端的变化中 似乎少了mvp这种模式。是因为Angular早早的把MVVM模式代入前端 跳过了MVP
MVP MVP与mvc很接近 P指的是Persenter 理解为一个中间人,他负责view和model之间的数据流,防止view好emodel之间直接交流,
P负责和M还有V进行双向交互,view变成了被动视图,而且本身编的很小,分离了v和m,但是应用变的很大,导致P的体积增大,难以维护。
MVVM
mvvm核心是中间的vm层: ViewModel通过实现一套数据相应式机制自动响应Model中数据变化。同时ViewModel会实现一套更新侧率自动将数据变化转化为视图更新 通过时间监听响应View中用户交互修改Model中数据。 这样在ViewModel中就减少了大量DOM操作代码 MVVM在保持view和Model松耦合的同时,还减少了维护他们的关系的代码,使用用户专注于业务逻辑,兼顾开发率和可维护性
总结: 1、这三者都是框架模式,他们的设计目标都是为了解决Model和View的耦合问题
2、MVC模式出现较早主要应用在后端,如Spring MVC ASP.NET MVC等,有点是分层清晰,缺点是数据流混乱,灵活性带来的维护问题
3.MVP模式在MVC的进化形式,Presenter作为中间层负责MV通讯,解决了两者的耦合问题,但p层过去臃肿会导致维护问题
4、MVVM模式在前端领域有广泛应用,他不仅解决了MV耦合问题,还同时解决了维护两者射影关系的大量繁杂代码和DOM操作,也就是说不用去挨个改变DOM操作了,在提高开发效率,可读性同时还保持了优越的性能表现
8、你了解哪些vue的性能优化方法
主要讨论vue层面的优化
1、路由懒加载:
2、keep-alive缓存页面
3、使用v-show复用DOM
4、v-for遍历避免同时使用v-if
计算属性提前把数组进行过滤
5、长列表性能优化
如果列表纯粹是显示数据 不会有改变 数据就不需要响应式
使用freeze方法进行冻结,或者更改属性为false
如果是大数据列表,可以采用虚拟滚动,只渲染少部分区域内容
参考第三方组件
6、事件销毁
vue组件销毁时,会自动解绑他的全部指令及事件监听器,但仅限于组件本身的事件
7、图片懒加载
对于图片过多的页面 为了加速页面的加载速度,所以很多时候我们需要将页面内未出现在可视区域内的图片不做加载,等到滚动到可视区域之后再去加载
8、第三方插件按需导入
像element-ui这样的第三方组件库可以按需映入避免体积太大
使用bable的插件
9、无状态组件标记为函数式组件
展示型组件 ,这样的话就没有实例 标记functional
10.子组件分割
性能优化
1.webpack打包文件体积过大?(最终打包为一个js文件)
2.如何优化webpack构建的性能
3.移动端的性能优化
4.Vue的SPA 如何优化加载速度
5.移动端300ms延迟
6.页面的重构
所有的知识点都有详细的解答,我整理成了280页PDF《前端校招面试真题精编解析》。