vue⾯试题+答案,2021前端⾯试
vue⾯试题+答案,2021前端⾯试
vue视频教程系列:
Vue3+ElementPlus+Koa2 全栈开发后台系统
试看:
完整课程:
Vue3.0⾼阶实战:开发⾼质量⾳乐Web app
试看:
完整课程:
VUE全⾯教学+VUE开源项⽬超级实战:
试看:
完整课程:
最新Vue.JS教程快速⼊门到项⽬实战(Vue3/VueJS技术详解)
试看:
完整课程:
最新最全前端毕设项⽬(⼩程序+VUE+Noed+React+uni app+Express+Mongodb)
试看:
完整课程:
MVC 和 MVVM 区别
MVC
MVC 全名是 Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,⼀种软件设计典范Model(模型):是应⽤程序中⽤于处理应⽤程序数据逻辑的部分。通常模型对象负责在数据库中存取数据
View(视图):是应⽤程序中处理数据显⽰的部分。通常视图是依据模型数据创建的
Controller(控制器):是应⽤程序中处理⽤户交互的部分。通常控制器负责从视图读取数据,控制⽤户输⼊,并向模型发送数据MVC 的思想:⼀句话描述就是 Controller 负责将 Model 的数据⽤ View 显⽰出来,换句话说就是在 Controller ⾥⾯把 Model 的数据赋值给View。
MVVM
MVVM 新增了 VM 类
ViewModel 层:做了两件事达到了数据的双向绑定⼀是将【模型】转化成【视图】,即将后端传递的数据转化成所看到的页⾯。实现的⽅式是:数据绑定。⼆是将【视图】转化成【模型】,即将所看到的页⾯转化成后端的数据。实现的⽅式是:DOM 事件监听。MVVM 与 MVC 最⼤的区别就是:它实现了 View 和 Model 的⾃动同步,也就是当 Model 的属性改变时,我们不⽤再⾃⼰⼿动操作 Dom 元素,来改变 View 的显⽰,⽽是改变属性后该属性对应 View 层显⽰会⾃动改变(对应Vue数据驱动的思想)
整体看来,MVVM ⽐ MVC 精简很多,不仅简化了业务与界⾯的依赖,还解决了数据频繁更新的问题,不⽤再⽤选择器操作 DOM 元素。因为在 MVVM 中,View 不知道 Model 的存在,Model 和 ViewModel 也观察不到 View,这种低耦合模式提⾼代码的可重⽤性
注意:Vue 并没有完全遵循 MVVM 的思想这⼀点官⽹⾃⼰也有说明
那么问题来了为什么官⽅要说 Vue 没有完全遵循 MVVM 思想呢?
严格的 MVVM 要求 View 不能和 Model 直接通信,⽽ Vue 提供了$refs 这个属性,让 Model 可以直接操作 View,违反了
这⼀规定,所以说 Vue 没有完全遵循 MVVM。
vue是如何实现响应式数据的呢?(响应式数据原理)
Vue2: Object.defineProperty重新定义 data中所有的属性, Object.defineProperty可以使数据的获取与设置增加⼀个拦截的功能,拦截属性的获取,进⾏依赖收集。拦截属性的更新操作,进⾏通知。
具体的过程:⾸先Vue使⽤initData初始化⽤户传⼊的参数,然后使⽤new Observer对数据进⾏观测,如果数据是⼀个对象类型就会调⽤this.walk(value)对对象进⾏处理,内部使⽤defineeReactive循环对象属性定义响应式变化,核⼼就是使⽤ Object.defineProperty重新定义数据。
那vue中是如何检测数组变化的呢?
数组就是使⽤ object.defineProperty重新定义数组的每⼀项,那能引起数组变化的⽅法我们都是知道的, pop、 push、 shift、 unshift、 splice、sort、 reverse这七种,只要这些⽅法执⾏改了数组内容,我就更新内容就好了,是不是很好理解。
1. 是⽤来函数劫持的⽅式,重写了数组⽅法,具体呢就是更改了数组的原型,更改成⾃⼰的,⽤户调数组的⼀些⽅法的时候,⾛的就是
⾃⼰的⽅法,然后通知视图去更新。
2. 数组⾥每⼀项可能是对象,那么我就是会对数组的每⼀项进⾏观测,(且只有数组⾥的对象才能进⾏观测,观测过的也不会进⾏观
测)
vue3:改⽤ proxy,可直接监听对象数组的变化。
vue的优点
轻量级框架:只关注视图层,是⼀个构建数据的视图集合,⼤⼩只有⼏⼗kb;
简单易学:国⼈开发,中⽂⽂档,不存在语⾔障碍,易于理解和学习;
双向数据绑定:保留了angular的特点,在数据操作⽅⾯更为简单;
组件化:保留了react的优点,实现了html的封装和重⽤,在构建单页⾯应⽤⽅⾯有着独特的优势;
视图,数据,结构分离:使数据的更改更为简单,不需要进⾏逻辑代码的修改,只需要操作数据就能完成相关操作;
虚拟DOM:dom操作是⾮常耗费性能的,不再使⽤原⽣的dom操作节点,极⼤解放dom操作,但具体操作的还是dom不过是换了另⼀种⽅式;
运⾏速度更快:相⽐较与react⽽⾔,同样是操作虚拟dom,就性能⽽⾔,vue存在很⼤的优势。
为什么vue组件中data必须是⼀个函数?
对象为引⽤类型,当复⽤组件时,由于数据对象都指向同⼀个data对象,当在⼀个组件中修改data时,其他重⽤的组件中的data会同时被修改;⽽使⽤返回对象的函数,由于每次返回的都是⼀个新对象(Object的实例),引⽤地址不同,则不会出现这个问题。
v-if 和 v-show 的区别
v-if 在编译过程中会被转化成三元表达式,条件不满⾜时不渲染此节点。
v-show 会被编译成指令,条件不满⾜时控制样式将对应节点隐藏(display:none)
为什么Vue采⽤异步渲染呢?
Vue是组件级更新,如果不采⽤异步更新,那么每次更新数据都会对当前组件进⾏重新渲染,所以为了性能, Vue会在本轮数据更新后,在异步更新视图。核⼼思想 nextTick。
⽗⼦组件⽣命周期调⽤顺序(简单)
渲染顺序:先⽗后⼦,完成顺序:先⼦后⽗
更新顺序:⽗更新导致⼦更新,⼦更新完成后⽗
销毁顺序:先⽗后⼦,完成顺序:先⼦后⽗
⽤VNode来描述⼀个DOM结构
虚拟节点就是⽤⼀个对象来描述⼀个真实的DOM元素。⾸先将 template(真实DOM)先转成 ast, ast
树通过 codegen⽣成 render函数,render函数⾥的 _c⽅法将它转为虚拟dom
diff算法
时间复杂度:个树的完全 diff算法是⼀个时间复杂度为 O(n*3),vue进⾏优化转化成 O(n)。
理解:
最⼩量更新, key很重要。这个可以是这个节点的唯⼀标识,告诉 diff算法,在更改前后它们是同⼀个DOM节点扩展 v-for为什么要有 key,没有 key会暴⼒复⽤,举例⼦的话随便说⼀个⽐如移动节点或者增加节点(修改DOM),加 key只会移动减少操作DOM。
只有是同⼀个虚拟节点才会进⾏精细化⽐较,否则就是暴⼒删除旧的,插⼊新的。
只进⾏同层⽐较,不会进⾏跨层⽐较。
diff算法的优化策略:四种命中查,四个指针
1. 旧前与新前(先⽐开头,后插⼊和删除节点的这种情况)
2. 旧后与新后(⽐结尾,前插⼊或删除的情况)
3. 旧前与新后(头与尾⽐,此种发⽣了,涉及移动节点,那么新前指向的节点,移动到旧后之后)
4. 旧后与新前(尾与头⽐,此种发⽣了,涉及移动节点,那么新前指向的节点,移动到旧前之前)
v-for 为什么要加 key
如果不使⽤ key,Vue 会使⽤⼀种最⼤限度减少动态元素并且尽可能的尝试就地修改/复⽤相同类型元素的算法。key 是为 Vue 中 vnode 的唯⼀标记,通过这个 key,我们的 diff 操作可以更准确、更快速
更准确:因为带 key 就不是就地复⽤了,在 sameNode 函数 a.key === b.key 对⽐中可以避免就地复⽤的情况。所以会更加准确。
更快速:利⽤ key 的唯⼀性⽣成 map 对象来获取对应节点,⽐遍历⽅式更快
vue-router 路由钩⼦函数是什么执⾏顺序是什么
路由钩⼦的执⾏流程, 钩⼦函数种类有:全局守卫、路由守卫、组件守卫
完整的导航解析流程:
1. 导航被触发。
2. 在失活的组件⾥调⽤ beforeRouteLeave 守卫。
3. 调⽤全局的 beforeEach 守卫。
4. 在重⽤的组件⾥调⽤ beforeRouteUpdate 守卫 (2.2+)。
5. 在路由配置⾥调⽤ beforeEnter。
6. 解析异步路由组件。
7. 在被激活的组件⾥调⽤ beforeRouteEnter。
8. 调⽤全局的 beforeResolve 守卫 (2.5+)。
9. 导航被确认。
10. 调⽤全局的 afterEach 钩⼦。
11. 触发 DOM 更新。
12. 调⽤ beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传⼊。
谈⼀下对 vuex 的个⼈理解
vuex 是专门为 vue 提供的全局状态管理系统,⽤于多个组件中数据共享、数据缓存等。(⽆法持久化、内部核⼼原理是通过创造⼀个全局实例 new Vue)
主要包括以下⼏个模块:
State:定义了应⽤状态的数据结构,可以在这⾥设置默认的初始状态。
Getter:允许组件从 Store 中获取数据,mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性。
Mutation:是唯⼀更改 store 中状态的⽅法,且必须是同步函数。
Action:⽤于提交 mutation,⽽不是直接变更状态,可以包含任意异步操作。
Module:允许将单⼀的 Store 拆分为多个 store 且同时保存在单⼀的状态树中。
keep-alive 使⽤场景和原理
keep-alive 是 Vue 内置的⼀个组件,可以实现组件缓存,当组件切换时不会对当前组件进⾏卸载。
常⽤的两个属性 include/exclude,允许组件有条件的进⾏缓存。
两个⽣命周期 activated/deactivated,⽤来得知当前组件是否处于活跃状态。
keep-alive 的中还运⽤了 LRU(最近最少使⽤) 算法,选择最近最久未使⽤的组件予以淘汰。
官⽅解释:d 使⽤基础 Vue 构造器,创建⼀个“⼦类”。参数是⼀个包含组件选项的对象。
其实就是⼀个⼦类构造器是 Vue 组件的核⼼ api 实现思路就是使⽤原型继承的⽅法返回了 Vue 的⼦类并且利⽤ mergeOptions 把传⼊组件
的 options 和⽗类的 options 进⾏了合并
Vue组件如何通信?
Vue组件通信的⽅法如下:
props/$emit+v-on: 通过props将数据⾃上⽽下传递,⽽通过$emit和v-on来向上传递信息。
EventBus: 通过EventBus进⾏信息的发布与订阅
vuex: 是全局数据管理库,可以通过vuex管理全局的数据流
$attrs/$listeners: Vue2.4中加⼊的$attrs/$listeners可以进⾏跨级的组件通信
provide/inject:以允许⼀个祖先组件向其所有⼦孙后代注⼊⼀个依赖,不论组件层次有多深,并在起上下游关系成⽴的时间⾥始终⽣效,这成为了跨组件通信的基础
还有⼀些⽤solt插槽或者ref实例进⾏通信的,使⽤场景过于有限就不赘述了。
computed和watch有什么区别?
computed:
1. computed是计算属性,也就是计算值,它更多⽤于计算值的场景
2. computed具有缓存性,computed的值在getter执⾏后是会缓存的,只有在它依赖的属性值改变之后,下⼀次获取computed的值时才会重
新调⽤对应的getter来计算
3. computed适⽤于计算⽐较消耗性能的计算场景
watch:
1. 更多的是「观察」的作⽤,类似于某些数据的监听回调,⽤于观察props$emit或者本组件的值,当数据变化时来执⾏回调进⾏后续操作
2. ⽆缓存性,页⾯重新渲染时值不变化也会执⾏
⼩结:
1. 当我们要进⾏数值计算,⽽且依赖于其他数据,那么把这个数据设计为computed
2. 如果你需要在某个数据变化时做⼀些事情,使⽤watch来观察这个数据变化
虚拟DOM的优劣如何?
优点:
保证性能下限: 虚拟DOM可以经过diff出最⼩差异,然后批量进⾏patch,这种操作虽然⽐不上⼿动优化,但是⽐起粗暴的DOM操作性能要好很多,因此虚拟DOM可以保证性能下限
⽆需⼿动操作DOM: 虚拟DOM的diff和patch都是在⼀次更新中⾃动进⾏的,我们⽆需⼿动操作DOM,极
⼤提⾼开发效率
跨平台: 虚拟DOM本质上是JavaScript对象,⽽DOM与平台强相关,相⽐之下虚拟DOM可以进⾏更⽅便地跨平台操作,例如服务器渲染、移动端开发等等
缺点:
⽆法进⾏极致优化: 在⼀些性能要求极⾼的应⽤中虚拟DOM⽆法进⾏针对性的极致优化,⽐如VScode采⽤直接⼿动操作DOM的⽅式进⾏极端的性能优化
虚拟DOM实现原理?
虚拟DOM本质上是JavaScript对象,是对真实DOM的抽象
状态变更时,记录新树和旧树的差异
最后把差异更新到真正的dom中
Vue 初始化页⾯闪动问题如何解决?
出现该问题是因为在 Vue 代码尚未被解析之前,尚⽆法控制页⾯中 DOM 的显⽰,所以会看见模板字符
串等代码。前端面试性能优化
解决⽅案是,在 css 代码中添加 v-cloak 规则,同时在待编译的标签上添加 v-cloak 属性:
[v-cloak] { display: none; }
<div v-cloak>
{{ message }}
</div>
Vue-router 路由有哪些模式?
⼀般有两种模式:
(1)hash 模式:后⾯的 hash 值的变化,浏览器既不会向服务器发出请求,浏览器也不会刷新,每次 hash 值的变化会触发 hashchange 事件。
(2)history 模式:利⽤了 HTML5 中新增的 pushState() 和 replaceState() ⽅法。这两个⽅法应⽤于浏览器的历史记录栈,在当前已有的back、forward、go 的基础之上,它们提供了对历史记录进⾏修改的
功能。只是当它们执⾏修改时,虽然改变了当前的 URL,但浏览器不会⽴即向后端发送请求。
$nextTick 是什么?
Vue 实现响应式并不是在数据发⽣后⽴即更新 DOM,使⽤vm.$nextTick是在下次 DOM 更新循环结束之后⽴即执⾏延迟回调。在修改数据之后使⽤,则可以在回调中获取更新后的 DOM。
Vue 中 computed 和 watch 有什么区别?
计算属性 computed:
(1)⽀持缓存,只有依赖数据发⽣变化时,才会重新进⾏计算函数;
(2)计算属性内不⽀持异步操作;
(3)计算属性的函数中都有⼀个 get(默认具有,获取计算属性)和 set(⼿动添加,设置计算属性)⽅法;
(4)计算属性是⾃动监听依赖值的变化,从⽽动态返回内容。
侦听属性 watch:
(1)不⽀持缓存,只要数据发⽣变化,就会执⾏侦听函数;
(2)侦听属性内⽀持异步操作;
(3)侦听属性的值可以是⼀个对象,接收 handler 回调,deep,immediate 三个属性;
(3)监听是⼀个过程,在监听的值变化时,可以触发⼀个回调,并做⼀些其他事情。
action 与 mutation 的区别
mutation是同步更新, $watch严格模式下会报错
action是异步操作,可以获取数据后调⽤ mutation提交最终数据
谈谈对keep-alive的了解
keep-alive可以实现组件的缓存,当组件切换时不会对当前组件进⾏卸载。常⽤的2个属性 include/exclude,2个⽣命周期 activated, deactivated
Vue 模板编译原理
Vue 的编译过程就是将 template 转化为 render 函数的过程分为以下三步
第⼀步是将模板字符串转换成 element ASTs(解析器)
第⼆步是对 AST 进⾏静态节点标记,主要⽤来做虚拟DOM的渲染优化(优化器)
第三步是使⽤ element ASTs ⽣成 render 函数代码字符串(代码⽣成器)
Vue 修饰符有哪些
事件修饰符
.stop 阻⽌事件继续传播
.prevent 阻⽌标签默认⾏为
.capture 使⽤事件捕获模式,即元素⾃⾝触发的事件先在此处处理,然后才交由内部元素进⾏处理
.self 只当在 event.target 是当前元素⾃⾝时触发处理函数
.once 事件将只会触发⼀次
.passive 告诉浏览器你不想阻⽌事件的默认⾏为
v-model 的修饰符
.
lazy 通过这个修饰符,转变为在 change 事件再同步
.number ⾃动将⽤户的输⼊值转化为数值类型
.trim ⾃动过滤⽤户输⼊的⾸尾空格
键盘事件的修饰符
.enter
.tab
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.
left
.right
系统修饰键
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论