一、响应式原理
vue2响应式的原理是借助数据劫持和发布订阅者模式
1、数据劫持:
目的:能够感知到数据的改变。
数据劫持是:使用ES5的Object.defineProperty()。把data配置项中的所有数据进行遍历,转成setter和getter(或者说,给每个属性增加set和get函数)既就是:访问器属性。
2、发布订阅者模式:
目的:当数据改变时,(直接和间接)使用该数据的模板处都会有相应的改变(模板会重新渲染)。
可能对方会进一步追问:能不能说的详细点。
怎么回答?
1)、在vue构造函数里,循环变量data中所有属性。首先,保存属性的值,再利用Object.defineProperty()给每个属性增加set和get方法。然后,每个属性需要一个订阅对象,遍历dom树,让所有使用该属性的dom元素都订阅该属性。
2)、当修改某个属性的值时,该属性的set函数就被调用,同时会调用所有订阅该属性的订阅者(函数)。
二、v-if和v-show区别
相同点:
都是用来控制dom元素的显示和隐藏。
不同点:
1、原理上:
v-if是 通过 添加和删除dom元素,来 控制dom元素的显示和隐藏。
v-show是 通过 控制dom元素样式的display属性的值,来 控制dom元素的显示和隐藏。
2、性能损耗
v-if:性能损耗主要体现在频繁切换时
v-show:性能损耗主要体现在首次。
3、应用场景:
v-if:用于切换不频繁的场景。
v-show:用户切换频繁的场景。
4、安全性:
v-if:安全性好。(如果dom元素不显示时,在elements里根本看不到)
v-show:安全性不好。(如果dom元素不显示时,在elements里依然可以看到,那么,懂程序 的人,即可以修改)
三、为什么不建议v-for与v-if连用
1、原因:
因为,v-for的优先级比v-if优先级高,如果,满足条件的数据相对(原始数据)较少,那么,会造成大量性能浪费。
2、解决方案:
在computed里,先把满足条件的数据过滤出来。然后,v-for直接循环过滤出来的数据。而computed是有缓存的,所以,在原始数据没有变化时,不会多次过滤数据,这样,就提高了效率。
四、双向的绑定原理
1、双向: M----》 V。 V--M
2、利用事件和属性完成的。
3、v-model是个语法糖。本质就是事件和属性的结合。
1)、针对文本框(单行和多行):value属性和input事件。 如果加上修饰符 lazy。事件变成了change事件。
2)、针对radio:使用的checked属性和change事件。同时,需要给radio加上value属性。
3)、针对checkbox:使用的checked属性和change事件。
3.1)、如果应用在多选时,需要给checkbox加上value属性。
3.3)、如果应用在单选时,不需要加。
4)、针对select:使用value属性和change事件。
五、computed和watch的区别
1、相同点:
都可以监听数据。
2、不同的:
1)、概念:
computed: 是计算属性,依赖其它属性值,并且 computed 的值有缓存,当依赖的属性值发生改变时,才会重新计算 computed 的值,默认是只读的(相当于getter函数),它也可以设置getter和setter函数来完成读和写。
watch:更多的是观察的作用,每当监听的数据变化时都会执行回调进行后续操作,它只能设置getter。watch默认只监听一层。如果要深度监听,让deep属性为true。
2)、作用:
computed:是为了显示而用,降低了模板上代码复杂度。
watch:属性变化的检测(相当于事件),当属性的值发生变化时,可以调用函数。
3)、依赖模板调用:
computed:只能在模板上使用。
watch:不能在模板上使用。
4)、是否异步:
computed:不能有异步,只能同步。
watch:可以有异步。
六、怎么理解虚拟DOM和diff算法
1)虚拟DOM: 用JSON对象模拟的真实dom,用来提升性能
2)diff算法:用来比较两个虚拟dom的不同之处。
3)步骤:
3.1)产生两个虚拟DOM树:newVDom,oldVDom。
3.2)、oldVDom和真实DOM保持一致
3.3)数据变化时,影响的是(操作的是)newVDom
3.4)操作newVDom后,通过diff算法对比newVDom和oldVDom的差异,并在oldVDom标注哪些节点要删除,哪些节点要增加,修改
3.5)根据oldVDom操作真实的DOM,让真实Dom和oldVDom保持一致
4)diff算法的解释:
逐步解析newVdom的节点,找到它在oldVdom中的位置,如果找到了就移动到下一个的DOM元素,如果没找到说明是新增节点,则新建一个节点插入。遍历完成之后如果oldVdom中还 有没处理过的节点,则说明这些节点在newVdom中被删除了,删除它们即可。
七、vue组件的data为什么是个函数
一个组件的 data 选项必须是一个函数,要有返回object(就是vue对象的data),只有这样,每个实例(vue组件对象)就可以维护一份被返回对象的独立的拷贝,否则,组件复用时,数据相互影响。即:组件的作用域(应该)是独立的。
简单回答:如果不是函数,那么,复用的组件的data共享同一块内存空间。
八、单向数据流
父-----》子 的数据传递是可以的。反之不行。
Prop 是单向绑定的:当父组件的属性(数据)变化时,将传导给子组件,但是反过来不会。这是为了防止子组件无意间修改了父组件的状态,来避免应用的数据流变得难以理解。
另外,每次父组件更新时,子组件的所有 prop 都会更新为最新值。这意味着你不应该在子组件内部改变 prop。如果你这么做了,Vue 会在控制台给出警告。
九、组件间通信:
1)、父子组件传值
1)、父---子传:props,ref
2)、子-->父传:emit
2)、兄弟组件
1)、子1---》父---》子2
2)、事件总线(event-bus)
原理:使用vue对象的$on和$emit完成。
具体做法:新建一个空的vue对象。在SonA里和SonB引入该vue对象。假设SonA给SonB传递数据。
$emit:触发事件(在SonA)
$on:绑定事件(在SonB)
对MVC,MVP,MVVM的理解
三者都是项目的架构模式(不是类的设计模式),即:一个项目的结构,如果分层,不同层负责不同的职责。
1、MVC:
MVC的出现是用在后端(全栈时代)
M:model,模型:
主要完成业务功能,在数据库相关的项目中,数据库的增删改查属于模型(重点)。(nodeJS中的db文件夹),没有页面,是纯粹的逻辑
V:view,视图:
主要负责数据的显示(HTML+CSS,动态网页(jsp,含有html的php文件))页面的展示和用户的交互。
C:controller,控制器:
主要负责每个业务的核心流程,在项目中体现在路由以及中间件上(nodeJS中的routes文件夹)
2、MVP
MVP是把MVC中的C改成了P。主要限制了M和V之间不能直接通信(互相调用,传递数据)。M和V之间的通信必须经过P。
P:Presenter,表示器
主要用于连接M层、V层,完成Model层与View层的交互,还可以进行业务逻辑的处理。
3、MVVM:
MVVM是把MVP中P改成了VM。主要体现的是MV之间和双向绑定。View的变动可以同步响应在Model,反之亦然。Vue就是一个MVVM的框架。准确来说,使用Vue框架完成项目时,使用的是MVVM模式。
VM:ViewModel
主要完成MV的数据通信,并且是双向绑定。而 View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作 DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。
SPA的理解:
1)、单页面应用的概念
SPA:single page application,单页面应用。
就是整个项目就只有一个html页面(文件),首次加载时,把所有的html,css,js全部加载下来。通过操作dom的删除和创建(添加)来完成页面的切换。
2)、单页面应用优缺点
优点:
1、单页应用相对服务器压力小。【因为:首次、或者只要HTML,CSS和JS加载完毕后,切换页面是不用再去服务器请求HTML,CSS和JS】
2、局部刷新,所以,用户体验好。【通过删除、添加、修改DOM的方式】 3、前后端分离 4、页面效果会比较炫酷(比如切换页面内容时的转场动画)
缺点: 1、不利于SEO(Search Engine Optimization)。如:百度,360等搜索引擎收录。 2、初次加载时耗时多(可以使用路由懒加载解决) 3、导航不可用,如果一定要导航需要自行实现前进、后退(vue-router做好了)。页面复杂度提高很多
4、容易造成CSS命名冲突。【用scoped或者BEM的方式解决】