1、虚拟DOM中key的作用:

​ key是虚拟DOM对象的标识,当状态中的数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】,随后Vue进行【新虚拟DOM】的差异比较,比较规则如下:

2、key的对比规则:

​ 1、旧虚拟DOM中找到了与新虚拟DOM相同的key:

  • 若虚拟DOM中内容没变,直接使用之前的真实DOM
  • 若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM

​ 2、旧虚拟DOM中未找到与新虚拟DOM相同的key

  • 创建新的真实DOM,随后渲染到页面

3、用index作为key可能会引发的问题:

​ 1、若对数据进行:逆序添加、逆序删除等破坏顺序操作:会产生没有必要的真实DOM更新 ===> 界面效果没问底,但效率低

​ 2、如果结构中还包含输入类的DOM:会产生错误DOM更新 ===> 界面有问题

4、开发中如何选择key?

​ 1、最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值

​ 2、如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key是没有问题的

5、Vue 组件中 data 为什么必须是函数?

​ 保证组件的独立性和可复用性,data是一个函数,组件实例化的时候将会调用这个函数,返回一个对象,计算机会给这个对象分配一个内存地址,你实例化几次,就分配几个内存地址,他们的地址都不一样,所以每个组件中的数据不会相互干扰,改变其中一个组件的状态,其它组件不变。

6、vuex的State特性是?

​ state属性是Vuex中用于存放组件之间共享的数据;也就是说,我们把一些组件之间共享的状态主要存放在state属性中;它采用的是单一状态树——用一个对象就包含了全部的应用层级状态。这也意味着,每个应用将仅仅包含一个 store 实例。单一状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。

7、Vue声明组件的state是⽤data⽅法,那为什么data是通过⼀个function来返回⼀个对象,⽽不是直接写⼀个对象呢?
​ 从语法上说,如果不⽤function返回就会出现语法错误导致编译不通过。从原理上的话,⼤概就是组件可以被多次创建,如果不使⽤function就会使所有调⽤该组件的页⾯公⽤同⼀个数据域,这样就失去了组件的概念了

8、介绍一下Vue的响应式系统

​ 1、任何一个 Vue Component 都有一个与之对应的 Watcher 实例

​ 2、Vue 的 data 上的属性会被添加 getter 和 setter 属性

​ 3、当 Vue Component render 函数被执行的时候, data 上会被 触碰(touch), 即被读, getter 方法会被调用, 此时 Vue 会去记录此 Vue component 所依赖的所有 data。(这一过程被称为依赖收集)

​ 4、data 被改动时(主要是用户操作), 即被写, setter 方法会被调用, 此时 Vue 会去通知所有依赖于此 data 的组件去调用他们的 render 函数进行更新

9、computed与watch的区别

  • 1、computed擅长处理的场景:一个数据受多个数据影响;watch擅长处理的场景:一个数据影响多个数据。
  • 2、功能上:computed是计算属性,watch是监听一个值的变化,然后执行对应的回调。
  • 3、是否调用缓存:computed支持缓存,只有依赖数据发生改变,才会重新进行计算;而watch不支持缓存,数据变,直接会触发相应的操作。
  • 4、是否调用return:computed中的函数必须要用return返回,watch中的函数不是必须要用return。
  • 5、computed不支持异步 ,当computed内有异步操作时无效,无法监听数据的变化;而watch支持异步。
  • 6、computed默认第一次加载的时候就开始监听;watch默认第一次加载不做监听,如果需要第一次加载做监听,添加immediate属性,设置为true(immediate:true)

10、介绍一下Vue的生命周期

​ 每一个vue实例从创建到销毁的过程,就是这个vue实例的生命周期。在这个过程中,他经历了从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、卸载等一系列过程。

  • 将要创建 ===>调用beforeCreate函数
  • 创建完毕 ===>调用created函数
  • 将要挂载 ===>调用beforeMount函数
  • 挂载完毕 ===>调用mounted函数
  • 将要更新 ===>调用beforeUpdate函数
  • 更新完毕 ===>调用updated函数
  • 将要销毁 ===>调用beforeDestory函数
  • 销毁完毕 ===>调用destroyed函数

11、vue生命周期的作用是什么?
Vue生命周期中有多个事件钩子,让我们在控制整个Vue实例过程时更容易形成好的逻辑。

12、第一次页面加载会触发哪几个钩子?
第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩子
13、DOM 渲染在 哪个周期中就已经完成?
DOM 渲染在 mounted 中就已经完成了。

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

  • beforeCreate : 可以在这加个loading事件,在加载实例时触发
  • created : 初始化完成时的事件写在这⾥,如在这结束loading事件,异步请求也适宜在这⾥调⽤
  • mounted : 挂载元素,获取到DOM节点
  • updated : 如果对数据统⼀处理,在这⾥写上相应函数
  • beforeDestroy : 可以做⼀个确认停⽌事件的确认框
  • nextTick : 更新数据后⽴即操作dom

15、组件之间是怎么通信的

组件之间通信主要分为三种:父子传参,子父传参,兄弟传参。

  1. 父子传参:父组件通过自定义属性的方式传参,通过props属性给子组件传参,子组件通过props属性去接收参数。
  2. 子父传参:子组件通过自定义事件的方式传参,通过$emit去进行传参。

16、Vue.cli中怎样使用自定义的组件?

  1. 在 components 目录新建组件文件
  2. 在需要用到的页面import中导入
  3. 使用component注册
  4. 在 template 视图中使用组件标签

17、Vue如何实现按需加载配合webpack设置

  • webpack中提供了require.ensure( )来实现按需加载。以前引入路由是通过import这样的方式引入,改为const定义方式进行引入。
  • 不进行页面按需加载引入方式 import home from ../../common/home.vue
  • 进行页面按需加载的引入方式:const home = r =>require.ensure([],() =>require(‘../../common/home.vue)))

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

css的预编译语言。

使用步骤:

  • 第一步:先装css-loadernode-loadersass-loader等加载器模块;
  • 第二步:在build目录找到webpack.base.config.js,在extends属性中加一个拓展.scss
  • 第三步:在同一个文件,配置一个module属性;
  • 第四步:然后在组件的style标签加上lang属性 ,例如:lang=”scss”

特性:

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

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

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

20、聊聊你对Vue.js的template编译的理解?

​ 简⽽⾔之,就是先转化成AST树,再得到的render函数返回VNode(Vue的虚拟DOM节点)
详情步骤:
​ ⾸先,通过compile编译器把template编译成AST语法树(abstract syntax tree 即 源代码的抽象语法结构的树状表现形式),compile是createCompiler的返回值,createCompiler是⽤以创建编译器的。另外compile还负责合并option。
​ 然后,AST会经过generate(将AST语法树转化成render funtion字符串的过程)得到render函数,render的返回值是VNode,VNode是Vue的虚拟DOM节点,⾥⾯有(标签名、⼦节点、⽂本等等)

21、Vue 路由跳转的几种方式

  • 第一种方式:router-link (声明式路由)
  • 第二种方式:router.push(编程式路由)
  • 第三种方式:this.$router.push() (函数里面调用)
  • 第四种方式:this.$router.replace() (用法同上,push)
  • 第五种方式:this.$router.go(n)

22、Vue的路由实现:hash模式和history模式

hash 模式 (默认)

  • 工作原理: 监听网页的hash值变化 —> onhashchange事件, 获取location.hash
  • 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。
  • 会给用户好像跳转了网页一样的感觉, 但是实际上没有跳转
  • 主要用在页面应用(SPA)

history 模式

  • 工作原理: 主要利用 history.pushState() API 来改变URL, 而不刷新页面.
  • 其实一共有五种模式可以实现改变URL, 而不刷新页面.
  • 需要后台配置支持, 如果输入一个并不存在的url, 需要后端配置做 “兜底配置”, 不是粗暴的返回404, 而是返回首页

23、Vue与Angular以及React的区别?

基本概念

  • Angular 是一个应用设计框架与开发平台,用于创建高效、复杂、精致的单页面应用。
  • React 是一个用于构建用户界面的 JavaScript 库
  • Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

三者比较
​ 相同点

  • 1.都是基于javascript/typescript的前端开发库,为前端开发提供高效、复用性高的开发方式
  • 2.都有组件和模板的开发思想
  • 3.各自的组件都有生命周期,不用的组件可以卸载,不占用资源
  • 4.都支持指令,如样式、事件等的指令

​ 不同点

  • 1.创始和发行不同:Angular是由googl提供支持的,初始发行于 2016年9月;React由Facebook维护,初始发行于 2013年3月;Vue是由前google人员创建,初始发行于2014年2月
  • 2.应用类型不同:Angular支持开发native应用程序、SPA单页应用程序、混合应用程序和web应用程序;React支持开发SPA和移动应用程序;Vue支持开发高级SPA,开始支持native应用程序
  • 3.模型不同:angular基于MVC(模型-视图-控制器)架构;react和vue是基于Virtual DOM(虚拟的文档对象模型)
  • 4、数据流流向不同:Angular使用的是双向数据绑定,React用的是单数据流的,而Vue则支持两者。
  • \5. 对微应用和微服务的支持不同:Angular使用的是TypeScript,因此它更适合于单页Web应用(single page web application,SPA),而非微服务。相反,React和Vue的灵活性更适合微应用和微服务的开发。
  • \6. 对原生应用的支持不同: React Native为iOS和Android开发原生应用;Angular的NativeScript已被原生应用所采用,特别是Ionic框架已经被广泛地运用在制作混合应用等方面;Vue的Weex平台正在开发之中,尚无下一步使之成为全面跨平台的计划。
  • \7. 框架和库:Angular 是一个框架而不是一个库,因为它提供了关于如何构建应用程序的强有力的约束,并且还提供了更多开箱即用的功能。React 和 Vue 是是一种库,可以和各种包搭配。
  • \8. 组件之间传值方式不同:Angular 中直接的父子组件,父组件可以直接访问子组件的 public 属性和方法,也可以借助于@Input 和 @Output 进行通讯。没有直接关系的,借助于 Service 单例进行通讯;React 组件之间通过通过prop或者state来通信,不同组件之间还有Rex状态管理功能;Vue组件之间通信通过props ,以及Vuex状态管理来传值

24、vue-router中导航守卫有哪些?

​ 全局前置守卫、路由独享守卫、组件内守卫

25、 为什么使用Vue?

  • 优点:轻量级的框架、双向数据绑定、组件化开发、单页面路由、学习成本低、虚拟dom、渐进式框架、数据和结构的分离、运行速度快、插件化
  • 缺点:不支持ie8以下、社区没有angular和react丰富、缺乏高阶教程和文档、单页面应用不利用seo优化、首次加载时耗时多

26、说出至少 4 种 vue 指令和它的用法?

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

27、v-if和v-show的区别

  • v-if通过控制dom节点的方式,添加和删除元素,进而实现显示或隐藏元素,v-show通过设置dom元素的display来实现显示或隐藏的操作,并不会删除dom
  • v-if隐藏会将组件销毁,显示时会将其内部的监听事件重建,v-show只是设置display,并不会阻止子组件内部的监听事件
  • v-if有着更高的切换消耗,v-show有着更高的初始渲染消耗

28、为什么避免 v-if 和 v-for 一起用?

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

29、什么是 MVVM ?

  • MVVMModel-View-ViewModel的缩写。MVVM是一种设计思想。Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View 代表UI 组件,它负责将数据模型转化成UI 展现出来,ViewModel 是一个同步ViewModel的对象。
  • MVVM架构下,ViewModel 之间并没有直接的联系,而是通过ViewModel进行交互,ModelViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
  • ViewModel 通过双向数据绑定把 View 层和 Model 层连接起来,而ViewModel 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。

30、vuex是什么?怎么使用?哪种功能场景使用它?

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

31、vuex有哪几种属性?

有五种,分别是 StateGetterMutationActionModule

32、vuex的State特性

  • Vuex就是一个仓库,仓库里面放了很多对象。其中state就是数据源存放地,对应于一般Vue对象里面的data
  • state里面存放的数据是响应式的,Vue组件从store中读取数据,若是store中的数据发生改变,依赖这个数据的组件也会发生更新。
  • 通过mapState和mapGetters把全局 stategetters 映射到当前组件的 computed 计算属性中。

33、vuex的Getter特性

  • getters 可以对State进行计算操作,它就是Store的计算属性。
  • 虽然在组件内也可以做计算属性,但是getters 可以在多组件之间复用。
  • 如果一个状态只在一个组件内使用,可以不用getters

34、vuex的Mutation特性

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

35、不用Vuex会带来什么问题?

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

36、keep-alive 的作用是什么?

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

37、vue-loader 是什么?用途有哪些?

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

用途:js 可以写es6style样式可以scsslesstemplate可以加jade等。

38、如何获取dom
​ 在我们的vue项⽬中,难免会因为引⽤第三⽅库⽽需要操作DOM标签,vue为我们提供了ref属性。 ref 被⽤来给元素或⼦组件注册引⽤信息。引⽤信息将会注册在⽗组件的 $refs 对象上。如果在普通的 DOM 元素上使⽤,引⽤指向的就是 DOM 元素;如果⽤在⼦组件上,引⽤就指向组件实例

39、iframe的优缺点?

​ iframe也称作嵌⼊式框架,嵌⼊式框架和框架⽹页类似,它可以把⼀个⽹页的框架和内容嵌⼊在现有的⽹页中。
​ 优点:

  • 解决加载缓慢的第三⽅内容如图标和⼴告等的加载问题
  • Security sandbox
  • 并⾏加载脚本
  • ⽅便制作导航栏

​ 缺点:

  • iframe会阻塞主页⾯的Onload事件
  • 即使内容为空,加载也需要时间
  • 没有语意

40、请说出vue.cli项⽬中src⽬录每个⽂件夹和⽂件的⽤法?
​ assets⽂件夹是放静态资源;components是放组件;router是定义路由相关的配置;view视图;app.vue是⼀个应⽤主组件;main.js是⼊⼝⽂件
41、vue常⽤的修饰符

  • .stop:等统⼀JavaScript中的event.stopPropagation(),防⽌事件冒泡
  • .prevent:等同于JavaScript中的event。preventDefault(),防⽌执⾏预设的⾏为(如果事件可取消,则取消该事件,⽽不停⽌事件的进⼀步
  • 传播);
  • .capture:与事件冒泡的⽅向相反,事件捕获由外到内
  • .self:只会触发⾃⼰范围内的事件,不包含⼦元素;
  • .once:只会触发⼀次。

42、⾃定义指令(v-check、v-focus)的⽅法有哪些?它有哪些钩⼦函数?还有哪些钩⼦函数参数?

  • 全局定义指令:在vue对象的directive⽅法⾥⾯有两个参数,⼀个是指令名称,另外⼀个是函数。组件内定义指令:directives
  • 钩⼦函数:bind(绑定事件触发)、inserted(节点插⼊的时候触发)、update(组件内相关更新)
  • 钩⼦函数参数:el、binding

43、vue的两个核⼼点
数据驱动,组件系统

  • 数据驱动:ViewModel,保证数据和视图的⼀致性
  • 组件系统:应⽤类UI可以看做全部是由组件树构成的

44、delete和Vue.delete删除数组的区别

  • delete只是被删除的元素变成了empty/undefined其他的元素的键值还是不变。
  • Vue.delete直接删除了数组 改变了数组的键值

45、Vue-router跳转和location.href有什么区别
​ 使⽤location.href=/url 来跳转,简单⽅便,但是刷新了页⾯;使⽤history.pushState(/url),⽆刷新页⾯,静态跳转;引进router,然后使⽤router.push(/url)来跳转,使⽤了diff算法,实现了按需加载,减少了dom的消耗。其实使⽤router跳转和使⽤history.pushState()没什么差别,因为vue-router就是⽤了history.pushState(),尤其是在history模式下。
46、RouterLink在IE和Firefox中不起作⽤(路由不跳转)的问题
​ ⽅法⼀
​ 只⽤a标签,不使⽤button标签
​ ⽅法⼆
​ 使⽤button标签和Router.navigate⽅法
47、请说下封装 vue 组件的过程?
​ ⾸先,组件可以提升整个项⽬的开发效率。能够把页⾯抽象成多个相对独⽴的模块,解决了我们传统项⽬开发:效率低、难维护、复⽤性等问题。
​ 然后,使⽤Vue.extend⽅法创建⼀个组件,然后使⽤Vue.component⽅法注册组件。⼦组件需要数据,可以在props中接受定义。⽽⼦组件修改好数据后,想把数据传递给⽗组件。可以采⽤emit⽅法。
48、params和query的区别
​ ⽤法:query要⽤path来引⼊,params要⽤name来引⼊,接收参数都是类似的,分别是this. $router.query.name 和 this.$router.params.name。url地址显⽰:query更加类似于我们ajax中get传参,params则类似于post,说的再简单⼀点,前者在浏览器地址栏中显⽰参数,后者则不显⽰
​ 注意点:query刷新不会丢失query⾥⾯的数据params刷新会丢失params⾥⾯的数据
49、vue mock数据
​ 在项⽬中尝试了mockjs,mock数据,实现前后端分离开发。
​ 关于mockjs,官⽹描述的是

  • 1.前后端分离
  • 2.不需要修改既有代码,就可以拦截 Ajax 请求,返回模拟的响应数据。
  • 3.数据类型丰富
  • 4.通过随机数据,模拟各种场景。

​ 总结:在后端接⼝没有开发完成之前,前端可以⽤已有的接⼝⽂档,在真实的请求上拦截ajax,并根据mockjs的mock数据的规则,模拟真实接⼝返回的数据,并将随机的模拟数据返回参与相应的数据交互处理,这样真正实现了前后台的分离开发。
​ 与以往的⾃⼰模拟的假数据不同,mockjs可以带给我们的是:在后台接⼝未开发完成之前模拟数据,并返回,完成前台的交互;在后台数据完成之后,你所做的只是去掉mockjs:停⽌拦截真实的ajax,仅此⽽已。
50、vue初始化页⾯闪动问题
​ 使⽤vue开发时,在vue初始化之前,由于div是不会vue管的,所以我们写的代码在还没有解析的情况下会容易出现花屏现象,看到类似于的字样,虽然⼀般情况下这个时间很短暂,但是我们还是有必要解决这个问题的。
​ ⾸先:在css⾥加上[v-cloak]{display:none;},如果没有彻底解决问题,则在根元素加上style=“display:none;” :style=”{display:block}”
51、vue更新数组时触发视图更新的⽅法
push();pop();shift();unshift();splice();sort();reverse()
52、vue常⽤的UI组件库
Mint UI,element,VUX
53、mint-ui是什么?怎么使⽤?说出⾄少三个组件使⽤⽅法?
​ 基于vue的前端组件库。
​ npm安装,然后import样式和js,vue.use(mintUi)全局引⼊。在单个组件局部引⼊:import {Toast} from ‘mint-ui’。

  • 组件⼀:Toast(‘登录成功’);
  • 组件⼆:mint-header;
  • 组件三:mint-swiper

54、Vue⾥⾯router-link在电脑上有⽤,在安卓上没反应怎么解决?
​ Vue路由在Android机上有问题,babel问题,安装babel polypill插件解决
55、Vue2中注册在router-link上事件⽆效解决⽅法
​ 使⽤@click.native。原因:router-link会阻⽌click事件,.native指直接监听⼀个原⽣事件。

56、Vue-router 导航守卫有哪些

  • 全局前置/钩子:beforeEach、beforeResolve、afterEach
  • 路由独享的守卫:beforeEnter
  • 组件内的守卫:beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave

引自:2022Vue经典面试题及答案汇总(持续更新)