VUE面试题整理1.0

VUE面试题:

    • 1.VUE的生命周期
    • 2.Vue2.x 双向绑定原理
    • 3.vue组件传参,调用方法的几种方式
    • 4.MVVM的理解?MVVM是什么?
    • 5.MVVM的优缺点?
    • 6.Vue是如何实现双向绑定的?
    • 7.你是如何理解Vue的响应式系统的?
    • 8.虚拟DOM的优劣势如何?
    • 9.虚拟DOM实现原理?
    • 10.axios是什么
    • 11.vue 的 nextTick 方法的实现原理
    • 12.v-if和v-for一起使用的弊端及解决办法
    • 13.vuex是什么?怎么使用?哪种功能场景使用它?
    • 14.< keep-alive>< /keep-alive>的作用是什么,如何使用?
    • 15.你都做过哪些Vue的性能优化?
    • 16.hash路由和history路由实现原理说一下
    • 17.vue.cli中怎样使用自定义的组件?有遇到过哪些问题吗?
    • 18.vuex的核心概念
    • 19. $ route和$ router的区别
    • 20.vue-router实现路由懒加载(动态加载路由)

VUE面试题整理1.0_第1张图片

1.VUE的生命周期

1.1.创建前/创建后

beforeCreated Vue的实例的挂载元素**$el** 和数据对象data都为undefined均未初始化
created 实例已经创建完成之后被调用。实例已完成以下的配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调。挂载阶段还没开始,$el 属性目前不可见

1.2. 载入前/载入后

beforeMount 在挂载开始之前被调用:相关的 render 函数(模板)首次被调用。
Mounted el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。

1.3.更新前/更新后

beforeUpdate 数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前,可以在这个钩子中进一步地更改状态,不会触发附加的重渲染过程。当更改Vue的任何数据,都会触发该函数
updated 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。当这个钩子被调用时,组件 DOM 已经更新,数据更新就会触发

1.4.销毁前/销毁后

beforeDestroy 实例销毁之前调用。在这一步,实例仍然完全可用。
destroyed Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。 该钩子在服务器端渲染期间不被调用。

2.Vue2.x 双向绑定原理

通过 数据劫持、结合、 发布者-订阅者 来实现双向绑定;数据劫持通过Object.defineProperty()方法的getset方法来重新定义,set是设置属性值触发的函数,get是读取属性值触发的函数;

底层实现逻辑:

1、监听器observer,object.defineProperty 的set方法监听所有属性,有变动通知订阅者,在这里还需要创建一个消息订阅器Dep来收集订阅者
2、订阅者watcher,接收变化通知执行相应函数,更新view
3、解析器compile,扫描解析每一个节点的指令,初始化订阅器

3.vue组件传参,调用方法的几种方式

props、$refs、 $emit、eventBus、provide 和 inject

props/ emit +v-on: 通过props将数据自上而下传递,通过$emit和v-on来向上传递信息。

EventBus: 通过EventBus进行信息的发布与订阅

vuex: 是全局数据管理库,可以通过vuex管理全局的数据流

attrs/listeners: Vue2.4中加入的attrs/listeners可以进行跨级的组件通信

provide/inject:以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效,这成为了跨组件通信的基础

4.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 中的数据也会得到自动更新。

5.MVVM的优缺点?

优点:
分离视图(View)和模型(Model),降低代码耦合,提高视图或者逻辑的重用性:
比如视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定不同的"View"上,当View变化的时候Model不可以不变,当Model变化的时候View也可以不变。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑
提高可测试性:
ViewModel的存在可以帮助开发者更好地编写测试代码
自动更新dom: 利用双向绑定,数据更新后视图自动更新,让开发者从繁琐的手动dom中解放

缺点:
Bug很难被调试:
因为使用双向绑定的模式,当你看到界面异常了,有可能是你View的代码有Bug,也可能是Model的代码有问题。数据绑定使得一个位置的Bug被快速传递到别的位置,要定位原始出问题的地方就变得不那么容易了。另外,数据绑定的声明是指令式地写在View的模版当中的,这些内容是没办法去打断点debug的
一个大的模块中model也会很大,虽然使用方便了也很容易保证了数据的一致性,当时长期持有,不释放内存就造成了花费更多的内存
对于大型的图形应用程序,视图状态较多,ViewModel的构建和维护的成本都会比较高

6.Vue是如何实现双向绑定的?

利用Object.defineProperty劫持对象的访问器,在属性值发生变化时我们可以获取变化,然后根据变化进行后续响应

7.你是如何理解Vue的响应式系统的?

响应式系统简述:
任何一个 Vue Component 都有一个与之对应的 Watcher 实例。

Vue 的 data 上的属性会被添加 gettersetter 属性。

Vue Component render 函数被执行的时候, data 上会被 触碰(touch), 即被读, getter 方法会被调用, 此时 Vue 会去记录此 Vue component 所依赖的所有 data。(这一过程被称为依赖收集)

data 被改动时(主要是用户操作), 即被写, setter 方法会被调用, 此时 Vue 会去通知所有依赖于此 data 的组件去调用他们的 render 函数进行更新。

8.虚拟DOM的优劣势如何?

优点:
保证性能下限:
虚拟DOM可以经过diff找出最小差异,然后批量进行patch,这种操作虽然比不上手动优化,但是比起粗暴的DOM操作性能要好很多,因此虚拟DOM可以保证性能下限

无需手动操作DOM:
虚拟DOM的diff和patch都是在一次更新中自动进行的,我们无需手动操作DOM,极大提高开发效率

跨平台:
虚拟DOM本质上是JavaScript对象,而DOM与平台强相关,相比之下虚拟DOM可以进行更方便地跨平台操作,例如服务器渲染、移动端开发等等

缺点:
无法进行极致优化:
在一些性能要求极高的应用中虚拟DOM无法进行针对性的极致优化,比如VScode采用直接手动操作DOM的方式进行极端的性能优化

9.虚拟DOM实现原理?

虚拟DOM本质上是JavaScript对象,是对真实DOM的抽象
状态变更时,记录新树和旧树的差异
最后把差异更新到真正的dom中

10.axios是什么

易用、简洁且高效的http库, 支持node端和浏览器端,支持Promise,支持拦截器等高级配置。

11.vue 的 nextTick 方法的实现原理

1.vue 用异步队列的方式来控制 DOM 更新和 nextTick 回调先后执行
2.microtask 因为其高优先级特性,能确保队列中的微任务在一次事件循环前被执行完毕

12.v-if和v-for一起使用的弊端及解决办法

由于v-for的优先级比v-if高,所以导致每循环一次就会去v-if一次,而v-if是通过创建和销毁dom元素来控制元素的显示与隐藏,所以就会不停的去创建和销毁元素,造成页面卡顿性能下降

解决办法:

1.在v-for的外层或内层包裹一个元素来使用v-if
2.用computed处理

13.vuex是什么?怎么使用?哪种功能场景使用它?

vue框架中状态管理。在main.js引入store,注入。新建了一个目录store,…… export 。
场景有:单页应用中,组件之间的状态。登录状态、加入购物车

14.< keep-alive>< /keep-alive>的作用是什么,如何使用?

包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染;
使用:简单页面时
缓存: < keep-alive include=”组件名”>< /keep-alive>
不缓存: < keep-alive exclude=”组件名”>< /keep-alive>

15.你都做过哪些Vue的性能优化?

编码阶段

1.尽量减少data中的数据,data中的数据都会增加getter和setter,会收集对应的2.watcher
3.v-if和v-for不能连用
4.如果需要使用v-for给每项元素绑定事件时使用事件代理
5.SPA 页面采用keep-alive缓存组件
6.在更多的情况下,使用v-if替代v-show
7.key保证唯一
8.使用路由懒加载、异步组件
9.防抖、节流
10.第三方模块按需导入
11.长列表滚动到可视区域动态加载
12.图片懒加载

SEO优化

1.预渲染
2.服务端渲染SSR

打包优化

1.压缩代码
2.Tree Shaking/Scope Hoisting
3.使用cdn加载第三方模块
4.多线程打包happypack
5.splitChunks抽离公共文件
6.sourceMap优化

用户体验

1.骨架屏
2.PWA

还可以使用缓存(客户端缓存、服务端缓存)优化、服务端开启gzip压缩等。

16.hash路由和history路由实现原理说一下

location.hash的值实际就是URL中#后面的东西。

history实际采用了HTML5中提供的API来实现,主要有history.pushState()history.replaceState()

17.vue.cli中怎样使用自定义的组件?有遇到过哪些问题吗?

第一步:在components目录新建你的组件文件(indexPage.vue),script一定要export default {}
第二步:在需要用的页面(组件)中导入:import indexPage from ‘@/components/indexPage.vue’
第三步:注入到vue的子组件的components属性上面,components:{indexPage}
第四步:在template视图view中使用,
例如有indexPage命名,使用的时候则index-page

18.vuex的核心概念

1.state => 基本数据
2.getters => 从基本数据派生的数据
3.mutations => 修改数据,同步
4.actions => 修改数据,异步 (Action 提交的是 mutation,而不是直接变更状态)
5.modules => 模块化Vuex

19. $ route和$ router的区别

1.$route是“路由信息对象”,包括path,params,hash,query,fullPath,matched,name等路由信息参数。

1.$route.path 字符串,对应当前路由的路径,总是解析为绝对路径如"/foo/bar"。
2. $route.params 一个 key/value 对象,包含了 动态片段 和 全匹配片段, 如果没有路由参数,就是一个空对象。
3. $route.query 一个 key/value 对象,表示 URL 查询参数。 例如,对于路径 /foo?user=1,则有 $route.query.user == 1, 如果没有查询参数,则是个空对象
4. $route.hash 当前路由的hash值 (不带#) ,如果没有 hash 值,则为空字符串
5. $route.fullPath 完成解析后的 URL,包含查询参数和hash的完整路径。
6. $route.matched 数组,包含当前匹配的路径中所包含的所有片段所对应的配置参数对象。
7. $route.name 当前路径名字
8. $ route.meta 路由元信息

$router是“路由实例”对象包括了路由的跳转方法,钩子函数等
实例方法:

1、push

1.字符串this. r o u t e r . p u s h ( ′ h o m e ′ ) 2. 对 象 t h i s . router.push('home') 2. 对象this. router.push(home)2.this.router.push({path:‘home’})
3. 命名的路由this. r o u t e r . p u s h ( n a m e : ′ u s e r ′ , p a r a m s : u s e r I d : 123 ) 4. 带 查 询 参 数 , 变 成 / r e g i s t e r ? p l a n = 123 t h i s . router.push({name:'user',params:{userId:123}}) 4.带查询参数,变成 /register?plan=123this. router.push(name:user,params:userId:123)4./register?plan=123this.router.push({path:‘register’,query:{plan:‘123’}})
push方法其实和< router-link :to="…">是等同的。
注意:push方法的跳转会向 history 栈添加一个新的记录,当我们点击浏览器的返回按钮时可以看到之前的页面。

2、go
页面路由跳转
前进或者后退this.$router.go(-1) // 后退
3、replace
push方法会向 history 栈添加一个新的记录,而replace方法是替换当前的页面,
不会向 history 栈添加一个新的记录

20.vue-router实现路由懒加载(动态加载路由)

把不同路由对应的组件分割成不同的代码块,然后当路由被访问时才加载对应的组件即为路由的懒加载,可以加快项目的加载速度,提高效率

const router = new VueRouter({
  routes: [
    {
      path: '/home',
      name: 'Home',
      component:() = import('../views/home')
		}
  ]
})

你可能感兴趣的:(面试题,vue.js,前端,javascript,面试)