谈谈你对MVVM开发模式的了解
MVVM分为Model、View、ViewModel三者。
Model:代表数据模型,数据和业务逻辑都在Model层中定义;
View:代表UI视图,负责数据的展现;
ViewModel:负责监听Model中数据的扭转并且管制视图的更新,解决用户交互操作;
Model和View并无间接关联,而是通过ViewModel来进行分割的,Model和ViewModel之间有着双向数据绑定的分割。因而当Model中的数据扭转时会触发View层的刷新,View中因为用户交互操作而扭转的数据也会在Model中同步。
这种模式实现了Model和View的数据主动同步,因而开发者只须要专一对数据的保护操作即可,而不须要本人操作dom。
v-if 和 v-show 有什么区别?
v-show 仅仅管制元素的显示方式,将 display 属性在 block 和 none 来回切换;而v-if会管制这个 DOM 节点的存在与否。当咱们须要常常切换某个元素的显示/暗藏时,应用v-show会更加节俭性能上的开销;当只须要一次显示或暗藏时,应用v-if更加正当。
简述Vue的响应式原理
Vue. js采纳ES5提供的属性个性性能,联合发布者-订阅者模式,通过 Object.defineProperty()为各个属性定义get、set个性办法,在数据产生扭转时给订阅者公布音讯,触发相应的监听回调。
具体步骤如下。
(1)对须要察看的数据对象进行递归遍历,包含子属性对象的属性,设置set和get个性办法。当给这个对象的某个值赋值时,会触发绑定的set个性办法,于是就能监听到数据变动。
(2)用 compile解析模板指令,将模板中的变量替换成数据。而后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,增加监听数据的订阅者。一旦数据有变动,就会收到告诉,并更新视图
(3) Watcher订阅者是 Observer和 Compile之间通信的桥梁,次要性能如下。
在本身实例化时向属性订阅器(dep)外面增加本人。
本身必须有一个 update( )办法。
在 dep.notice()公布告诉时,能调用本身的 updat()办法,并触发 Compile中绑定的回调函数。
(4)MVVM是数据绑定的入口,整合了 Observer、 Compile和 Watcher三者,通过Observer来监听本人的 model数据变动,通过 Compile来解析编译模板指令,最终利用Watcher搭起 Observer和 Compile之间的通信桥梁,达到数据变动告诉视图更新的成果。利用视图交互,变动更新数据 model变更的双向绑定成果。
4、请具体阐明你对Vue.js生命周期的了解。
总共分为8个阶段,别离为 beforeCreate、created、beforeMount、 mounted、beforeUpdate、 updated、 beforeDestroyed、 destroyed。
beforeCreate:在实例初始化之后,数据观测者( data observer)和 event/ watcher事件配置之前调用。
created:在实例创立实现后立刻调用。在这一步,实例已实现以下的配置:数据观测者,属性和办法的运算, watch/event事件回调。然而,挂载阶段还没开始,$el属性目前不可见。
beforeMount:在挂载开始之前调用,相干的 render函数首次调用。
mounted: el被新创建的vm.$el替换,并且在挂载到实例上之后再调用该钩子如果root实例挂载了一个文档内元素,当调用 mounted时vm.sel也在文档内。
beforeUpdate:在数据更新时调用,产生在虛拟DOM从新渲染和打补丁之前。
updated:因为数据更改导致的虚构DOM从新渲染和打补丁,在这之后会调用该钩。
beforeDestroy:在实例销毁之前调用。在这一步,实例依然齐全可用。
destroyed:在 Vue. js实例销毀后调用。调用后,Vue. js实例批示的所有货色都会解除绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
当应用组件的kep- alive性能时,减少以下两个周期。
activated在keep- alive组件激活时调用;
deactivated在keep-live组件停用时调用。
Vue2.5.0版本新增了一个周期钩子:ErrorCaptured,当捕捉一个来自子孙组件的谬误时调用。
5、请具体阐明你对Vue.js生命周期的了解。
总共分为8个阶段,别离为 beforeCreate、created、beforeMount、 mounted、beforeUpdate、 updated、 beforeDestroyed、 destroyed。
beforeCreate:在实例初始化之后,数据观测者( data observer)和 event/ watcher事件配置之前调用。
created:在实例创立实现后立刻调用。在这一步,实例已实现以下的配置:数据观测者,属性和办法的运算, watch/event事件回调。然而,挂载阶段还没开始,$el属性目前不可见。
beforeMount:在挂载开始之前调用,相干的 render函数首次调用。
mounted: el被新创建的vm.$el替换,并且在挂载到实例上之后再调用该钩子如果root实例挂载了一个文档内元素,当调用 mounted时vm.sel也在文档内。
beforeUpdate:在数据更新时调用,产生在虛拟DOM从新渲染和打补丁之前。
updated:因为数据更改导致的虚构DOM从新渲染和打补丁,在这之后会调用该钩。
beforeDestroy:在实例销毁之前调用。在这一步,实例依然齐全可用。
destroyed:在 Vue. js实例销毀后调用。调用后,Vue. js实例批示的所有货色都会解除绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
当应用组件的kep- alive性能时,减少以下两个周期。
activated在keep- alive组件激活时调用;
deactivated在keep-live组件停用时调用。
Vue2.5.0版本新增了一个周期钩子:ErrorCaptured,当捕捉一个来自子孙组件的谬误时调用。
6、请形容封装Vue组件的作用过程。
组件能够晋升整个我的项目的开发效率,可能把页面形象成多个绝对独立的模块,解决了传统我的项目开发中效率低、难保护、复用性等问题。
应用Vue.extend办法创立一个组件,应用Vue.component办法注册组件。子组件须要数据,能够在 props中接收数据。而子组件批改妤数据后,若想把数据传递给父组件,能够采纳emit办法。
7、你是怎么意识vuex的?
vuex能够了解为一种开发模式或框架。它是对 Vue. js框架数据层面的扩大。通过状态(数据源)集中管理驱动组件的变动。利用的状态集中放在 store中。扭转状态的形式是提交 mutations,这是个同步的事务。异步逻辑应该封装在 action中。
8、Vue- loader是什么?它的用处有哪些?
它是解析.vue文件的一个加载器,能够将 template/js/style转换成 JavaScript模块。
用处是通过 vue-loader, JavaScript能够写 EMAScript 6语法, style款式能够利用scss或less, template能够增加jade语法等。
9、请说出vue.cli我的项目的src目录中每个文件夹和文件的用法。
assets文件夹寄存动态资源;components寄存组件;router定义路由相干的配置;view是视图;app. vue是一个利用主组件;main.js是入口文件。
10、在Vue.cli中怎么应用自定义组件?在应用过程中你遇到过哪些问题?
具体步骤如下。
(1)在 components目录中新建组件文件,脚本肯定要导出裸露的接口。
(2)导入须要用到的页面(组件)。
(3)将导入的组件注入uejs的子组件的 components属性中。
(4)在 template的视图中应用自定义组件。
11、谈谈你对vue.js的 template编译的了解。
简而言之,就是首先转化成AST( Abstract Syntax Tree,形象语法树),行将源代码语法结构形象成树状表现形式,而后通过 render函数进行渲染,并返回VNode( Vue. js的虚构DOM节点)。
具体步骤如下。
(1)通过 compile编译器把 template编译成AST, compile是 create Compiler的返回值, createCompiler用来创立编译器。另外, compile还负责合并 option。
(2)AST会通过 generate(将AST转化成 render funtion字符串的过程)失去 render函数, render的返回值是 VNode, VNode是 Vue.Js的虚构DOM节点,外面有标签名子节点、文本等。
12、如何让CSS只在以后组件中起作用?
在每一个Vue.js组件中都能够定义各自的CSS、 JavaScript代码。如果心愿组件内写的CSS只对以后组件起作用,只须要在Style标签增加Scoped属性,即<style scoped></style>。
13、如何检测数据变动?
因为 JavaScript个性的限度, Vue. js不能检测到上面数组的变动,即以下数组中扭转的数据“失落”了。
通过间接索引设置元素,如app.arr[0]=...
批改数据的长度,如 app. arr.length。
为了解决该问题,Vue.js扩大了察看数组,为它增加了一个$set( )办法,用该办法批改的数组,能触发视图更新,检测数据变动。
app.$set(app. arr, 5, 500);
14、如何检测对象变动?
因为 JavaScript个性的限度,Vue.js不能检测到对象属性的增加或删除。因为Vue.js在初始化时将属性转化为 getter/setter,所以属性必须在data对象中定义,能力在初始化时让Vue.js转换它并让它响应,例如以下代码
var data ={
obj:{
a:1
}
}
var app= new Vue ({
el:'#app ',
data:data
})
app.obj.a=10
// 'app.obj.a'和'data.obj.a'当初是响应的
app. obj. b=2
//'app.obj.b'不是响应的
data.obj.b=2
//data.obj.b'不是响应的
如果须要在实例创立之后增加属性并且让它可能响应,能够应用$set实例办法。
app.$set(app.obj,'b',500)
// 'app.obj.b'和'data.obj.b'当初是响应的
对于一般数据对象,能够应用全局办法Vue.set( object,key, value)。
Vue.set(data.obj,"b',500)
//'app.obj.b'和'cata,obj.b'当初是响应的
15、说一下Vue.js页面闪动{{message}}。
Vue. js提供了一个v- cloak指令,该指令始终放弃在元素上,直到关联实例完结编译。当和CSS一起应用时,这个指令能够暗藏未编译的标签,直到实例编译完结。用法如下。
[v-cloak ]{
display:none;
}
<div v-cloak> { { title } }</div>
这样<div>不会显示,直到编译完结。
16、如何解决数据层级构造太深的问题?
在开发业务时,常常会岀现异步获取数据的状况,有时数据档次比拟深,如以下代码。
<span 'v-text="a.b.c.d"></span>
能够应用vm.$set手动定义一层数据。
vm.$set ("demo",a .b.c.d)
17、 Vue3.x响应式数据原理
Vue3.x改用Proxy代替Object.defineProperty。
因为Proxy能够间接监听对象和数组的变动,并且有多达13种拦挡办法。并且作为新规范将受到浏览器厂商重点继续的性能优化。
Proxy只会代理对象的第一层,Vue3是怎么解决这个问题的呢?
判断以后Reflect.get的返回值是否为Object,如果是则再通过reactive办法做代理, 这样就实现了深度观测。
监测数组的时候可能触发屡次get/set,那么如何避免触发屡次呢?咱们能够判断key是否为以后被代理对象target本身属性,也能够判断旧值与新值是否相等,只有满足以上两个条件之一时,才有可能执行trigger。
18、Vue3.0 里为什么要用 Proxy API代替 defineProperty API?
1.defineProperty API 的局限性最大起因是它只能针对单例属性做监听。
Vue2.x中的响应式实现正是基于defineProperty中的descriptor,对 data 中的属性做了遍历 + 递归,为每个属性设置了 getter、setter。这也就是为什么 Vue 只能对 data 中预约义过的属性做出响应的起因。
2.Proxy API的监听是针对一个对象的,那么对这个对象的所有操作会进入监听操作, 这就齐全能够代理所有属性,将会带来很大的性能晋升和更优的代码。
Proxy 能够了解成,在指标对象之前架设一层“拦挡”,外界对该对象的拜访,都必须先通过这层拦挡,因而提供了一种机制,能够对外界的拜访进行过滤和改写。
3.响应式是惰性的。
在 Vue.js 2.x 中,对于一个深层属性嵌套的对象,要劫持它外部深层次的变动,就须要递归遍历这个对象,执行 Object.defineProperty 把每一层对象数据都变成响应式的,这无疑会有很大的性能耗费。
在 Vue.js 3.0 中,应用 Proxy API 并不能监听到对象外部深层次的属性变动,因而它的解决形式是在 getter 中去递归响应式,这样的益处是真正拜访到的外部属性才会变成响应式,简略的能够说是按需实现响应式,缩小性能耗费。
19、Proxy 与 Object.defineProperty 优劣比照
1.Proxy 能够间接监听对象而非属性;
2.Proxy 能够间接监听数组的变动;
3.Proxy 有多达 13 种拦挡办法,不限于 apply、ownKeys、deleteProperty、has 等等是 Object.defineProperty 不具备的;
4.Proxy 返回的是一个新对象,咱们能够只操作新的对象达到目标,而 Object.defineProperty 只能遍历对象属性间接批改;
5.Proxy 作为新规范将受到浏览器厂商重点继续的性能优化,也就是传说中的新规范的性能红利;
6.Object.defineProperty 的劣势如下:
兼容性好,反对 IE9,而 Proxy 的存在浏览器兼容性问题,而且无奈用 polyfill 磨平,因而 Vue 的作者才申明须要等到下个大版本( 3.0 )能力用 Proxy 重写。
vue中组件的data为什么是一个函数?而new Vue 实例里,data 能够间接是一个对象
咱们晓得,Vue组件其实就是一个Vue实例。
JS中的实例是通过构造函数来创立的,每个构造函数能够new出很多个实例,那么每个实例都会继承原型上的办法或属性。
Vue的data数据其实是Vue原型上的属性,数据存在于内存当中。Vue为了保障每个实例上的data数据的独立性,规定了必须应用函数,而不是对象。
因为应用对象的话,每个实例(组件)上应用的data数据是相互影响的,这当然就不是咱们想要的了。对象是对于内存地址的援用,间接定义个对象的话组件之间都会应用这个对象,这样会造成组件之间数据相互影响。
应用函数后,应用的是data()函数,data()函数中的this指向的是以后实例自身,就不会相互影响了。
而 new Vue 的实例,是不会被复用的,因而不存在援用对象的问题。
20.单页面利用和多页面利用区别及优缺点
答:单页面利用(SPA),艰深一点说就是指只有一个主页面的利用,浏览器一开始要加载所有必须的 html, js, css。所有的页面内容都蕴含在这个所谓的主页面中。但在写的时候,还是会离开写(页面片段),而后在交互的时候由路由程序动静载入,单页面的页面跳转,仅刷新部分资源。多利用于pc端。
多页面(MPA),就是指一个利用中有多个页面,页面跳转时是整页刷新
单页面的长处:用户体验好,快,内容的扭转不须要从新加载整个页面,基于这一点spa对服务器压力较小;前后端拆散;页面成果会比拟炫酷(比方切换页面内容时的专场动画)。
单页面毛病:不利于seo;导航不可用,如果肯定要导航须要自行实现后退、后退。(因为是单页面不能用浏览器的后退后退性能,所以须要本人建设堆栈治理);首次加载时耗时多;页面复杂度进步很多。