Vue 高频面试题2021

179 阅读9分钟

1. 简述MVVM

     MVVM 是 Model-View-ViewModel缩写,也就是把MVC中的Controller演变成ViewModel。Model层代表数据模型,View代表UI组件,ViewModel是View和Model层的桥梁,数据会绑定到ViewModel层并自动将数据渲染到页面中,视图变化的时候会通知ViewModel层更新数据。

2. Vue生命周期

  • beforeCreate阶段: vue实例的挂载元素el和数据对象data都是undefined,还没有初始化。

  • created阶段: vue实例的数据对象data有了,可以访问里面的数据和方法,未挂载到DOM,el还没有。

  • beforeMount阶段: vue实例的el和data都初始化了,但是挂载之前为虚拟的dom节点。

  • mounted阶段: vue实例挂载到真实DOM上,就可以通过DOM获取DOM节点。

  • beforeUpdate阶段: 响应式数据更新时调用,发生在虚拟DOM打补丁之前,适合在更新之前访问现有的DOM,比如手动移除已添加的事件监听器。

  • updated阶段: 虚拟DOM重新渲染和打补丁之后调用,组成新的DOM已经更新,避免在这个钩子函数中操作数据,防止死循环。

  • beforeDestroy阶段: 实例销毁前调用,实例还可以用,this能获取到实例,常用于销毁定时器,解绑事件。

  • destroyed阶段: 实例销毁后调用,调用后所有事件监听器会被移除,所有的子实例都会被销毁。

3. Vue 是如何实现数据双向绑定的

  • Vue 数据双向绑定主要是指:数据变化更新视图,视图变化更新数据
    • 输入框内容变化时,Data 中的数据同步变化。即 View => Data 的变化。
    • Data 中的数据变化时,文本节点的内容同步变化。即 Data => View 的变化。
  • View 变化更新 Data,可以通过事件监听的方式实现,所以Vue 的数据双向绑定的主要工作是如何让 Data 变化更新 View

4. Vue 实现双向绑定的原理

  1. 实现一个监听器 Observer: 对数据对象进行遍历,包括子属性对象属性,利用 Object.defineProperty 对属性都加上 setter 和 getter。这样之后,给这个对象某个属性赋值,就会触发它的 setter ,那么就能监听到数据变化。

  2. 实现一个解析器 Compile: 解析 Vue 模板指令,将模板中的变量都替换成数据,然后渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据发生变动,收到通知调用更新函数进行更新.

  3. 实现一个订阅者 Watcher: Watcher 订阅者是 Observer 和 Compile 之间通信的桥梁,主要任务是订阅 Observer 中的属性值变化的消息,当收到变化时,触发解析器 Compile 中对应的更新函数。

5. Vue 中的 computed 和 watch 的区别

  • 功能上:computed 是计算属性,也就是依赖其它的属性计算后所得出的值。 watch是去监听一个值的变化,然后执行相应的函数
  • 使用上:computed 中的函数必须使用 return 返回;,watch 的回调里面传入监听属性的新旧值,通过这两个值可以做一些特定的操作,不是必须要return 
  • 性能上:computed 中的函数所依赖的属性没有发生变化,那么调用当前函数的时候回从缓存中读取,而 watch 在每次监听值发生变化的时候都会执行回调,支持对属性的深度监听。
  • 场景上:computed 当一个属性受多个属性影响的时候,例如:商品结算;watch:当一条数据影响多个数据的时候。例如:分页

6. Vuex的流程

  1. 页面通过mapAction异步提交事件到action。
  2. action通过commit把对应参数同步提交到mutation。
  3. mutation会修改state中对于的值。
  4. 最后通过getter把对应值跑出去,在页面的计算属性中通过mapGetter来动态获取state中的值

7. Vuex有哪几种状态和属性

  • state中保存着共有数据,数据是响应式的
  • getter可以对state进行计算操作,主要用来过滤一些数据,可以在多组件之间复用
  • mutations定义的方法动态修改state中的数据,通过commit提交方法,方法必须是同步的
  • actions将mutations里面处理数据的方法变成异步的,就是异步操作数据,通过store.dispatch来分发actions,把异步的方法写在actions中,通过commit提交mutations,进行修改数据。
  • modules:模块化vuex

8. 常用指令

  • v-if:判断是否隐藏
  • v-for:数据循环出来
  • v-bind:绑定数据
  • v-model:实现双向绑定
  • v-on:事件

9. Vue修饰符

  • stop:阻止事件的冒泡
  • prevent:阻止事件的默认行为
  • once:只触发一次
  • self:只触发自己的事件行为时,才会执行

10. v-for中key的作用

key 是 Vue 使用 v-for 渲染列表时的节点标识。使用了 key 之后,当列表项发生变化时,Vue 会基于 key 的变化而重新排列元素顺序,并且移除 key 不存在的元素,提升运行效率。

11. v-if 和 v-show 有什么区别

v-if 在进行切换时,会直接对标签进行创建或销毁,不显示的标签不会加载在 DOM 树中。
v-show 在进行切换时,会对标签的 display 属性进行切换,通过 display 不显示来隐藏元素。
一般来说,v-if 的性能开销会比 v-show 大,切换频繁的标签更适合使用 v-show。

12. $route和$router的区别

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

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

13. $nextTick的实现

Vue 实现响应式并不是在数据发生后立即更新 DOM,使用 vm.$nextTick 是在下次 DOM 更新循环结束之后立即执行延迟回调。在修改数据之后使用,则可以在回调中获取更新后的 DOM。

14. Vue组件中data必须是一个函数

如果 data 是一个对象,当复用组件时,因为 data 都会指向同一个引用类型地址,其中一个组件的 data 一旦发生修改,则其他重用的组件中的 data 也会被一并修改。

如果 data 是一个返回对象的函数,因为每次重用组件时返回的都是一个新对象,引用地址不同,便不会出现如上问题

15. Vue-router 路由有哪些模式?

一般有两种模式:

  • hash 模式:后面的 hash 值的变化,浏览器既不会向服务器发出请求,浏览器也不会刷新,每次 hash 值的变化会触发 hashchange 事件。

  • history 模式:利用了 HTML5 中新增的 pushState()replaceState() 方法。这两个方法应用于浏览器的历史记录栈,在当前已有的 back、forward、go的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改时,虽然改变了当前的 URL,但浏览器不会立即向后端发送请求。

16. SPA 单页面的理解,优缺点分别是什么

single-page application 仅在 web 页面初始化时加载响应的 HTML、JavaScript 和 CSS。一旦页面加载完成,SPA 不会因为用户的操作而进行页面的重新加载或跳转;取而代之的是利用路由机制实现 HTML 内部的变换,UI与用户的交互,避免页面的重新加载。

优点:

  1. 用户体验好,快,内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染;
  2. 基于1的优点,SPA 相对对服务器的压力小;
  3. 前后端分离,架构清晰,前端进行交互逻辑,后端负责数据处理;

缺点:

  1. 初次加载消耗多,问了实现单页 web 应用功能及显示效果,需要在加载页面的时候将 JavaScript、CSS 同一加载,部分页面按需加载
  2. 前进后退路由管理: 由于单页面应用在一个页面上显示所有的内容,所以不能使用浏览器的前进后退功能,所有的页面切换需要自己建立堆栈管理。
  3. SEO 难度较大: 由于所有的内容都在一个页面中动态替换显示,所以在 SEO 上有着天然的劣势。

17. SSR(服务端渲染)

SSR(服务端渲染) 将 Vue 在客户端将标签渲染成HTML 片段的工作放到了服务端完成,服务端形成的 HTML 片段直接返回给客户端这个过程,叫做服务端渲染。

优点:

  1. 更好的 SEO:因为 SPA 页面的内容是通过 Ajax 获取,而搜索引擎爬取并不会等待异步完成后再去抓取结果,所以在 SPA 中抓取不到页面 Ajax 的请求内容,而 SSR 是结果从服务端渲染,返回时已经渲染好的页面(数据也包含在内),所以搜索引擎爬取可以抓到渲染好的页面;
  2. 更快的内容到达时间(首屏加载更快):SPA 等待所有 Vue 编译后的 js 文件都要下载完成后,才会进行页面的渲染,需要等待一段时间,SSR 直接由服务端渲染好页面直接返回显示,无需等待下载js 过程再去渲染,所以 SSR 更快。

缺点:

  1. 更多的开发条件限制: 只能在某些生命周期钩子函数 (lifecycle hook) 中使用;一些外部扩展库 (external library) 可能需要特殊处理,才能在服务器渲染应用程序中运行。
  2. 涉及构建设置和部署的更多要求:与可以部署在任何静态文件服务器上的完全静态单页面应用程序 (SPA) 不同,服务器渲染应用程序,需要处于 Node.js server 运行环境。
  3. 更多的服务器端负载:在 Node.js 中渲染完整的应用程序,显然会比仅仅提供静态文件的 server 更加大量占用 CPU 资源 (CPU-intensive - CPU 密集),因此如果你预料在高流量环境 (high traffic) 下使用,请准备相应的服务器负载,并明智地采用缓存策略。