1 Vue.js 双向绑定的原理
Vue.js 2.0 采纳数据劫持(Proxy 模式)联合发布者-订阅者模式(PubSub 模式)的形式,通过 Object.defineProperty()来劫持各个属性的 setter,getter,在数据变动时公布音讯给订阅者,触发相应的监听回调。
每个组件实例都有相应的watcher程序实例,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的setter被调用时,会告诉watcher从新计算,从而以致它关联的组件得以更新。
Vue.js 3.0, 放弃了Object.defineProperty ,应用更快的ES6原生 Proxy (拜访对象拦截器, 也称代理器)
步骤:
须要observe的数据对象进行递归遍历,包含子属性对象的属性,都加上setter和getter这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变动
compile解析模板指令,将模板中的变量替换成数据,而后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,增加监听数据的订阅者,一旦数据有变动,收到告诉,更新视图
Watcher订阅者是Observer和Compile之间通信的桥梁,次要做的事件是: ①在本身实例化时往属性订阅器(dep)外面增加本人 ②本身必须有一个update()办法 ③待属性变动dep.notice()告诉时,能调用本身的update()办法,并触发Compile中绑定的回调,则功成身退。
MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来监听本人的model数据变动,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变动 -> 视图更新;视图交互变动(input) -> 数据model变更的双向绑定成果。
2. Vue.js 3.0 放弃defineProperty, 应用Proxy的起因
Object.defineProperty缺点
监控到数组下标的变动时,开销很大。所以Vue.js放弃了下标变动的检测;
Object.defineProperty只能劫持对象的属性,而Proxy是间接代理对象。Object.defineProperty须要遍历对象的每个属性,如果属性值也是对象,则须要深度遍历。而 Proxy 间接代理对象,不须要遍历操作。
Object.defineProperty对新增属性须要手动进行Observe。vue2时须要应用 vm.$set 能力保障新增的属性也是响应式
Proxy反对13种拦挡操作,这是defineProperty所不具备的
Proxy 作为新规范,久远来看,JS引擎会持续优化 Proxy,但 getter 和 setter 根本不会再有针对性优化
3. Vue 2 中给 data 中的对象属性增加一个新的属性时会产生什么?如何解决?
视图并未刷新。这是因为在Vue实例创立时,新属性并未申明,因而就没有被Vue转换为响应式的属性,天然就不会触发视图的更新,这时就须要应用Vue的全局 api $set():this.$set(this.obj, 'new_property', 'new_value')
4. Computed和Watch的区别
computed 计算属性 : 依赖其它属性值,并且 computed 的值有缓存,只有它依赖的 属性值产生扭转,下一次获取 computed 的值时才会从新计算 computed 的值。
watch 侦听器 : 更多的是察看的作用,无缓存性,相似于某些数据的监听回调,每 当监听的数据变动时都会执行回调进行后续操作。
5. data为什么是一个函数而不是对象
JavaScript中的对象是援用类型的数据,当多个实例援用同一个对象时,只有一个实例对这个对象进行操作,其余实例中的数据也会发生变化。
而在Vue中,咱们更多的是想要复用组件,那就须要每个组件都有本人的数据,这样组件之间才不会互相烦扰。
所以组件的数据不能写成对象的模式,而是要写成函数的模式。数据以函数返回值的模式定义,这样当咱们每次复用组件的时候,就会返回一个新的data,也就是说每个组件都有本人的公有数据空间,它们各自保护本人的数据,不会烦扰其余组件的失常运行。
6. 父子组件的生命周期程序
加载渲染过程:
父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted
子组件更新过程:父beforeUpdate->子beforeUpdate->子updated->父updated
父组件更新过程:父beforeUpdate->父updated
销毁过程:父beforeDestroy->子beforeDestroy->子destroyed->父destroyed
7.服务器渲染
destroyed->父destroyed
8.Vue的生命周期办法有哪些?个别在哪一步发动申请及起因
beforeCreate:在new一个vue实例后,只有一些默认的生命周期钩子和默认事件,其余的货色都还没创立。在beforeCreate生命周期执行的时候,data和methods中的数据都还没有初始化。不能在这个阶段应用data中的数据和methods中的办法
create:data 和 methods都曾经被初始化好了,如果要调用 methods 中的办法,或者操作 data 中的数据,最早能够在这个阶段中操作
beforeMount:执行到这个钩子的时候,在内存中曾经编译好了模板了,然而还没有挂载到页面中,此时,页面还是旧的
mounted:执行到这个钩子的时候,就示意Vue实例曾经初始化实现了。此时组件脱离了创立阶段,进入到了运行阶段。 如果咱们想要通过插件操作页面上的DOM节点,最早能够在和这个阶段中进行
beforeUpdate: 当执行这个钩子时,页面中的显示的数据还是旧的,data中的数据是更新后的, 页面还没有和最新的数据放弃同步
updated:页面显示的数据和data中的数据曾经放弃同步了,都是最新的
beforeDestory:Vue实例从运行阶段进入到了销毁阶段,这个时候上所有的 data 和 methods , 指令, 过滤器 ……都是处于可用状态。还没有真正被销毁
destroyed: 这个时候上所有的 data 和 methods , 指令, 过滤器 ……都是处于不可用状态。组件曾经被销毁了。
补充答复:
created 实例曾经创立实现,因为它是最早触发的起因能够进行一些数据,资源的申请。(服务端渲染反对created办法)
mounted 实例曾经挂载实现,能够进行一些DOM操作
beforeUpdate 能够在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。
updated 能够执行依赖于 DOM 的操作。然而在大多数状况下,你应该防止在此期间更改状态,因为这可能会导致更新有限循环。该钩子在服务器端渲染期间不被调用。
destroyed 能够执行一些优化操作,清空定时器,解除绑定事件
9.mixin混入
10.过滤器filter
全局
部分
11.插槽
12.vuex
state:寄存公共数据的中央;
getter:获取依据业务场景解决返回的数据;
mutations:惟一批改state的办法,批改过程是同步的;
action:异步解决,通过散发操作触发mutation;
module:将store模块宰割,缩小代码臃肿
9.params和query的区别
答:用法:query要用path来引入,params要用name来引入,接管参数都是相似的,别离是this.$route.query.name和this.$route.params.name。
url地址显示:query更加相似于咱们ajax中get传参,params则相似于post,说的再简略一点,前者在浏览器地址栏中显示参数,后者则不显示
留神点:query刷新不会失落query外面的数据
params刷新 会 失落 params外面的数据。
10. vue-router有哪几种导航钩子?
全局导航钩子:router.beforeEach(to,from,next)
组件内的钩子beforeRouteEnter (to, from, next) beforeRouteUpdate (to, from, next) beforeRouteLeave (to, from, next)
独自路由独享组件 beforeEnter: (to, from, next)