前言本文用最简单的方式讲解了VUE2最重要的响应式原理。一、响应性原则什么是响应性原则?这意味着当数据更改时,视图将相应更新。这意味着你只需要管理数据,这为我们搬砖提供了极大的方便。VUE是使用Object.defineProperty方法中setter和getter方法的观察者模式实现的。所以在学习VUE的响应式原理之前,先学习两个预备知识:Object.defineProperty和观察者模式。3.原理分析学习了前面的铺垫,我们终于可以开始讲解VUE的响应式原理了。官网用一张图来表示这个过程,但一开始你可能看不懂。看到文末,我们应该就能明白了。总共分为三个步骤:1.Init阶段:VUE的数据的属性会是reactive的,即添加setter/getter函数。functiondefineReactive(obj:Object,key:string,...){constdep=newDep()Object.defineProperty(obj,key,{enumerable:true,configurable:true,get:functionreactiveGetter(){....dep.depend()返回值....},set:functionreactiveSetter(newVal){...val=newValdep.notify()...}})}classDep{statictarget:?Watcher;潜艇:数组<观察者>;depend(){if(Dep.target){Dep.target.addDep(this)}}notify(){constsubs=this.subs.slice()for(leti=0,l=subs.length;i{vm._update(vm._render(),...)}newWatcher(vm,updateComponent,...)...}classWatcher{getter:Function;//代码简化构造函数(vm:Component,expOrFn:string|Function,...){...this.getter=expOrFnDep.target=this//注意当前的Watcher赋值给了Dep.targetthis.value=this.getter.call(vm,vm)//调用组件的update函数...}}看过我上一篇学习vue源码的同学(四)手写vm.$mount方法,相信mountComponent函数他们会很熟悉,如图:我们已经讲过了。在挂载阶段,将创建一个Watcher类的对象。这个Watcher其实就是连接Vue组件和Dep的桥梁。每个Watcher对应一个vue组件。这里可以看到,当newWatcher被创建时,构造函数中的this.getter.call(vm,vm)函数就会被执行。getter是updateComponent。这个函数会调用组件的渲染函数来更新和重新渲染。在render函数中,会访问data的属性,如render:function(createElement){returncreateElement('h1',this.blogTitle)}这时候会调用这个属性blogTitle的getter函数,即://getterfunctionget:functionreactiveGetter(){....dep.depend()returnvalue....},//dep的依赖函数depend(){if(Dep.target){Dep.target.addDep(this)}}在depend函数中,Dep.target就是watcher本身(我们在Watch类中讲过,但是不记得可以转到第三段代码),我们这里做的是为blogTitle注册Watcher对象。这样,每次渲染一个vue组件,如果该组件使用了blogTitle,就会在blogTitle的Dep中注册这个组件对应的Watcher对象。此过程称为依赖项收集。收集到所有依赖blogTitle属性的组件对应的Watcher后,当它发生变化时,会通知Watcher去更新关联的组件。3、Update阶段:当blogTitle发生变化时,调用Dep的notify函数,然后通知所有Watcher调用update函数进行更新。notify(){constsubs=this.subs.slice()for(leti=0,l=subs.length;iitem())}}constreader=newOberver();//每次有订阅者来,注册函数reader.register(()=>{'console.log("calldaisy")'})reader.register(()=>{'console.log("callanny")'})reader.register(()=>{'console.log("callsunny")'})//最后在新书发布后,通知所有客户wantCake.notify()2.1Object.defineProperty相信既然看到了源码,这个就不用介绍了。VUE对data中的所有属性添加set和get的过程称为Reactive。