Vue面试题汇总

1. v-if与v-show区别

v-if只有当条件是true才进行渲染,是真正的销毁和重建。
v-show无论条件是否为true都会渲染,只不过是基于css display:none来进行切换。
一般来说,v-if切换开销比较高,而v-show有比较高的初始渲染开销

2. router-link与a有区别吗

router-link其实还是转换成了a标签进行页面跳转。但是router-link利用了缓存机制,只渲染修改的部分。所有尽量使用router-link

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

是基于webpack的一个的loader,解析和转换 .vue 文件,提取出其中的逻辑代码 script、样式代码 style、以及 HTML 模版 template,再分别把它们交给对应的 Loader 去处理,
selector–将.vue文件解析拆分成一个parts对象,其中分别包含style、script、template
style-compiler–解析style部分
template-compiler 解析template部分
babel-loader-- 解析script部分,并转换为浏览器能识别的普通js

4. 计算属性和watch的区别

计算属性自动监听依赖值得变化,从而动态返回内容。watch是一个过程,在监听的值改变后,可以触发一个回调,并做一些事情。
一般来说,如果只是需要动态值,用计算属性;如果需要监听值的变化后执行逻辑,用watch。
另外:
计算属性是一个对象的时候,会有get和set两个属性。
计算属性跟方法相比,计算属性会有缓存,方法没有;计算属性不能接受参数,方法可以。

5. watch中的deep:true 是如何实现的?为什么computed没有deep:true

如果用户要监听的是个对象,内层的对象就不会被依赖收集,这时候有一个deep属性,要想让收集到内层的对象,就需要将deep设置成true,这时候就会执行traverse这个方法,这个方法里就是做了个数组递归,如果是数组的话,会根据数组的每一项索引取值,进行递归追加依赖,如果是对象会拿的key进行遍历取值,进行递归追加依赖,traverse就是deep:true实现的核心。这样就会把数组或者对象的没一个属性都进行依赖追加进行监听,只有依赖发生变化就会通知视图更新
因为computed是用在模板里的,在模板中的数据会调一个方法JSON.strginify(),放一个对象,默认会对这个对象里的所有属性求值。

6. 为何vue采用异步渲染

如果不采用异步渲染,那么每次更新数据都会对当前组件进行渲染。为了性能考虑,vue会在本轮数据更新后,异步更新视图。(一个组件,更新了很多的数据,每次都要渲染,那效率就太低了)

7. 为什么组件中的 data 必须是一个函数,然后 return 一个对象,而 new Vue 实例里,data 可以直接是一个对象?

因为组件会被拿来复用。JS里的对象是引用关系,作用域没有隔离。这样一来就会造成不同组件的data相互影响。而new Vue的实例是不会被复用的,因此也不存在引用对象的问题。

8. vue中key的作用

key 的作用主要是为了更高效的更新虚拟 DOM,提高性能。
举例来说,a、b、c、d、e五个节点,如果更新后变成了a、b、c、z、d、e。如果没有key的话,diff算法会挨个更新元素。给节点添加key后,相当于是给节点添加了唯一标识。diff算法可以正确的识别节点,找到位置插入新的节点。


9. nextTick

作用:在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,可以获取更新后的 DOM。
应用场景:需要在视图更新之后,基于新的视图进行操作。
触发时机:在同一事件循环中的数据变化后,DOM完成更新,立即执行Vue.nextTick()的回调。
Vue 在内部对异步队列尝试使用原生的 Promise.thenMutationObserversetImmediate,如果执行环境不支持,则会采用 setTimeout(fn, 0) 代替。宏任务耗费的时间是大于微任务的,所以在浏览器支持的情况下,优先使用微任务。如果浏览器不支持微任务,使用宏任务。

10. keep-alive

11. vue的双向绑定原理

分对象和数组
对象的话,利用Object.defineProperty()来重新定义属性,当属性发生变化时,就会通知相关依赖进行更新操作。
数组的话,使用函数劫持的方法,重写了数组的方法
Vue将data中的数组进行了原型链重写,指向了自己定义的数组原型方法。这样调用数组api(7种会改变数组的方法)时,就会通知依赖更新。如果数组中包含引用类型,则会对引用类型再进行监控。
vue3
vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过new Proxy()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
Vue 3.0与Vue 2.0的区别仅是数据劫持的方式由Object.defineProperty更改为Proxy代理,其他代码不变。

12. v-model是如何实现的

13. 单向数据流

vue 组件间传递数据是单向的,即数据总是由父组件传递到子组件,子组件在其内部可以有自己维护的数据,但它无权修改父组件传递给它的数据,当开发者尝试这样做的时候,vue 将会报错。这样做是为了组件间更好的解耦,在开发中可能有多个子组件依赖于父组件的某个数据,假如子组件可以修改父组件数据的话,一个子组件变化会引发所有依赖这个数据的子组件发生变化,所以 vue 不推荐子组件修改父组件的数据,直接修改 props 会抛出警告。

14. 组件通信

(1)props
一般属性,父传子
函数属性,子传父
父子通信比较常用的是,父传子用props,子传父用$emit(方法, 参数)
(2)事件总线,通过一个空的vue实例作为事件总线,用来触发和监听事件。$on$emit
可以实现任意组件间通信
(3)vuex
状态管理。最常用,最方便。可以实现任意关系组件的通信。
(4)$parent,$childrenref
ref如果在子组件上,就指向子组件实例

15. vuex管理状态的机制

vuex用来管理共享状态
state是共享状态的集合,getters通过操作state获得派生状态,mutations是操作state数据的方法集合,actions让mutations中的方法能够在异步操作中起作用

16. vue实例的生命周期

在beforeCreate 钩子函数调用的时候,是获取不到props 或者data 中的数据的,因为这些数据的初始化都在initState 中。
然后会执行created 钩子函数,在这一步的时候已经可以访问到之前不能访问到的数据,但是这时候组件还没被挂载,所以是看不到的。
接下来会先执行beforeMount 钩子函数,开始创建VDOM,最后执行mounted 钩子,并将VDOM 渲染为真实DOM 并且渲染数据。组件中如果有子组件的话,会递归挂载子组件,只有当所有子组件全部挂载完毕,才会执行根组件的挂载钩子。
再接下来是数据更新时会调用的钩子函数beforeUpdate 和updated,这两个钩子函数没什么好说的,就是分别在数据更新前和更新后会调用。
另外还有keep-alive 独有的生命周期,分别为activated 和deactivated 。用keep-alive 包裹的组件在切换时不会进行销毁,而是缓存到内存中并执行deactivated 钩子函数,命中缓存渲染后会执行actived 钩子函数。
最后就是销毁组件的钩子函数beforeDestroy 和destroyed。前者适合移除事件、定时器等等,否则可能会引起内存泄露的问题。然后进行一系列的销毁操作,如果有子组件的话,也会递归销毁子组件,所有子组件都销毁完毕后才会执行根组件的destroyed 钩子函数。

17. 何时需要使用beforeDestroy

当前页面中使用了$on方法,那就需要在组件销毁前解绑
清除自己定义的定时器
解除事件的绑定scroll, mousemove等

18. Vue模板编译原理

19. 虚拟dom

20. diff算法

21. $.set

我们在data中定义一个对象后,如果给对象增加新的属性。则这个新增加的属性不是响应式的。当数据发生变化,并不会显示到视图。这是因为新添加的属性没有被Object.defineProperty劫持,导致视图不会同步更新。解决办法是使用this.$set(obj, 'name', 'jack')
对于数组,直接通过索引设置元素,例如arr[] = 2
修改数组长度,例如arr.length = 6
vue同样不能监测到数据变化

22. MVVM的理解

参考资料:
通俗易懂了解Vue中nextTick的内部实现原理

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容

  • 什么是vue生命周期 Vue 实例从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、销毁等一系列过程...
    为光pig阅读 531评论 0 12
  • .什么是vue生命周期 Vue 实例从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、销毁等一系列过...
    酷酷的凯先生阅读 4,323评论 0 3
  • 谈谈你对MVVM开发模式的理解 MVVM分为Model、View、ViewModel三者。 Model 代表数据模...
    廖若晨阅读 1,283评论 0 4
  • 1、V-if和V-show的区别 答案:区别就是dom元素是否挂载了,v-show是dom树上有内容,不显示,di...
    cj_jax阅读 20,106评论 2 22
  • 推荐指数: 6.0 书籍主旨关键词:特权、焦点、注意力、语言联想、情景联想 观点: 1.统计学现在叫数据分析,社会...
    Jenaral阅读 5,701评论 0 5