vue面试题
一、MVVM
MVVM是Model-View-ViewModel的简写
- 低耦合。视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
- 可重用性。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。
- 独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计,使用Expression Blend可以很容易设计界面并生成xaml代码。
- 可测试。界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。
MVC
优点:
1、把业务逻辑全部分离到Controller中,模块化程度高。当业务逻辑变更的时候,不需要变更View和Model,只需要Controller换成另外一个Controller就行了(Swappable
Controller)。
2、观察者模式可以做到多视图同时更新。
缺点:
1、Controller测试困难。因为视图同步操作是由View自己执行,而View只能在有UI的环境下运行。在没有UI环境下对Controller进行单元测试的时候,Controller业务逻辑的正确性是无法验证的:Controller更新Model的时候,无法对View的更新操作进行断言。2、View无法组件化。View是强依赖特定的Model的,如果需要把这个View抽出来作为一个另外一个应用程序可复用的组件就困难了。因为不同程序的的Domain
Model是不一样的
vue生命周期
vue实例从创建到销毁的过程
有八个钩子函数 分别对应的是 创建-挂载-更新-销毁
创建
beforecreate 数据初始化,会定义data数据方法和事件,并完成数据劫持observe以及给组件实例配置watcher观察者实例。这样后续数据发生变化时才能感知到数据变化。
created 最早可以操作data中的数据还有methods下的方法 在这里可以调用方法进行数据请求 created的时候数据已经和data属性进行绑定
挂载
beforemount 调用后会产生一个虚拟dom (用于后续数据发生变化时,新老虚拟dom对比计算)
mounted 最早可以操作dom的,因为这个时候dom已经渲染完成了
更新
beforemount 调用后会产生一个虚拟dom (用于后续数据发生变化时,新老虚拟dom对比计算)
mounted 最早可以操作dom的,因为这个时候dom已经渲染完成了
销毁
beforedestroy 实例销毁前,也就是说在这个函数内,你还是可以操作实例的
destroyed 释放缓存 销毁完毕。 解除各种数据引用,移除事件监听,删除组件_watcher,删除子实例,删除自身self等, 比如定时器。
双向数据绑定
双向数据绑定的核心思想是通过Object.defineProperty()实现, 用数据劫持结合发布者-订阅者模式的方式
利用 observer来实现对每个vue中的data中定义的属性循环,以便利用其中的setter和getter,然后通知订阅者,订阅者会触发它的update方法,对视图进行更新
get就是在读取name属性这个值触发的函数,set就是在设置name属性这个值触发的函数
watcher负责数据监听,当数据发生改变通知订阅者,调用视图更新函数更新视图
订阅/发布者模式
发布者就是通过 事件触发机制 发布任务
订阅者通过监听机制 监听任务执行 过程的变化
订阅发布模式(又称观察者模式)定义了一种一对多的关系,让多个观察者同时监听某一个主题对象,这个主题对象的状态发生改变时就会通知所有观察者对象。
发布者发出通知 => 主题对象收到通知并推送给订阅者 => 订阅者执行相应操作
文档碎片
文档碎片不放在DOM树中,而是放在内存中,就是将节点替换插入文档碎片中的时候不会引起回流重绘,如果插入大量节点,一个个插入必然会引起大量的回流和重绘,先放到文档碎片中,再将文档碎片插入,可以减少回流重绘,提高性能
document.createDocumentFragment 就可以用于暂时存放创建的得dom元素
将需要的添加的大量元素先添加到文档碎片中再将文档碎片添加到需要查入的位置 减少了dom操作
vue组件中的data为什么是一个函数
因为组件的特性是可以复用的,js里对象是引用关系,如果组件data是一个对象,那么子组件中的data属性值会互相污染,产生副作用(每个组件的data都是内存的同一个地址,一个数据改变了其他也改变了)
每个组件的data在function返回后都会在堆里开辟新的内存空间 在栈内存中存放内存地址
一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝
v-if和v-show的区别
v-if是动态的向DOM树内添加或者删除DOM元素;
v-show是通过设置DOM元素的display样式属性控制显隐
v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;
v-show只是简单的基于css切换
性能消耗:v-if有更高的切换消耗;v-show有更高的初始渲染消耗
v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。
因此,如果需要非常频繁地切换,则使用 v-show 较好;
如果在运行时条件不太可能改变,则使用 v-if 较好
v-if和v-for的优先级
当v-if和v-for一起使用时,v-for具有v-if更高的优先级。
如果列表项较少的话,带来的性能消耗可能还不是很明显。如果数据项一多。计算机的性能消耗就十分可观。
Vue.nextTick 的原理和用途
用法:
在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
应用场景:
在进行获取数据后,需要对新视图进行下一步操作或者其他操作时,发现获取不到 DOM。
原因:
这里就涉及到 Vue 一个很重要的概念:异步更新队列(JS运行机制 、 事件循环)。
Vue 在观察到数据变化时并不是直接更新 DOM,而是开启一个队列,并缓冲在同一事件循环中发生的所有数据改变。
在缓冲时会去除重复数据,从而避免不必要的计算和DOM操作。
然后,在下一个事件循环 tick 中,Vue 刷新队列并执行实际(已去重的)工作。
所以如果用 for 循环来动态改变数据100次,其实它只会应用最后一次改变,如果没有这种机制,DOM就要重绘100次,是一个很大的开销,损耗性能。