【建议收藏】2020大厂Vue面试题汇总,持续更新中~

1.vue中 key 值的做用

使用key来给每一个节点作一个惟一标识
key的做用主要是为了高效的更新虚拟DOM。另外vue中在使用相同标签名元素的过渡切换时,也会使用到key属性,其目的也是为了让vue能够区分它们,
不然vue只会替换其内部属性而不会触发过渡效果。html

2.Vue 组件中 data 为何必须是函数?

在 new Vue() 中,data 是能够做为一个对象进行操做的,然而在 component 中,data 只能以函数的形式存在,不能直接将对象赋值给它。
当data选项是一个函数的时候,每一个实例能够维护一份被返回对象的独立的拷贝,这样各个实例中的data不会相互影响,是独立的。前端

3.vuex的State特性是?

1、Vuex就是一个仓库,仓库里面放了不少对象。其中state就是数据源存放地,对应于与通常Vue对象里面的data
2、state里面存放的数据是响应式的,Vue组件从store中读取数据,如果store中的数据发生改变,依赖这个数据的组件也会发生更新
3、它经过mapState把全局的 state 和 getters 映射到当前组件的 computed 计算属性中vue

4.介绍一下Vue的响应式系统

Vue为MVVM框架,当数据模型data变化时,页面视图会获得响应更新,其原理对data的getter/setter方法进行拦截(Object.defineProperty或者Proxy),利用发布订阅的设计模式,在getter方法中进行订阅,在setter方法中发布通知,让全部订阅者完成响应。node

在响应式系统中,Vue会为数据模型data的每个属性新建一个订阅中心做为发布者,而监听器watch、计算属性computed、视图渲染template/render三个角色同时做为订阅者,对于监听器watch,会直接订阅观察监听的属性,对于计算属性computed和视图渲染template/render,若是内部执行获取了data的某个属性,就会执行该属性的getter方法,而后自动完成对该属性的订阅,当属性被修改时,就会执行该属性的setter方法,从而完成该属性的发布通知,通知全部订阅者进行更新。react

5.computed与watch的区别

计算属性computed和监听器watch均可以观察属性的变化从而作出响应,不一样的是:webpack

计算属性computed更可能是做为缓存功能的观察者,它能够将一个或者多个data的属性进行复杂的计算生成一个新的值,提供给渲染函数使用,当依赖的属性变化时,computed不会当即从新计算生成新的值,而是先标记为脏数据,当下次computed被获取时候,才会进行从新计算并返回。ios

而监听器watch并不具有缓存性,监听器watch提供一个监听函数,当监听的属性发生变化时,会当即执行该函数。web

6.介绍一下Vue的生命周期

beforeCreate:是new Vue()以后触发的第一个钩子,在当前阶段data、methods、computed以及watch上的数据和方法都不能被访问。面试

created:在实例建立完成后发生,当前阶段已经完成了数据观测,也就是可使用数据,更改数据,在这里更改数据不会触发updated函数。能够作一些初始数据的获取,在当前阶段没法与Dom进行交互,若是非要想,能够经过vm.$nextTick来访问Dom。ajax

beforeMount:发生在挂载以前,在这以前template模板已导入渲染函数编译。而当前阶段虚拟Dom已经建立完成,即将开始渲染。在此时也能够对数据进行更改,不会触发updated。

mounted:在挂载完成后发生,在当前阶段,真实的Dom挂载完毕,数据完成双向绑定,能够访问到Dom节点,使用$refs属性对Dom进行操做。

beforeUpdate:发生在更新以前,也就是响应式数据发生更新,虚拟dom从新渲染以前被触发,你能够在当前阶段进行更改数据,不会形成重渲染。

updated:发生在更新完成以后,当前阶段组件Dom已完成更新。要注意的是避免在此期间更改数据,由于这可能会致使无限循环的更新。

beforeDestroy:发生在实例销毁以前,在当前阶段实例彻底能够被使用,咱们能够在这时进行善后收尾工做,好比清除计时器。

destroyed:发生在实例销毁以后,这个时候只剩下了dom空壳。组件已被拆解,数据绑定被卸除,监听被移出,子实例也通通被销毁。

7.为何组件的data必须是一个函数

一个组件可能在不少地方使用,也就是会建立不少个实例,若是data是一个对象的话,对象是引用类型,一个实例修改了data会影响到其余实例,因此data必须使用函数,为每个实例建立一个属于本身的data,使其同一个组件的不一样实例互不影响。

8.组件之间是怎么通讯的

父子组件通讯
父组件 -> 子组件:prop

子组件 -> 父组件:$on/$emit

获取组件实例:使用$parent/$children,$refs.xxx,获取到实例后直接获取属性数据或调用组件方法

兄弟组件通讯
Event Bus:每个Vue实例都是一个Event Bus,都支持$on/$emit,能够为兄弟组件的实例之间new一个Vue实例,做为Event Bus进行通讯。

Vuex:将状态和方法提取到Vuex,完成共享

跨级组件通讯
使用provide/inject

Event Bus:同兄弟组件Event Bus通讯

Vuex:将状态和方法提取到Vuex,完成共享

9.Vue事件绑定原理说一下

每个Vue实例都是一个Event Bus,当子组件被建立的时候,父组件将事件传递给子组件,子组件初始化的时候是有$on方法将事件注册到内部,在须要的时候使用$emit触发函数,而对于原生native事件,使用addEventListener绑定到真实的DOM元素上。

10.vue的优势是什么?

低耦合。视图(View)能够独立于Model变化和修改,一个ViewModel能够绑定到不一样的"View"上,当View变化的时候Model能够不变,当Model变化的时候View也能够不变。
可重用性。你能够把一些视图逻辑放在一个ViewModel里面,让不少view重用这段视图逻辑。
独立开发。开发人员能够专一于业务逻辑和数据的开发(ViewModel),设计人员能够专一于页面设计。
可测试。界面素来是比较难于测试的,而如今测试能够针对ViewModel来写

11.Vue与Angular以及React的区别?

1.与AngularJS的区别
相同点:
都支持指令:内置指令和自定义指令。
都支持过滤器:内置过滤器和自定义过滤器。
都支持双向数据绑定。
都不支持低端浏览器。
不一样点:
1.AngularJS的学习成本高,好比增长了Dependency Injection特性,而Vue.js自己提供的API都比较简单、直观。
2.在性能上,AngularJS依赖对数据作脏检查,因此Watcher越多越慢。
Vue.js使用基于依赖追踪的观察而且使用异步队列更新。全部的数据都是独立触发的。 对于庞大的应用来讲,这个优化差别仍是比较明显的。
2.与React的区别
相同点:
1.React采用特殊的JSX语法,Vue.js在组件开发中也推崇编写.vue特殊文件格式,对文件内容都有一些约定,二者都须要编译后使用。
2.中心思想相同:一切都是组件,组件实例之间能够嵌套。
3.都提供合理的钩子函数,可让开发者定制化地去处理需求。
4.都不内置AJAX,Route等功能到核心包,而是以插件的方式加载。 5.在组件开发中都支持mixins的特性。
不一样点:
React依赖Virtual DOM,而Vue.js使用的是DOM模板。React采用的Virtual DOM会对渲染出来的结果作脏检查。
Vue.js在模板中提供了指令,过滤器等,能够很是方便,快捷地操做DOM。

12.什么是vue的计算属性?

在模板中放入太多的逻辑会让模板太重且难以维护,在须要对数据进行复杂处理,且可能屡次使用的状况下,尽可能采起计算属性的方式。好处:①使得数据处理结构清晰;②依赖于数据,数据更新,处理结果自动更新;③计算属性内部this指向vm实例;④在template调用时,直接写计算属性名便可;⑤经常使用的是getter方法,获取数据,也可使用set方法改变数据;⑥相较于methods,无论依赖的数据变不变,methods都会从新计算,可是依赖数据不变的时候computed从缓存中获取,不会从新计算。

13.vue等单页面应用(spa)及其优缺点

优势: Vue的目标是经过尽量简单的 API实现响应的数据绑定和组合的视图组件,核心是一个响应的数据绑定系统。MVVM、数据驱动、组件化、轻量、简洁、高效、快速、模块友好;即第一次就将全部的东西都加载完成,所以,不会致使页面卡顿。
缺点: 不支持低版本的浏览器,最低只支持到IE9;不利于SEO的优化(若是要支持SEO,建议经过服务端来进行渲染组件);第一次加载首页耗时相对长一些;不可使用浏览器的导航按钮须要自行实现前进、后退。

14.active-class是哪一个组件的属性?嵌套路由怎么定义?

vue-router模块的router-link组件的属性。
嵌套路由:
嵌套路由顾名思义就是路由的多层嵌套。
重构router/index.js的路由配置,须要使用children数组来定义子路由 ,路由定义:

{
      path: '/me',
      name: 'Me',
      component: Me,
      children: [
        {
          path: 'collection',
          name: 'Collection',
          component: Collection
        },
        {
          path: 'trace',
          name: 'Trace',
          component: Trace
        }
      ]
    }

以“/”开头的嵌套路径会被看成根路径,因此子路由上不用加“/”;
在生成路由时,主路由上的path会被自动添加到子路由以前,因此子路由上的path不用在从新声明主路由上的path了。
在外层路由组件中,以下写法。

<template>
  <div class="me">
    <div class="tabs">
      <ul>
        <!--<router-link :to="{name: 'Default'}" tag="li" exact>默认内容</router-link>-->
        <router-link :to="{name: 'Collection'}" tag="li" >个人收藏</router-link>
        <router-link :to="{name: 'Trace'}" tag="li">个人足迹</router-link>
      </ul>
    </div>
    <div class="content">
      <router-view></router-view>
    </div>
  </div>
</template>
因为篇幅有限,只能分享部分面试题,更多面试题及答案能够【点击我】阅读下载哦~无偿分享给你们,算是一个感恩回馈吧

15.pwa是什么?

渐进式网页应用,PWA 应该具备一下特性:
渐进式:能确保每一个用户都能打开网页响应式:PC,手机,平板,无论哪一种格式,网页格式都能完美适配
2.离线应用:支持用户在没网的条件下也能打开网页,这里就须要 Service Worker 的帮助
3.APP 化:可以像 APP 同样和用户进行交互
4.常更新:一旦 Web 网页有什么改动,都能当即在用户端体现出来
5.安全:安全第一,给本身的网站加上一把绿锁–HTTPS
6.可搜索:可以被引擎搜索到
7.推送:作到在不打开网页的前提下,推送新的消息
8.可安装:可以将 Web 想 APP 同样添加到桌面
9.可跳转:只要经过一个链接就能够跳转到你的 Web 页面

16.slot是什么?有什么做用?原理是什么?

slot又名插槽,是Vue的内容分发机制,组件内部的模板引擎使用slot元素做为承载分发内容的出口。插槽slot是子组件的一个模板标签元素,而这一个标签元素是否显示,以及怎么显示是由父组件决定的。

slot又分三类,默认插槽,具名插槽和做用域插槽。

默认插槽:又名匿名查抄,当slot没有指定name属性值的时候一个默认显示插槽,一个组件内只有有一个匿名插槽。
具名插槽:带有具体名字的插槽,也就是带有name属性的slot,一个组件能够出现多个具名插槽。
做用域插槽:默认插槽、具名插槽的一个变体,能够是匿名插槽,也能够是具名插槽,该插槽的不一样点是在子组件渲染做用域插槽时,能够将子组件内部的数据传递给父组件,让父组件根据子组件的传递过来的数据决定如何渲染该插槽。
实现原理:当子组件vm实例化时,获取到父组件传入的slot标签的内容,存放在vm.$slot中,默认插槽为vm.$slot.default,具名插槽为vm.$slot.xxx,xxx 为插槽名,当组件执行渲染函数时候,遇到slot标签,使用$slot中的内容进行替换,此时能够为插槽传递数据,若存在数据,则可称该插槽为做用域插槽。

17.Vue模板渲染的原理是什么?

vue中的模板template没法被浏览器解析并渲染,由于这不属于浏览器的标准,不是正确的HTML语法,全部须要将template转化成一个JavaScript函数,这样浏览器就能够执行这一个函数并渲染出对应的HTML元素,就可让视图跑起来了,这一个转化的过程,就成为模板编译。

模板编译又分三个阶段,解析parse,优化optimize,生成generate,最终生成可执行函数render。

parse阶段:使用大量的正则表达式对template字符串进行解析,将标签、指令、属性等转化为抽象语法树AST。
optimize阶段:遍历AST,找到其中的一些静态节点并进行标记,方便在页面重渲染的时候进行diff比较时,直接跳过这一些静态节点,优化runtime的性能。
generate阶段:将最终的AST转化为render函数字符串。

18.template预编译是什么?

对于 Vue 组件来讲,模板编译只会在组件实例化的时候编译一次,生成渲染函数以后在也不会进行编译。所以,编译对组件的 runtime 是一种性能损耗。

而模板编译的目的仅仅是将template转化为render function,这个过程,正好能够在项目构建的过程当中完成,这样可让实际组件在 runtime 时直接跳过模板渲染,进而提高性能,这个在项目构建的编译template的过程,就是预编译。

19.那template和jsx的有什么分别?

对于 runtime 来讲,只须要保证组件存在 render 函数便可,而咱们有了预编译以后,咱们只须要保证构建过程当中生成 render 函数就能够。

在 webpack 中,咱们使用vue-loader编译.vue文件,内部依赖的vue-template-compiler模块,在 webpack 构建过程当中,将template预编译成 render 函数。

与 react 相似,在添加了jsx的语法糖解析器babel-plugin-transform-vue-jsx以后,就能够直接手写render函数。

因此,template和jsx的都是render的一种表现形式,不一样的是:

JSX相对于template而言,具备更高的灵活性,在复杂的组件中,更具备优点,而 template 虽然显得有些呆滞。可是 template 在代码结构上更符合视图与逻辑分离的习惯,更简单、更直观、更好维护。

20.说一下什么是Virtual DOM

Virtual DOM 是 DOM 节点在 JavaScript 中的一种抽象数据结构,之因此须要虚拟DOM,是由于浏览器中操做DOM的代价比较昂贵,频繁操做DOM会产生性能问题。虚拟DOM的做用是在每一次响应式数据发生变化引发页面重渲染时,Vue对比更新先后的虚拟DOM,匹配找出尽量少的须要更新的真实DOM,从而达到提高性能的目的。

21.介绍一下Vue中的Diff算法

在新老虚拟DOM对比时

首先,对比节点自己,判断是否为同一节点,若是不为相同节点,则删除该节点从新建立节点进行替换
若是为相同节点,进行patchVnode,判断如何对该节点的子节点进行处理,先判断一方有子节点一方没有子节点的状况(若是新的children没有子节点,将旧的子节点移除)
比较若是都有子节点,则进行updateChildren,判断如何对这些新老节点的子节点进行操做(diff核心)。
匹配时,找到相同的子节点,递归比较子节点
在diff中,只对同层的子节点进行比较,放弃跨级的节点比较,使得时间复杂从O(n^3)下降值O(n),也就是说,只有当新旧children都为多个子节点时才须要用核心的Diff算法进行同层级比较。

22.key属性的做用是什么

在对节点进行diff的过程当中,判断是否为相同节点的一个很重要的条件是key是否相等,若是是相同节点,则会尽量的复用原有的DOM节点。因此key属性是提供给框架在diff的时候使用的,而非开发者。

23.说说Vue2.0和Vue3.0有什么区别

重构响应式系统,使用Proxy替换Object.defineProperty,使用Proxy优点:
可直接监听数组类型的数据变化
监听的目标为对象自己,不须要像Object.defineProperty同样遍历每一个属性,有必定的性能提高
可拦截apply、ownKeys、has等13种方法,而Object.defineProperty不行
直接实现对象属性的新增/删除
新增Composition API,更好的逻辑复用和代码组织
重构 Virtual DOM
模板编译时的优化,将一些静态节点编译成常量
slot优化,将slot编译为lazy函数,将slot的渲染的决定权交给子组件
模板中内联事件的提取并重用(本来每次渲染都从新生成内联函数)
代码结构调整,更便于Tree shaking,使得体积更小
使用Typescript替换Flow

24.为何要新增Composition API,它能解决什么问题

Vue2.0中,随着功能的增长,组件变得愈来愈复杂,愈来愈难维护,而难以维护的根本缘由是Vue的API设计迫使开发者使用watch,computed,methods选项组织代码,而不是实际的业务逻辑。

另外Vue2.0缺乏一种较为简洁的低成本的机制来完成逻辑复用,虽然能够minxis完成逻辑复用,可是当mixin变多的时候,会使得难以找到对应的data、computed或者method来源于哪一个mixin,使得类型推断难以进行。

因此Composition API的出现,主要是也是为了解决Option API带来的问题,第一个是代码组织问题,Compostion API可让开发者根据业务逻辑组织本身的代码,让代码具有更好的可读性和可扩展性,也就是说当下一个开发者接触这一段不是他本身写的代码时,他能够更好的利用代码的组织反推出实际的业务逻辑,或者根据业务逻辑更好的理解代码。

第二个是实现代码的逻辑提取与复用,固然mixin也能够实现逻辑提取与复用,可是像前面所说的,多个mixin做用在同一个组件时,很难看出property是来源于哪一个mixin,来源不清楚,另外,多个mixin的property存在变量命名冲突的风险。而Composition API恰好解决了这两个问题。

25.都说Composition API与React Hook很像,说说区别

从React Hook的实现角度看,React Hook是根据useState调用的顺序来肯定下一次重渲染时的state是来源于哪一个useState,因此出现了如下限制

不能在循环、条件、嵌套函数中调用Hook
必须确保老是在你的React函数的顶层调用Hook
useEffect、useMemo等函数必须手动肯定依赖关系
而Composition API是基于Vue的响应式系统实现的,与React Hook的相比

声明在setup函数内,一次组件实例化只调用一次setup,而React Hook每次重渲染都须要调用Hook,使得React的GC比Vue更有压力,性能也相对于Vue来讲也较慢
Compositon API的调用不须要顾虑调用顺序,也能够在循环、条件、嵌套函数中使用
响应式系统自动实现了依赖收集,进而组件的部分的性能优化由Vue内部本身完成,而React Hook须要手动传入依赖,并且必须必须保证依赖的顺序,让useEffect、useMemo等函数正确的捕获依赖变量,不然会因为依赖不正确使得组件性能降低。
虽然Compositon API看起来比React Hook好用,可是其设计思想也是借鉴React Hook的。

26.SSR有了解吗?原理是什么?

在客户端请求服务器的时候,服务器到数据库中获取到相关的数据,而且在服务器内部将Vue组件渲染成HTML,而且将数据、HTML一并返回给客户端,这个在服务器将数据和组件转化为HTML的过程,叫作服务端渲染SSR。

而当客户端拿到服务器渲染的HTML和数据以后,因为数据已经有了,客户端不须要再一次请求数据,而只须要将数据同步到组件或者Vuex内部便可。除了数据意外,HTML也结构已经有了,客户端在渲染组件的时候,也只须要将HTML的DOM节点映射到Virtual DOM便可,不须要从新建立DOM节点,这个将数据和HTML同步的过程,又叫作客户端激活。

使用SSR的好处:

有利于SEO:其实就是有利于爬虫来爬你的页面,由于部分页面爬虫是不支持执行JavaScript的,这种不支持执行JavaScript的爬虫抓取到的非SSR的页面会是一个空的HTML页面,而有了SSR之后,这些爬虫就能够获取到完整的HTML结构的数据,进而收录到搜索引擎中。
白屏时间更短:相对于客户端渲染,服务端渲染在浏览器请求URL以后已经获得了一个带有数据的HTML文本,浏览器只须要解析HTML,直接构建DOM树就能够。而客户端渲染,须要先获得一个空的HTML页面,这个时候页面已经进入白屏,以后还须要通过加载并执行 JavaScript、请求后端服务器获取数据、JavaScript 渲染页面几个过程才能够看到最后的页面。特别是在复杂应用中,因为须要加载 JavaScript 脚本,越是复杂的应用,须要加载的 JavaScript 脚本就越多、越大,这会致使应用的首屏加载时间很是长,进而下降了体验感。

因为篇幅有限,只能分享部分面试题,更多面试题及答案能够【点击我】阅读下载哦~无偿分享给你们,算是一个感恩回馈吧

27.ajax和axios、fetch的区别?

ajax
传统 Ajax 指的是 XMLHttpRequest(XHR), 最先出现的发送后端请求技术,隶属于原始js中,核心使用XMLHttpRequest对象,多个请求之间若是有前后关系的话,就会出现回调地狱。

juery.ajax
$.ajax({
   type: 'POST',
   url: url,
   data: data,
   dataType: dataType,
   success: function () {},
   error: function () {}
});

JQuery ajax 是对原生XHR的封装,除此之外还增添了对JSONP的支持,举出几个缺点
自己是针对MVC的编程,不符合如今前端MVVM的浪潮
基于原生的XHR开发,XHR自己的架构不清晰。
JQuery整个项目太大,单纯使用ajax却要引入整个JQuery很是的不合理(采起个性化打包的方案又不能享受CDN服务)
不符合关注分离(Separation of Concerns)的原则
配置和调用方式很是混乱,并且基于事件的异步模型不友好

axios
axios({
    method: 'post',
    url: '/user/12345',
    data: {
        firstName: 'Fred',
        lastName: 'Flintstone'
    }
})
.then(function (response) {
    console.log(response);
})
.catch(function (error) {
    console.log(error);
});

axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,本质上也是对原生XHR的封装,只不过它是Promise的实现版本,符合最新的ES规范,它自己具备如下特征:
1.从浏览器中建立 XMLHttpRequest
2.支持 Promise API
3.客户端支持防止CSRF
4.提供了一些并发请求的接口(重要,方便了不少的操做)
5.从 node.js 建立 http 请求
6.拦截请求和响应
7.转换请求和响应数据
8.取消请求
9.自动转换JSON数据

fetch
try {
  let response = await fetch(url);
  let data = response.json();
  console.log(data);
} catch(e) {
  console.log("Oops, error", e);
}

fetch号称是AJAX的替代品,是在ES6出现的,使用了ES6中的promise对象。Fetch是基于promise设计的。Fetch的代码结构比起ajax简单多了,参数有点像jQuery ajax。可是,必定记住fetch不是ajax的进一步封装,而是原生js,没有使用XMLHttpRequest对象。
fetch的优势:
1.符合关注分离,没有将输入、输出和用事件来跟踪的状态混杂在一个对象里
2.更好更方便的写法
3.语法简洁,更加语义化
基于标准 Promise 实现,支持 async/await
同构方便,使用 isomorphic-fetch
4.更加底层,提供的API丰富(request, response)
5.脱离了XHR,是ES规范里新的实现方式

28.说下对 Virtual DOM 算法的理解

包括几个步骤:
一、用 JavaScript 对象结构表示 DOM 树的结构,而后用这个树构建一个真正的 DOM 树,插到文档当中;
二、当状态变动的时候,从新构造一棵新的对象树,而后用新的树和旧的树进行比较,记录两棵树差别;
三、把 2 所记录的差别应用到步骤 1 所构建的真正的 DOM 树上,视图就更新了。
Virtual DOM 本质上就是在 JS 和 DOM 之间作了一个缓存。能够类比 CPU 和硬盘,既然硬盘这么慢,咱们就在它们之间加个缓存:既然 DOM 这么慢,咱们就在它们 JS 和 DOM 之间加个缓存。CPU(JS)只操做内存(Virtual DOM),最后的时候再把变动写入硬盘(DOM)。

29.解释单向数据流和双向数据绑定

单向数据流:顾名思义,数据流是单向的。数据流动方向能够跟踪,流动单一,追查问题的时候能够更快捷。缺点就是写起来不太方便。要使 UI 发生变动就必须建立各类 action 来维护对应的 state。
双向数据绑定:数据之间是相通的,将数据变动的操做隐藏在框架内部。优势是在表单交互较多的场景下,会简化大量与业务无关的代码。缺点就是没法追踪局部状态的变化,增长了出错时 debug 的难度。

30.Vue如何去除URL中的

vue-router 默认使用 hash 模式,因此在路由加载的时候,项目中的 URL 会自带 “#”。若是不想使用 “#”, 可使用 vue-router 的另外一种模式 history:new Router ({ mode : 'history', routes: [ ]})须要注意的是,当咱们启用 history 模式的时候,因为咱们的项目是一个单页面应用,因此在路由跳转的时候,就会出现访问不到静态资源而出现 “404” 的状况,这时候就须要服务端增长一个覆盖全部状况的候选资源:若是 URL 匹配不到任何静态资源,则应该返回同一个 “index.html” 页面。

相关文章
相关标签/搜索