Vue面试题整理汇总

1、面试官:简述MVVM?

MVVM表示的是 Model-View-ViewModel,也就是把MVC中的Controller演变成ViewModel。Model层代表数据模型,View代表UI组件,ViewModel是View和Model层的桥梁,数据会绑定到viewModel层并自动将数据渲染到页面中,视图变化的时候会通知viewModel层更新数据。以前是操作DOM结构更新视图,现在是数据驱动视图。

MVVM的优点:

1.低耦合。视图(View)可以独立于Model变化和修改,一个Model可以绑定到不同的View上,当View变化的时候Model可以不变化,当Model变化的时候View也可以不变;

2.可重用性。你可以把一些视图逻辑放在一个Model里面,让很多View重用这段视图逻辑。

3.独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计。

4.可测试。

2、面试官:请描述下你对vue生命周期的理解?在created和mounted这两个生命周期中请求数据有什么区别呢?

每个Vue实例在创建时都会经过一系列的初始化过程,vue的生命周期钩子,就是说在达到某一阶段或条件时去触发的函数,目的就是为了完成一些动作或者事件

Vue生命周期总共可以分为8个阶段:创建前后,载入前后,更新前后,销毁前销毁后,以及一些特殊场景的生命周期

生命周期

描述

beforeCreate

组件实例被创建之初,此时data和methods中的数据都还没有初始化,无法用vm访问

created

组件实例已经完全创建,data中有值,未挂载,可以用vm访问

beforeMount

组件挂载之前,页面呈现的是未经Vue编译的DOM结构,可以取数据

Mounted

组件挂载到实例上去之后,此时可以操作DOM,页面呈现的是经Vue编译的DOM结构

beforeUpdate

组件数据发生变化,更新之前,数据是新的,但页面是旧的。

updated

组件数据更新之后,页面和数据保持同步

beforeDestroy

组件实例销毁之前,此时可以手动销毁一些方法

destroyed

组件实例销毁之后

activated

keep-alive 缓存的组件激活时

deactivated

keep-alive 缓存的组件停用时调用

errorCaptured

捕获一个来自子孙组件的错误时被调用

题外话:数据请求在created和mouted的区别

created是在组件实例一旦创建完成的时候立刻调用,这时候页面dom节点并未生成;mounted是在页面dom节点渲染完毕之后就立刻执行的。触发时机上created是比mounted要更早的,两者的相同点:都能拿到实例对象的属性和方法。 讨论这个问题本质就是触发的时机,放在mounted中的请求有可能导致页面闪动(因为此时页面dom结构已经生成),但如果在页面加载前完成请求,则不会出现此情况。建议对页面内容的改动放在created生命周期当中。

3、面试官:你对SPA单页面的理解

单页应用SPA是一种网络应用程序或网站的模型,它通过动态重写当前页面来与用户交互,这种方法避免了页面之间切换打断用户体验。在单页应用中,所有必要的代码(HTML、JavaScript和CSS)都通过单个页面的加载而检索,或者根据需要(通常是为响应用户操作)动态装载适当的资源并添加到页面页面在任何时间点都不会重新加载,也不会将控制转移到其他页面。

我们熟知的JS框架如react,vue,angular都属于SPA

4、面试官:v-show和v-if有什么区别?使用场景分别是什么?

在 vue 中 v-show 与 v-if 的作用效果是相同的,都能控制元素在页面是否显示

当表达式为true的时候,都会占据页面的位置,当表达式为false时,都不会占据页面位置

区别:

1、v-show隐藏则是为该元素添加css--display:none,dom元素依旧还在。v-if显示隐藏是将dom元素整个添加或删除

2、v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-show只是简单的基于css切换

3、v-show 由false变为true的时候不会触发组件的生命周期

v-if由false变为true的时候,触发组件的beforeCreate、create、beforeMount、mounted钩子,由true变为false的时候触发组件的beforeDestory、destoryed方法

性能消耗:v-if有更高的切换消耗;v-show有更高的初始渲染消耗;

v-show与v-if的使用场景

如果需要非常频繁地切换,则使用 v-show 较好

如果在运行时条件很少改变,则使用 v-if 较好

5、面试官:Vue实例挂载的过程

1、new Vue的时候调用会调用_init方法

定义 $set、$get、$delete、$watch 等方法

定义 $on、$off、$emit、$off等事件

定义 _update、$forceUpdate、$destroy生命周期

2、调用$mount进行页面的挂载

3、挂载的时候主要是通过mountComponent方法

4、定义updateComponent更新函数

5、执行render生成虚拟DOM

6、update将虚拟DOM生成真实DOM结构,并且渲染到页面中

6、面试官:v-if和v-for的优先级是什么?

v-if指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 true值的时候被渲染 。

v-for指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组或者对象,而 item 则是被迭代的数组元素的别名

在 v-for 的时候,建议设置key值,并且保证每个key值是独一无二的,这便于diff算法进行优化。

1.当 v-for 和 v-if 处于同一个节点时,v-for 的优先级比v-if 更高,这意味着 v-if 将分别重复运行于每个 v-for 循环中。如果要遍历的数组很大,而真正要展示的数据很少时,这将造成很大的性能浪费(Vue2.x)

2.这种场景建议使用 computed,先对数据进行过滤

7、面试官:组件中的data为什么是一个函数?

1.一个组件被复用多次的话,也就会创建多个实例。本质上,这些实例用的都是同一个构造函数。

2.如果data是对象的话,对象属于引用类型,会影响到所有的实例造成数据污染。所以为了保证组件不同的实例之间data不冲突,data必须是一个函数。

8、面试官:动态给vue的data添加一个新的属性时会发生什么?怎样解决?

直接添加属性数据虽然更新了,但页面并没有更新

因为vue2是用Object.defineProperty实现数据响应式,当我们访问或者设置数据的时候都能够触发setter与getter,但是我们为obj添加新属性的时候,却无法触发事件属性的拦截

原因是一开始obj的旧属性被设成了响应式数据,而后面新增的属性并没有通过Object.defineProperty设置成响应式数据

解决方案:

若想实现数据与视图同步更新,可采取下面三种解决方案:

Vue.set()     //Vue.set( target, propertyName, value )
Object.assign()  //创建一个新的对象,合并原对象和混入对象的属性
$forcecUpdated()   //在Vue中做一次强制更新

9、面试官:Vue中组件和插件有什么区别?

组件就是把图形、非图形的各种逻辑均抽象为一个统一的概念(组件)来实现开发的模式,在Vue中每一个.vue文件都可以视为一个组件

插件通常用来为Vue 添加全局功能

两者的区别主要表现在以下几个方面:

1、编写形式 2、注册形式 3、使用场景

编写形式:组件的编写形式为