天天看点

vue面试题大全(持续更新)

什么是MVVM?

MVVM详解

mvvm和mvc区别?它和其它框架(jquery)的区别是什么?哪些场景适合?

mvc和mvvm其实区别并不大。都是一种设计思想。主要就是mvc中Controller演变成mvvm中的viewModel。mvvm主要解决了mvc中大量的DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验。

区别:vue数据驱动,通过数据来显示视图层而不是节点操作。

场景:数据操作比较多的场景,更加便捷

vue的优点是什么?

  • 低耦合。视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
  • 可重用性。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。
  • 独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计。
  • 可测试。界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。
  • vue两大特点:响应式编程、组件化
  • vue的优势:轻量级框架、简单易学、双向数据绑定、组件化、视图、数据和结构的分离、虚拟DOM、运行速度快

组件之间的传值?

  • 父组件与子组件传值

    父组件通过标签上面定义传值

    子组件通过props方法接受数据

  • 子组件向父组件传递数据

    子组件通过$emit方法传递参数

路由之间跳转

声明式(标签跳转) 编程式( js跳转)

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

  • 第一步:在components目录新建你的组件文件(indexPage.vue),script一定要export default {}
  • 第二步:在需要用的页面(组件)中导入:import indexPage from '@/components/indexPage.vue'
  • 第三步:注入到vue的子组件的components属性上面,components:{indexPage}
  • 第四步:在template视图view中使用,

    例如有indexPage命名,使用的时候则index-page

vue如何实现按需加载配合webpack设置

webpack中提供了require.ensure()来实现按需加载。以前引入路由是通过import 这样的方式引入,改为const定义的方式进行引入。

不进行页面按需加载引入方式:import home from '../../common/home.vue'

进行页面按需加载的引入方式:const home = r => require.ensure( [], () => r (require('../../common/home.vue')))

vuex面试相关

(1)vuex是什么?怎么使用?哪种功能场景使用它?

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

(2)vuex有哪几种属性?

有五种,分别是 State、 Getter、Mutation 、Action、 Module

  • vuex的State特性

    A、Vuex就是一个仓库,仓库里面放了很多对象。其中state就是数据源存放地,对应于一般Vue对象里面的data

    B、state里面存放的数据是响应式的,Vue组件从store中读取数据,若是store中的数据发生改变,依赖这个数据的组件也会发生更新

    C、它通过mapState把全局的 state 和 getters 映射到当前组件的 computed 计算属性中

  • vuex的Getter特性

    A、getters 可以对State进行计算操作,它就是Store的计算属性

    B、 虽然在组件内也可以做计算属性,但是getters 可以在多组件之间复用

    C、 如果一个状态只在一个组件内使用,是可以不用getters

  • vuex的Mutation特性

    Action 类似于 mutation,不同在于:Action 提交的是 mutation,而不是直接变更状态;Action 可以包含任意异步操作。

(3)不用Vuex会带来什么问题?

  1. 可维护性会下降,想修改数据要维护三个地方;
  2. 可读性会下降,因为一个组件里的数据,根本就看不出来是从哪来的;
  3. 增加耦合,大量的上传派发,会让耦合性大大增加,本来Vue用Component就是为了减少耦合,现在这么用,和组件化的初衷相背。

 v-show和v-if指令的共同点和不同点

  1. v-show指令是通过修改元素的display的CSS属性让其显示或者隐藏
  2. v-if指令是直接销毁和重建DOM达到让元素显示和隐藏的效果

如何让CSS只在当前组件中起作用

         将当前组件的<style>修改为<style scoped>

的作用是什么?

<keep-alive></keep-alive> 包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染。

Vue中引入组件的步骤?

1)采用ES6的import ... from ...语法或CommonJS的require()方法引入组件

2)对组件进行注册,代码如下

// 注册
Vue.component('my-component', {
  template: '<div>A custom component!</div>'
})      

3)使用组件​

​<my-component></my-component>​

指令v-el的作用是什么?

提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标.可以是 CSS 选择器,也可以是一个 HTMLElement 实例

在Vue中使用插件的步骤

  1. 采用ES6的import ... from ...语法或CommonJS的require()方法引入插件
  2. 使用全局方法Vue.use( plugin )使用插件,可以传入一个选项对象Vue.use(MyPlugin, { someOption: true })

请列举出3个Vue中常用的生命周期钩子函数

  1. created: 实例已经创建完成之后调用,在这一步,实例已经完成数据观测, 属性和方法的运算, watch/event事件回调. 然而, 挂载阶段还没有开始, $el属性目前还不可见
  2. mounted: el被新创建的 vm.el 也在文档内。
  3. activated: keep-alive组件激活时调用

active-class是哪个组件的属性?

vue-router模块的router-link组件。

怎么定义vue-router的动态路由以及如何获取传过来的动态参数?

在router目录下的index.js文件中,对path属性加上/:id。

        使用router对象的params.id。

vue-router有哪几种导航钩子?

三种,一种是全局导航钩子:router.beforeEach(to,from,next),作用:跳转前进行判断拦截。

        第二种:组件内的钩子;

        第三种:单独路由独享组件

生命周期相关面试题

总共分为8个阶段创建前/后,载入前/后,更新前/后,销毁前/后。

  • 创建前/后: 在beforeCreate阶段,vue实例的挂载元素el和数据对象data都为undefined,还未初始化。在created阶段,vue实例的数据对象data有了,el还没有。
  • 载入前/后:在beforeMount阶段,vue实例的$el和data都初始化了,但还是挂载之前为虚拟的dom节点,data.message还未替换。在mounted阶段,vue实例挂载完成,data.message成功渲染。
  • 更新前/后:当data变化时,会触发beforeUpdate和updated方法。
  • 销毁前/后:在执行destroy方法后,对data的改变不会再触发周期函数,说明此时vue实例已经解除了事件监听以及和dom的绑定,但是dom结构依然存在

(1)、什么是vue生命周期

答: Vue 实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。

(2)、vue生命周期的作用是什么

答:它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑。

(3)、vue生命周期总共有几个阶段

答:可以总共分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/销毁后

(4)、第一次页面加载会触发哪几个钩子

答:第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩子

(5)、DOM 渲染在 哪个周期中就已经完成

答:DOM 渲染在 mounted 中就已经完成了。

(6)、简单描述每个周期具体适合哪些场景

答:生命周期钩子的一些使用方法:

  1. beforecreate : 可以在这加个loading事件,在加载实例时触发
  2. created : 初始化完成时的事件写在这里,如在这结束loading事件,异步请求也适宜在这里调用
  3. mounted : 挂载元素,获取到DOM节点
  4. updated : 如果对数据统一处理,在这里写上相应函数
  5. beforeDestroy : 可以做一个确认停止事件的确认框
  6. nextTick : 更新数据后立即操作dom

说出至少4种vue当中的指令和它的用法?

v-if:判断是否隐藏;v-for:数据循环;v-bind:class:绑定一个属性;v-model:实现双向绑定

vue-loader是什么?使用它的用途有哪些?

        解析.vue文件的一个加载器。

        用途:js可以写es6、style样式可以scss或less、template可以加jade等

scss是什么?在vue.cli中的安装使用步骤是?有哪几大特性?

答:css的预编译。

使用步骤:

第一步:先装css-loader、node-loader、sass-loader等加载器模块

第二步:在build目录找到webpack.base.config.js,在那个extends属性中加一个拓展.scss

第三步:在同一个文件,配置一个module属性

第四步:然后在组件的style标签加上lang属性 ,例如:lang=”scss”

特性:

  1. 可以用变量,例如($变量名称=值);
  2. 可以用混合器,例如()
  3. 可以嵌套

为什么使用key?

当有相同标签名的元素切换时,需要通过 key 特性设置唯一的值来标记以让 Vue 区分它们,否则 Vue 为了效率只会替换相同标签内部的内容。

二十四、为什么避免 v-if 和 v-for 用在一起

当 Vue 处理指令时,v-for 比 v-if 具有更高的优先级,通过v-if 移动到容器元素,不会再重复遍历列表中的每个值。取而代之的是,我们只检查它一次,且不会在 v-if 为否的时候运算 v-for。

二十五、VNode是什么?虚拟 DOM是什么?

Vue在 页面上渲染的节点,及其子节点称为“虚拟节点 (Virtual Node)”,简写为“VNode”。“虚拟 DOM”是由 Vue 组件树建立起来的整个 VNode 树的称呼。

对vue的理解

Vue是一套用于构建用户界面的渐进式框架,轻量级,没有强主张(主张性少), 也能完美地驱动复杂的单页应用。vue.js在设计上也使用 mvvm模式。

渐进式框架个人理解:不做职责之外的事情。

Vue的生命周期

创建:

beforeCreate(创建前) 在数据观测和初始化事件还未开始

created(创建后) 完成数据观测,属性和方法的运算,初始化事件,el属性还没有显示出来。挂载:beforeMount(载入前)在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。注意此时还没有挂载html到页面上。mounted(载入后)在el被新创建的vm. el属性还没有显示出来。挂载:beforeMount(载入前) 在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。注意此时还没有挂载html到页面上。mounted(载入后) 在el 被新创建的 vm.el属性还没有显示出来。挂载:beforeMount(载入前)在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。注意此时还没有挂载html到页面上。mounted(载入后)在el被新创建的vm.el 替换,并挂载到实例上去之后调用。实例已完成以下的配置:用上面编译好的html内容替换el属性指向的DOM对象。完成模板中的html渲染到html页面中。此过程中进行ajax交互。

修改:

beforeUpdate(更新前) 在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程。

updated(更新后) 在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用。

销毁:

beforeDestroy(销毁前) 在实例销毁之前调用。实例仍然完全可用。

destroyed(销毁后) 在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。

1.什么是vue生命周期?

答: Vue 实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、销毁等一系列过程,称之为 Vue 的生命周期。

2.vue生命周期的作用是什么?

答:它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑。

3.vue生命周期总共有几个阶段?

答:它可以总共分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/销毁后。

4.第一次页面加载会触发哪几个钩子?

答:会触发 下面这几个beforeCreate, created, beforeMount, mounted 。

5.DOM 渲染在 哪个周期中就已经完成?

答:DOM 渲染在 mounted 中就已经完成了。

四.Vue实现双向数据绑定的原理

vue实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。

vue的数据双向绑定 将MVVM作为数据绑定的入口,整合Observer,Compile和Watcher三者,通过Observer来监听自己的model的数据变化,通过Compile来解析编译模板指令(vue中是用来解析 {{}}),最终利用watcher搭起observer和Compile之间的通信桥梁,达到数据变化 —>视图更新;视图交互变化(input)—>数据model变更双向绑定效果。

对 MVC、MVP 、MVVM 的理解

MVC 模式的意思是,软件可以分成三个部分。

视图(View):用户界面。

控制器(Controller):业务逻辑。

模型(Model):数据保存。

各部分之间的通信方式如下。View 传送指令到 Controller,Controller 完成业务逻辑后,要求 Model 改变状态,Model 将新的数据发送到 View,用户得到反馈,所有通信都是单向的(逆时针)。

MVP 模式将 Controller 改名为 Presenter,同时改变了通信方向。各部分之间的通信,都是双向的(顺时针)。View 与 Model 不发生联系,都通过 Presenter 传递。View 非常薄,不部署任何业务逻辑,称为 “被动视图”(Passive View),即没有任何主动性,而 Presenter非常厚,所有逻辑都部署在那里。MVVM 模式将 Presenter 改名为 ViewModel,基本上与 MVP 模式完全一致。唯一的区别是,它采用双向绑定(data-binding):View 的变动,自动反映在 ViewModel,反之亦然。Angular 和 Ember 都采用这种模式。

如何理解 Vue 是异步执行 DOM 更新的 ?

Vue 是异步执行 DOM 更新。只要观察到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据改变。如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作上非常重要。然后,在下一个的事件循环 tick 中,Vue 刷新队列并执行实际 (已去重的) 工作。Vue 在内部尝试对异步队列使用原生的 Promise.then 和 MessageChannel,如果执行环境不支持,会采用 setTimeout(fn, 0) 代替。例如,当你设置 vm.someData = ‘new value’ ,该组件不会立即重新渲染。

当刷新队列时,组件会在事件循环队列清空时的下一个 tick 更新。多数情况我们不需要关心这个过程,但是如果你想在 DOM 状态更新后做点什么,这就可能会有些棘手。虽然 Vue.js 通常鼓励开发人员沿着 “数据驱动” 的方式思考,避免直接接触 DOM,但是有时我们确实要这么做。为了在数据变化之后等待 Vue 完成更新 DOM ,可以在数据变化之后立即使用 Vue.nextTick(callback) 。这样回调函数在 DOM 更新完成后就会调用。

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

v-if用于操作Dom是否渲染,而v-if操作的则是display属性,v-if的有更高的切换开销,v-show有更大的初始渲染开销,所以,如果需要频繁切换,使用v-show比较好,而如果渲染条件改变次数少,则v-if更好

计算属性和watch的区别及使用场景

computed计算属性是用来声明式的描述一个值依赖了其它的值。当你在模板里把数据绑定到一个计算属性上时,Vue 会在其依赖的任何值导致该计算属性改变时更新 DOM。这个功能非常强大,它可以让你的代码更加声明式、数据驱动并且易于维护。 // 计算属性computed,计算的是Name依赖的值,它不能计算在data中已经定义过的变量。

watch监听的是你定义的变量,当你定义的变量的值发生变化时,调用对应的方法。// 当num的值发生变化时,就会调用num的方法,方法里面的形参对应的是num的新值和旧值

  • 一个数据属性在它所依赖的属性发生变化时,也要发生变化,这种情况下,我们最好使用计算属性。
  • watch函数适用于,当数据发生变化时,执行异步操作或较大开销操作的情况。

双向绑定 – Object.defineProperty()

vue实现数据双向绑定主要是:

采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty() 来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty() 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue追踪依赖,在属性被访问和修改时通知变化。

vue路由hash模式与history模式的区别

  • hash模式
  • 路由的哈希模式其实是利用了window可以监听onhashchange事件,也就是说你的url中的哈希值(#后面的值)如果有变化,前端是可以做到监听并做一些响应(搞点事情),这么一来,即使前端并没有发起http请求他也能够找到对应页面的代码块进行按需加载。

    后来人们给他起了一个霸气的名字叫前端路由,成为了单页应用标配。

  • history模式
  • 我们先介绍一下H5新推出的两个神器:pushState与replaceState

    具体自行百度,简而言之,这两个神器的作用就是可以将url替换并且不刷新页面,好比挂羊头卖狗肉,http并没有去请求服务器该路径下的资源,一旦刷新就会暴露这个实际不存在的“羊头”,显示404。

那么如何去解决history模式下刷新报404的弊端呢,这就需要服务器端做点手脚,将不存在的路径请求重定向到入口文件(index.html),前后端联手,齐心协力做好“挂羊头卖狗肉”的完美特效。

总之,pushState方法不会触发页面刷新,只是导致history对象发生变化,地址栏会有反应。

history模式下,build之后本地 index.html 打开是无效的。

hash模式下,build之后本地 index.html 打开正常!

大牛回答:hash模式url里面永远带着#号,我们在开发当中默认使用这个模式。那么什么时候要用history模式呢?如果用户考虑url的规范那么就需要使用history模式,因为history模式没有#号,是个正常的url适合推广宣传。当然其功能也有区别,比如我们在开发app的时候有分享页面,那么这个分享出去的页面就是用vue或是react做的,咱们把这个页面分享到第三方的app里,有的app里面url是不允许带有#号的,所以要将#号去除那么就要使用history模式,但是使用history模式还有一个问题就是,在访问二级页面的时候,做刷新操作,会出现404错误,那么就需要和后端人员配合让他配置一下apache或是nginx的url重定向,重定向到你的首页路由上就ok啦。

$route 和 $router的区别

  • $route是“路由信息对象”,包括path,params,hash,query,fullPath,matched,name等路由信息参数。
  • 而$router是“路由实例”对象包括了路由的跳转方法,钩子函数等

路由跳转

  • 编程式( js跳转)this.$router.push()
  • 声明式(标签跳转)​

    ​<router-link to=""></router-link>​

路由的懒加载

import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

const routes = [ 
  {
  path:'/',
  component:resolve => require(['@/components/First'],resolve)
  }, 
  {
  path:'/first', 
  component:resolve => require(['@/components/First'],resolve)
  },
  {
  path:'/second',
  component: resolve => require(['@/components/Second'],resolve)
  }
 ] 
 //最后创建router 对路由进行管理,它是由构造函数 new vueRouter() 创建,接受routes 参数。 
  const router = new VueRouter({ 
  routes 
 }) 
   
 export default router;      

按需加载会在页面第一次请求的时候,把相关路由组件块的js添加上;非按需加载则会把所有的路由组件块的js包打在一起。当业务包很大的时候建议用路由的按需加载(懒加载)。

vue-router解决的问题

  • 监听URL的变化,并在变化前后执行相应的逻辑
  • 不同的URL对应不同的组件
  • 提供多种方式改变URL的API(URL的改变不能导致浏览器刷新)

v-if 和 v-show 的区别

  • v-if按照条件是否渲染,v-show是display的block或none;
  • v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

在Vue中使用插件的步骤

  • 采用ES6的import … from …语法或CommonJS的require()方法引入插件
  • 使用全局方法Vue.use( plugin )使用插件,可以传入一个选项对象Vue.use(MyPlugin, { someOption: true })

vue-cli 工程技术集合介绍

使用技术

  • vue.js:vue-cli工程的核心,主要特点是 双向数据绑定 和 组件系统。
  • vue-router:vue官方推荐使用的路由框架。
  • vuex:专为 Vue.js 应用项目开发的状态管理器,主要用于维护vue组件间共用的一些 变量 和 方法。
  • axios( 或者 fetch 、ajax ):用于发起 GET 、或 POST 等 http请求,基于 Promise 设计。
  • vuex等:一个专为vue设计的移动端UI组件库。
  • 创建一个emit.js文件,用于vue事件机制的管理。
  • webpack:模块加载和vue-cli工程打包器。

vue-cli配置反向代理

vue-cli提供了配置反向代理的接口,即设置config/index.js中的proxyTable。配置如下:

dev: {
    ......
    
    proxyTable: {
      '/api':{     //将www.exaple.com印射为/apis
        target:'https://www.exaple.com',     //跨域地址
        changeOrigin:true,       //是否跨域
        secure:false,        //是否使用https
        pathRewrite: {
          '^/api': '/api'       //匹配以/api为开头的请求地址,并使用/api替换
        }
      }
    }
}      

对反向代理解决跨域过程的理解

通过伪造请求使得http请求为同源的,然后将同源的请求发送到反向代理服务器上,由反向代理服务器去请求真正的url,这样就绕过直接请求真正的url导致跨域问题。

Vue 组件 data 为什么必须是函数

  • 每个组件都是 Vue 的实例。
  • 组件共享 data 属性,当 data 的值是同一个引用类型的值时,改变其中一个会影响其他

v-if和v-for可以一起使用吗?为什么?

可以是可以,但是不推荐,一起使用会导致性能上的下降;因为v-for比v-if具有更高的权重,所以会先解析v-for,然后在进行v-if判断,这就导致每一次循环迭代都要进行一次判断;解决方案:可以在父元素进行v-if判断,或者使用计算属性将数组进行过滤。

在页面来回切换之间,怎么让页面不重复发生网络请求?

可以使用keep-alive标签包裹在router-view路由出口里

指令keep-alive

在vue-router写着keep-alive,keep-alive的含义:

如果把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染。为此可以添加一个keep-alive指令

<component :is='curremtView' keep-alive></component>

Vue.js特点

简洁:页面由HTML模板+Json数据+Vue实例组成

数据驱动:自动计算属性和追踪依赖的模板表达式

组件化:用可复用、解耦的组件来构造页面

轻量:代码量小,不依赖其他库

快速:精确有效批量DOM更新

vue-router 有哪几种导航钩子?

全局导航钩子

router.beforeEach(to, from, next),

router.beforeResolve(to, from, next),

router.afterEach(to, from ,next)

组件内钩子

beforeRouteEnter,

beforeRouteUpdate,

beforeRouteLeave

单独路由独享组件

beforeEnter

 vuex 的mutation和action的特性是什么?有什么区别?

mutation用于修改state的数据,是同步的。

action 类似于 muation, 不同在于:action 提交的是 mutation,而不是直接变更状态

action 可以包含任意异步操作

computed 和 watched 的区别:

computed 是计算属性,依赖其他属性计算值,并且 computed 的值有缓存,只有当计算值变化才会返回内容。

watch 监听到值的变化就会执行回调,在回调中可以进行一些逻辑操作。

所以一般来说需要依赖别的属性来动态获得值的时候可以使用 computed,对于监听到值的变化需要做一些复杂业务逻辑的情况可以使用 watch。