前端面试题-vue相关
Vue⾯试题
框架部分我们会涉及⼀些⾼频且有⼀定探讨价值的⾯试题,我们不会涉及⼀些⾮常初级的在官⽅⽂档就能查看的纯记忆性质的⾯试题,⽐如:vue常⽤的修饰符?vue-cli ⼯程常⽤的 npm 命令有哪些?vue中 keep-alive 组件的作⽤?⾸先,上述类型的⾯试题在⽂档中可查,没有⽐官⽅⽂档更权威的答案了,其次这种问题没有太⼤价值,除了考察候选⼈的记忆⼒,最后,这种⾯试题只要⽤过vue的都知道,没有必要占⽤我们的篇幅.我们的问题并不多,但是难度可能会⾼⼀些,如果你真的搞懂了这些问题,在绝⼤多数情况下会有举⼀反三的效果,可以说基本能拿下Vue相关的所有重要知识点了.
Q1.你对MVVM的理解?MVVM是什么?
MVVM 模式,顾名思义即 Model-View-ViewModel 模式。它萌芽于2005年微软推出的基于 Windows 的⽤户界⾯框架WPF,前端最早的 MVVM 框架 knockout 在2010年发布。Model 层: 对应数据层的域模型,它主要做域模型的同步。通过 Ajax/fetch 等 API 完成客户端和服务端业务 Model 的同步。在层间关系⾥,它主要⽤于抽象出 ViewModel 中视图的 Model。View 层:作为视图模板存在,在 MVVM ⾥,整个 View 是⼀个动态模板。除了定义结构、布局外,它展示的是ViewModel 层的数据和状态。View 层不负责处理状态,View 层做的是 数据绑定的声明、 指令的声明、 事件绑定的声明。ViewModel 层:把 View 需要的层数据暴露,并对 View 层的 数据绑定声明、 指令声明、 事件绑定声明 负责,也就是处理 View 层的具体业务逻辑。ViewModel 底层会做好绑定属性的监听。当 ViewModel 中数据变化,View 层会得到更新;⽽当 View 中声明了数据的双向绑定(通常是表单元素),框架也会监听 View 层(表单)值的变化。⼀旦值变化,View 层绑定的 ViewModel 中的数据也会得到⾃动更新。
MVVM的优缺点?
优点:
1. 分离视图(View)和模型(Model),降低代码耦合,提⾼视图或者逻辑的重⽤性: ⽐如视图(View)可以独⽴于Model变化和修改,⼀个ViewModel可以绑定不同的"View"上,当View变化的时候Model不可以不变,当Model变化的时候View也可以不变。你可以把⼀些视图逻辑放在⼀个ViewModel⾥⾯,让很多view重⽤这段视图逻辑
2. 提⾼可测试性: ViewModel的存在可以帮助开发者更好地编写测试代码
3. ⾃动更新dom: 利⽤双向绑定,数据更新后视图⾃动更新,让开发者从繁琐的⼿动dom中解放
缺点:
1. Bug很难被调试: 因为使⽤双向绑定的模式,当你看到界⾯异常了,有可能是你View的代码有Bug,也可能是Model 的代码有问题。数据绑定使得⼀个位置的Bug被快速传递到别的位置,要定位原始出问题的地⽅就变得不那么容易了。另外,数据绑定的声明是指令式地写在View的模版当中的,这些内容是没办法去打断点debug的
2. ⼀个⼤的模块中model也会很⼤,虽然使⽤⽅便了也很容易保证了数据的⼀致性,当时⻓期持有,不释放内存就造成了花费更多的内存
3. 对于⼤型的图形应⽤程序,视图状态较多,ViewModel的构建和维护的成本都会⽐较⾼
Q2.你对Vue⽣命周期的理解?
⽣命周期是什么Vue 实例有⼀个完整的⽣命周期,也就是从开始创建、初始化数据、编译模版、挂载Dom -> 渲染、更新 -> 渲染、卸载等⼀系列过程,我们称这是Vue的⽣命周期。
各个⽣命周期的作⽤
⽣命周期示意图
Q3.异步请求适合在哪个⽣命周期调⽤?
官⽅实例的异步请求是在mounted⽣命周期中调⽤的,⽽实际上也可以在created⽣命周期中调⽤。
Q4.Vue组件如何通信?
Vue组件通信的⽅法如下:props/$emit+v-on: 通过props将数据⾃上⽽下传递,⽽通过$emit和v-on来向上传递信息。EventBus: 通过EventBus进⾏信息的发布与订阅vuex: 是全局数据管理库,可以通过vuex管理全局的数据流$attrs/$listeners: Vue2.4中加⼊的$attrs/$listeners可以进⾏跨级的组件通信
provide/inject:以允许⼀个祖先组件向其所有⼦孙后代注⼊⼀个依赖,不论组件层次有多深,并在起上下游关系成⽴的时间⾥始终⽣效,这成为了跨组件通信的基础还有⼀些⽤solt插槽或者ref实例进⾏通信的,使⽤场景过于有限就不赘述了。
Q5.computed和watch有什么区别?
computed:
1. computed 是计算属性,也就是计算值,它更多⽤于计算值的场景
2. computed 具有缓存性,computed的值在getter执⾏后是会缓存的,只有在它依赖的属性值改变之后,下⼀次获取 computed的值时才会重新调⽤对应的getter来计算
3. computed 适⽤于计算⽐较消耗性能的计算场景
watch:
1. 更多的是「观察」的作⽤,类似于某些数据的监听回调,⽤于观察 props $emit 或者本组件的值,当数据变化时来执 ⾏回调进⾏后续操作
2. ⽆缓存性,⻚⾯重新渲染时值不变化也会执⾏
⼩结:
1. 当我们要进⾏数值计算,⽽且依赖于其他数据,那么把这个数据设计为computed
2. 如果你需要在某个数据变化时做⼀些事情,使⽤watch来观察这个数据变化
Q6.Vue是如何实现双向绑定的?
利⽤Object.defineProperty 劫持对象的访问器,在属性值发⽣变化时我们可以获取变化,然后根据变化进⾏后续响应,在vue3.0中通过Proxy代理对象进⾏类似的操作。
Q7.Proxy与Object.defineProperty的优劣对⽐?
Proxy的优势如下: Proxy可以直接监听对象⽽⾮属性 Proxy可以直接监听数组的变化 Proxy有多达13种拦截⽅法,不限于apply、ownKeys、deleteProperty、has等等是 Object.defineProperty 不具备的 Proxy返回的是⼀个新对象,我们可以只操作新的对象达到⽬的,⽽ Object.defineProperty 只能遍历对象属性直接修改Proxy作为新标准将受到浏览器⼚商重点持续的性能优化,也就是传说中的新标准的性能红利 Object.defineProperty的优势如下: 兼容性好,⽀持IE9
Q8.你是如何理解Vue的响应式系统的?
响应式系统简述:任何⼀个 Vue Component 都有⼀个与之对应的 Watcher 实例。Vue 的 data 上的属性会被添加 getter 和 setter 属性。当 Vue Component render 函数被执⾏的时候, data 上会被 触碰(touch), 即被读, getter ⽅法会被调⽤, 此时 Vue 会去记录此 Vue component 所依赖的所有 data。(这⼀过程被称为依赖收集)data 被改动时(主要是⽤户操作), 即被写, setter ⽅法会被调⽤, 此时 Vue 会去通知所有依赖于此data 的组件去调⽤他们的 render 函数进⾏更新。
Q9.既然Vue通过数据劫持可以精准探测数据变化,为什么还需要虚拟DOM进⾏diff检测差异?
考点: Vue的变化侦测原理
前置知识: 依赖收集、虚拟DOM、响应式系统 现代前端框架有两种⽅式侦测变化,⼀种是pull⼀种是push pull: 其代表为React,我们可以回忆⼀下React是如何侦测到变化的,我们通常会⽤ setState API显式更新,然后React会进 ⾏⼀层层的Virtual Dom Diff操作找出差异,然后Patch到DOM上,React从⼀开始就不知道到底是哪发⽣了变化,只是知道 「有变化了」,然后再进⾏⽐较暴⼒的Diff操作查找「哪发⽣变化了」,另外⼀个代表就是Angular的脏检查操作。 push: Vue的响应式系统则是push的代表,当Vue程序初始化的时候就会对数据data进⾏依赖的收集,⼀但数据发⽣变化,响 应式系统就会⽴刻得知,因此Vue是⼀开始就知道是「在哪发⽣变化了」,但是这⼜会产⽣⼀个问题,如果你熟悉Vue的响 应式系统就知道,通常⼀个绑定⼀个数据就需要⼀个Watcher,⼀但我们的绑定细粒度过⾼就会产⽣⼤量的Watcher,这会 带来内存以及依赖追踪的开销,⽽细粒度过低会⽆法精准侦测变化,因此Vue的设计是选择中等细粒度的⽅案,在组件级别 进⾏push侦测的⽅式,也就是那套响应式系统,通常我们会第⼀时间侦测到发⽣变化的组件,然后在组件内部进⾏Virtual Dom Diff获取更加具体的差异,⽽Virtual Dom Diff则是pull操作,Vue是push+pull结合的⽅式进⾏变化侦测的.
Q10.Vue为什么没有类似于React中shouldComponentUpdate的⽣命周期?
考点: Vue的变化侦测原理前置知识:
依赖收集、虚拟DOM、响应式系统根本原因是Vue与React的变化侦测⽅式有所不同React是pull的⽅式侦测变化,当React知道发⽣变化后,会使⽤Virtual Dom Diff进⾏差异检测,但是很多组件实际上是肯定不会发⽣变化的,这个时候需要⽤shouldComponentUpdate进⾏⼿动操作来减少diff,从⽽提⾼程序整体的性能.Vue是pull+push的⽅式侦测变化的,在⼀开始就知道那个组件发⽣了变化,因此在push的阶段并不需要⼿动控制diff,⽽组件内部采⽤的diff⽅式实际上是可以引⼊类似于shouldComponentUpdate相关⽣命周期的,但是通常合理⼤⼩的组件不会有过量的diff,⼿动优化的价值有限,因此⽬前Vue并没有考虑引⼊shouldComponentUpdate这种⼿动优化的⽣命周期.
Q11.Vue中的key到底有什么⽤?
key是为Vue中的vnode标记的唯⼀id,通过这个key,我们的diff操作可以更准确、更快速diff算法的过程中,先会进⾏新旧节点的⾸尾交叉对⽐,当⽆法匹配的时候会⽤新节点的 key 与旧节点进⾏⽐对,然后超出差异.
diff程可以概括为:oldCh和newCh各有两个头尾的变量StartIdx和EndIdx,它们的2个变量相互⽐较,⼀共有4种⽐较⽅式。如果4种⽐较都没匹配,如果设置了key,就会⽤key进⾏⽐较,在⽐较的过程中,变量会往中间靠,⼀旦StartIdx>EndIdx表明oldCh和newCh⾄少有⼀个已经遍历完了,就会结束⽐较,这四种⽐较⽅式就是⾸、尾、旧尾新头、旧头新尾.
准确: 如果不加 key ,那么vue会选择复⽤节点(Vue的就地更新策略),导致之前节点的状态被保留下来,会产⽣⼀系列的bug.
快速: key的唯⼀性可以被Map数据结构充分利⽤,相⽐于遍历查找的时间复杂度O(n),Map的时间复杂度仅仅为O(1).
Q12.常见的前端框架有哪些
a: EasyUI
EasyUI是一种基于jQuery的用户界面插件集合。easyui为创建现代化,互动,JavaScript 应用程序,提供必要的功能。使用 easyui 你不需要写很多代码,你只需要通过编写一些简单 HTML 标记,就可以定义用户界面。
优势:开源免费,页面也还说的过去。
b: MiniUI
基于 jquery 的框架,开发的界面功能都很丰富。jQuery MiniUI - 快速开发 WebUI。它能缩短开发时间,减少代码量,使开发者更专注于业务和服务端,轻松实现界面开发,带来绝佳的用户体验。使用 MiniUI,开发者可以快速创建Ajax无刷新、B/S 快速录入数据、CRUD、 Master-Detail、菜单工具栏、弹出面板、布局导航、数据验证、 分页表格、树、树形表格等典型 WEB 应用系统界面。
缺点:收费,没有源码,基于这个开发如果想对功能做扩展就 需要找他们的团队进行升级!
c: LayUI
是一款采用自身模块规范编写的前端 UI 框架,遵循原生 HTML/CSS/JS 的书写与组织形式,门槛极低,拿来即用。其外在极简,却又不失饱满的内在,体积轻盈,组件丰盈,从核心代码到 API 的每一处细节都经过精心雕琢,非常适合界面的快速开发。layui 首个版本发布于 2016 年金秋,她区别于那些基于 MVVM 底层的 UI 框架,却并非逆道而行,而是信奉返璞归真之道。准确地说,她更多是为后端程序员量身定做,你无需涉足各种前端工具的复杂配置,只需面对浏览器本身,让一切你所需要的元素与交互,从这里信手拈来。
d: jQueryUI
jQuery UI 是一套 jQuery 的页面 UI 插件,包含很多种常用的页面空间,例如 Tabs(如本站首页右上角部分)、拉帘效果(本站首页左上角)、对话框、拖放效果、日期选择、颜色选择、数据排序、窗体大小调整等等非常多的内容。
技术亮点:
l 简单易用:继承 jQuery 简易使用特性,提供高度抽象接口,短期改善网站易用性。
l 开源免费:采用 MIT & GPL 双协议授权,轻松满足自由产品至企业产品各种授权需求。
l 广泛兼容:兼容主流桌面浏览器。包括 IE 6+、Firefox 2+、Safari 3+、Opera 9+、Chrome 1+。
l 轻便快捷:组件间相对独立,可按需加载,避免浪费带宽拖慢网页打开速度。
l 标准先进:支持 WAI-ARIA,通过标准 XHTML 代码提供渐进增强,保证低端环境可访问性。
l 美观多变:提供近20种预设主题,并可自定义多达60项可配置样式规则,提供24种背景纹理选择。
e:Vue.js
Vue.js (读音 /vjuː/,类似于 view)是一套构建用户界面的渐进式框架。与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计。Vue 的核心库只关注视图层,它不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与单文件组件和 Vue 生态系统支持的库结合使用时,Vue 也完全能够为复杂的单页应用程序提供驱动。
f:AngularJS
AngularJS 是 google 开发者设计的一个前端开发框架,它是由是由 JavaScript 编写的一个 JS 框架。通常它是 用来在静态网页构建动态应用不足而设计的。
标签:
相关文章
-
无相关信息