Vue高级面试题汇总

说说你对SPA单页面的理解,它的优缺点分别是什么?

参考答案

是一种只须要将单个页面加载到服务器之中的web应用程序。当浏览器向服务器发出第一个请求时,服务器会返回一个index.html文件,它所需的js,css等会在显示时统一加载,部分页面按需加载。url地址变化时不会向服务器在请求页面,经过路由才实现页面切换。javascript

优势:css

  • 良好的交互体验,用户不须要从新刷新页面,获取数据也是经过Ajax异步获取,页面显示流畅;
  • 良好的先后端工做分离模式。

缺点:html

  • SEO难度较高,因为全部的内容都在一个页面中动态替换显示,因此在SEO上其有着自然的弱势。
  • 首屏加载过慢(初次加载耗时多)

SPA单页面的实现方式有哪些?

参考答案
  • 在hash模式中,在window上监听hashchange事件(地址栏中hash变化触发)驱动界面变化;
  • 在history模式中,在window上监听popstate事件(浏览器的前进或后退按钮的点击触发)驱动界面变化,监听a连接点击事件用history.pushState、history.replaceState方法驱动界面变化;
  • 直接在界面用显示隐藏事件驱动界面变化。

说说你对MVC、MVP、MVVM模式的理解

参考答案

在以往开发程序过程当中,界面布局代码、界面交互逻辑代码、业务逻辑代码三者代码都是混在一块儿的。随着业务需求愈来愈大,代码愈来愈复杂,不只致使开发困难,更是致使维护代码更困难,特别是维护别人的代码。vue

因此就出现MVC模式来解决这个问题,其中M表明Model,专门来处理、存储数据。V表明View,专门来处理页面的展现。C表明Controller专门处理业务逻辑。java

用户操做View,View发送指令到Control,完成业务逻辑处理后,要求Model处理相应的数据,将处理好的数据发送到View,要求View把这些数据展现给用户。node

固然用户也能够直接下发指令到Control,完成对应业务逻辑处理后,要求Model处理相应的数据,将处理好的数据发送到View,要求View把这些数据展现给用户。webpack

也能够经过View直接要求Moder处理数据,将处理好的数据发送到View,要求View把这些数据展现给用户。ios

然而在MVC模式中,Model、Control、View三者相互依赖,修改起来要兼顾其余二者,仍是很是困难。git

因此又出现了MVP模式来解决这个问题,在MVP模式中P表明Presenter替代原来的Control。github

当用户操做View,View发送指令到Presenter,完成业务逻辑处理后,要求Model处理相应的数据,将处理好的数据返回到Presenter中,Presenter将数据发送到View中,要求View把这些数据展现给用户。

MVP模式中,Presenter将View和Model彻底隔离开,Presenter和View相互依赖,Presenter和Model相互依赖,View和Model再也不相互依赖,使代码耦合下降。

由于Presenter和View相互依赖,这样Presenter就没办法单独作单元测试,非得等到View作好之后才行。因此对View分割一部分叫作View接口,Presenter只依赖View接口,这样Presenter不用依赖View就能够测试了,而且也增长了复用性,只要View实现了View接口部分,Presenter就能够大发神威。

然而在MVP模式中,由于让Presenter发送数据到View,让View展现,仍然须要大量的、烦人的代码,这实在是一件不舒服的事情。 那么可不可让View在Model变化时自动更新。

因此出现了MVVM模式来实现这个设想,其中VM表明ViewModel负责视图显示逻辑和监听视图变化,M表明Model变成处理业务逻辑和数据。

当用户操做View时,ViewModel监听到View的变化,会通知Model中对应的方法进行业务逻辑和数据处理,处理完毕后,ViewModel会监听到自动让View作出相应的更新。ViewModel能够对应多个View,具备很强的复用性。

在Vue项目中。new Vue()就是一个ViewModel,View就是template模板。Model就是Vue的选项如data、methods等。在开发过程咱们只关注View怎么展现,Model怎么处理业务逻辑和数据。不要去管处理业务逻辑和数据后怎么让View更新,View上有操做,怎么让Model处理这个操做,这些统统交给ViewModel来实现,大大下降了开发成本。

说说你对Object.defineProperty的理解

参考答案
  • Object.defineProperty(obj,prop,descriptor)方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
    • obj:要在其上定义属性的对象。
    • prop:要定义或修改的属性的名称。
    • descriptor:将被定义或修改的属性描述符。
  • descriptor属性描述符主要有两种形式:数据描述符和存取描述符。描述符必须是这两种形式之一;不能同时是二者。
    • 数据描述符和存取描述符共同拥有
      • configurable:特性表示对象的属性是否能够被删除,以及除value和writable特性外的其余特性是否能够被修改。默认为false。
      • enumerable:当该属性的enumerable为true时,该属性才能够在for...in循环和Object.keys()中被枚举。默认为false。
    • 数据描述符
      • value:该属性对应的值。能够是任何有效的 JavaScript 值(数值,对象,函数等)。默认为undefined。
      • writable:当且仅当该属性的writable为true时,value才能被赋值运算符改变。默认为false。
    • 存取描述符
      • get:一个给属性提供 getter的方法,若是没有getter则为undefined。当访问该属性时,该方法会被执行,方法执行时没有参数传入,可是会传入this对象(因为继承关系,这里的this并不必定是定义该属性的对象)。默认为undefined。
      • set:一个给属性提供 setter的方法,若是没有setter则为undefined。当属性值修改时,触发执行该方法。该方法将接受惟一参数,即该属性新的参数值。默认为undefined。
  • 定义descriptor时,最好先把这些属性都定义清楚,防止被继承和继承时出错。
function Archiver() {
    var temperature = null;
    var archive = [];
    Object.defineProperty(this, 'temperature', {
        get: function() {
          console.log('get!');
          return temperature;
        },
        set: function(value) {
          temperature = value;
          archive.push({ val: temperature });
        }
    });
    this.getArchive = function() { return archive; };
}
var arc = new Archiver();
arc.temperature; // 'get!'
arc.temperature = 11;
arc.temperature = 13;
arc.getArchive(); // [{ val: 11 }, { val: 13 }]
复制代码

说说你对Proxy的理解

参考答案 官方定义:proxy对象用于定义基本操做的自定义行为(如属性查找,赋值,枚举,函数调用等)。

通俗来讲是在对目标对象的操做以前提供了拦截,对外界的操做进行过滤和修改某些操做的默认行为,能够不直接操做对象自己,而是经过操做对象的代理对象来间接来操做对象。

let proxy = new Proxy(target, handler)

  • target 是用 Proxy 包装的目标对象(能够是任何类型的对象,包括原生数组,函数,甚至另外一个代理);
  • handler 一个对象,其属性是当执行一个操做时定义代理的行为的函数,也就是自定义的行为。

handle能够为{},可是不能为null,不然会报错

Proxy 目前提供了 13 种可代理操做,比较经常使用的

  • handler.get(target,property,receiver)获取值拦截
  • handler.set(target,property,value,receiver)设置值拦截
  • handler.has(target,prop)in 操做符拦截
let obj = {
	a : 1,
	b : 2
}
let test = new Proxy(obj,{
    get : function (target,property) {
        return property in target ? target[property] : 0
    },
    set : function (target,property,value) {
        target[property] = 6;
    },
    has: function (target,prop){
        if(prop == 'b'){
            target[prop] = 6;
        }
        return prop in target;
    },
})

console.log(test.a);        // 1
console.log(test.c);        // 0

test.a = 3;
console.log(test.a)         // 6

if('b' in test){
    console.log(test)       // Proxy {a: 6, b: 6}
}
复制代码

Object.defineProperty和Proxy的区别

参考答案
  • Object.defineProperty
    • 不能监听到数组length属性的变化;
    • 不能监听对象的添加;
    • 只能劫持对象的属性,所以咱们须要对每一个对象的每一个属性进行遍历。
  • Proxy
    • 能够监听数组length属性的变化;
    • 能够监听对象的添加;
    • 可代理整个对象,不须要对对象进行遍历,极大提升性能;
    • 多达13种的拦截远超Object.defineProperty只有get和set两种拦截。

Vue的模板语法用的是哪一个web模板引擎的吗?说说你对这模板引擎的理解?

参考答案

采用的是Mustache的web模板引擎mustache.js

<script type="text/javascript" src="./mustache.js"></script>
<script type="text/javascript">
    var data = {
        "company": "Apple",
    }

    var tpl = '<h1>Hello {{company}}</h1>';
    var html = Mustache.render(tpl, data);

    console.log(html);
</script>
复制代码

你认为Vue的核心是什么?

参考答案

Vue.js 的核心是一个容许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统。

以上是官方原话,从中能够得知Vue的核心是模板语法和数据渲染。

说说你对单向数据流和双向数据流的理解

参考答案

单向数据流是指数据只能从父级向子级传递数据,子级不能改变父级向子级传递的数据。

双向数据流是指数据从父级向子级传递数据,子级能够经过一些手段改变父级向子级传递的数据。

好比用v-model.sync来实现双向数据流。

什么是双向绑定?原理是什么?

参考答案

双向绑定是指数据模型(Module)和视图(View)之间的双向绑定。

其原理是采用数据劫持结合发布者-订阅者模式的方式来实现。

Vue中先遍历data选项中全部的属性(发布者)用Object.defineProperty劫持这些属性将其转为getter/setter。读取数据时候会触发getter。修改数据时会触发setter。

而后给每一个属性对应new Dep(),Dep是专门收集依赖、删除依赖、向依赖发送消息的。先让每一个依赖设置在Dep.target上,在Dep中建立一个依赖数组,先判断Dep.target是否已经在依赖中存在,不存在的话添加到依赖数组中完成依赖收集,随后将Dep.target置为上一个依赖。

组件在挂载过程当中都会new一个Watcher实例。这个实例就是依赖(订阅者)。Watcher第二参数式一个函数,此函数做用是更新且渲染节点。在首次渲染过程,会自动调用Dep方法来收集依赖,收集完成后组件中每一个数据都绑定上该依赖。当数据变化时就会在seeter中通知对应的依赖进行更新。在更新过程当中要先读取数据,就会触发Wacther的第二个函数参数。一触发就再次再次自动调用Dep方法收集依赖,同时在此函数中运行patch(diff运算)来更新对应的DOM节点,完成了双向绑定。

什么是虚拟DOM?

参考答案 虚拟DOM是将状态映射成视图的众多解决方案中的一种,其是经过状态生成一个虚拟节点树,而后使用虚拟节点树进行渲染生成真实DOM,在渲染以前,会使用新生成的虚拟节点树和上一次虚拟节点树进行对比,只渲染不一样的部分。

Vue中如何实现一个虚拟DOM?说说你的思路

参考答案 首先要构建一个VNode的类,DOM元素上的全部属性在VNode类实例化出来的对象上都存在对应的属性。例如tag表示一个元素节点的名称,text表示一个文本节点的文本,chlidren表示子节点等。将VNode类实例化出来的对象进行分类,例如注释节点、文本节点、元素节点、组件节点、函数式节点、克隆节点。

而后经过编译将模板转成渲染函数render,执行渲染函数render,在其中建立不一样类型的VNode类,最后整合就能够获得一个虚拟DOM(vnode)。

最后经过patch将vnode和oldVnode进行比较后,生成真实DOM。

你了解Vue的diff算法吗?

参考答案

你知道nextTick的原理吗?

参考答案

说说你对Vue的template编译的理解?

参考答案

Vue实例挂载的过程是什么?

参考答案

在初始化的最后,若是检测到选项有el属性,则调用vm.$mount方法挂载vm,挂载的目标就是把模板渲染成最终的DOM

  • 第一步:确保vm.$options有render函数。

由于在不一样构建版本上的挂载过程都不同,因此要对Vue原型上的$mount方法进行函数劫持。

首先建立一个变量mount将Vue原型上的$mount方法保存到这个变量上。而后Vue原型上的$mount方法被一个新的方法覆盖。在这个新方法中调用mount这个原始方法。

经过el属性进行获取DOM元素。若是el是字符串,则使用document.querySelector获取DOM元素并赋值给el。若是获取不到,则建立一个空的div元素并赋值给el。若是el不是字符串,默认el是DOM元素,不进行处理。

判断el是否是html元素或body元素,若是是则给出警告退出程序。

由于挂载后续过程当中须要render函数生成vnode,故要判断$options选项中是否有render函数这个属性,若是有直接调用原始的$mount方法。

若是没有,则判断template是否存在。若不存在则将el的outerHTML赋值给template。若存在,若是template是字符串且以#开头,经过选择符获取DOM元素获取innerHTML赋值给template,若是template已是DOM元素类型直接获取innerHTML赋值给template。

而后将template编译成代码字符串并将代码字符串转成render函数,并赋值到vm.$options的render属性上。

最后调用原始的$mount方法。

  • 第二步: 在原始的$mount方法,先触发beforeMount钩子函数,而后建立一个Watcher实例,在第二参数传入一个函数vm._update

该函数是首次渲染和更新渲染做用,参数为render函数(vnode),若是vm._vnode不存在则进行首次渲染。

同时vnode中被劫持的数据自动收集依赖。当vnode中被劫持的数据变化时候触发对应的依赖,从而触发vm._update进行更新渲染。

最后触发mounted钩子函数。

说下你对指令的理解?

参考答案

Vue为何要求组件模板只能有一个根元素?

参考答案 当前的virtualDOM差别和diff算法在很大程度上依赖于每一个子组件老是只有一个根元素。

你有用过事件总线(EventBus)吗?说说你的理解

参考答案

使用Vue后怎么针对搜索引擎作SEO优化?

参考答案

SSR解决了什么问题?有作过SSR吗?你是怎么作的?

参考答案

axios是什么?怎样使用它?怎么解决跨域的问题?

参考答案

ajax、fetch、axios这三都有什么区别?

参考答案

为什么官方推荐使用axios而不用vue-resource?

参考答案

你有封装过axios吗?主要是封装哪方面的?

参考答案

Vue开发过程你是怎么作接口管理的?

参考答案

如何中断axios的请求?

参考答案

若是将axios异步请求同步化处理?

参考答案

你了解axios的原理吗?有看过它的源码吗?

参考答案

你有写过自定义组件吗?

参考答案

说说你对Vue组件的设计原则的理解

参考答案

写出多种定义组件模板的方法

参考答案

你有使用过render函数吗?有什么好处?

参考答案

你了解什么是函数式组件吗?

参考答案

函数式组件的应用

你有使用过JSX吗?说说你对JSX的理解?

参考答案

JSX就是Javascript和XML结合的一种格式。React发明了JSX,利用HTML语法来建立虚拟DOM。当遇到<,JSX就当HTML解析,遇到{就当JavaScript解析。

若是想扩展某个现有的Vue组件时,怎么作呢?

参考答案
  • 用mixins混入
  • 用extends,比mixins先触发
  • 用高阶组件HOC封装

你了解什么是高阶组件吗?能否举个例子说明下?

参考答案

怎么在Vue中使用插件?

参考答案

组件和插件有什么区别?

参考答案

为何Vue使用异步更新组件?

参考答案

你有看过Vue推荐的风格指南吗?列举出你知道的几条

参考答案

如何优化首页的加载速度?

参考答案

Vue渲染大量数据时应该怎么优化?说下你的思路!

参考答案 懒加载和分页

你有使用过babel-polyfill模块吗?主要是用来作什么的?

参考答案

为何咱们写组件的时候能够写在.vue里呢?能够是别的文件名后缀吗?

参考答案

vue-loader是什么?它有什么做用?

参考答案

分析下Vue项目本地开发完成后部署到服务器后报404是什么缘由呢?

参考答案

Vue首页白屏是什么问题引发的?如何解决呢?

参考答案

vue打包成最终的文件有哪些?

参考答案

如何解决vue打包vendor过大的问题?

参考答案

webpack打包vue速度太慢怎么办?

参考答案

vue部署上线前须要作哪些准备工做?

参考答案

说说你以为认为的Vue开发规范有哪些?

参考答案

你有使用过Vue开发多语言项目吗?说说你的作法?

参考答案

用vue怎么实现一个换肤的功能?

参考答案

对于即将到来的vue3.0特性你有什么了解的吗?

参考答案
相关文章
相关标签/搜索