Vue.js 响应式原理

数据模型仅仅是普通的 JavaScript 对象。而当你修改它们时,视图会进行更新。

  • How Changes are Tracked
  • check change notice
  • delcaring Reactive Properties
  • async update Queue

 

如何追踪变化

当把普通的JavaScript对象传递给Vue实例的data选项, Vue遍历这个对象的属性:

使用Object.defineProperty()把属性{attr_name:  value}格式转化为 getter/setter对儿。

个人理解:

ruby中的方法,attr_write 和attr_read和getter/setter类似都是操作对象读/写的方法。

普通JS对象内部的数据,每个数据(hash格式)被分配了getter/setter方法,用于进行读和写

 

 

getter/setter用于追踪依赖, 在属性被访问和修改时通知变化。

每个组件实例都有相应的watcher实例对象, 它会在组件渲染的过程中把属性记录为依赖dependency.

之后当依赖项的setter被调用时,会通知watcher重新计算,从而致使它关联的组件得以更新。

 


 

 

Object.defineProperty(obj, prop, descriptor)

这个方法直接在一个对象上定义一个新的属性,或修改现有的属性,返回这个对象。

  • obj即对象
  • prop 对象属性的名字或符号Symbol, 用于被定义或修改
  • descriptor 被定义/修改的属性的描述

 

属性desciptor在对象中有2种主要形式:

  • 数据描述符:  attr-name: value。writable: true/false (正常的新增属性和修改属性值)
  • 存取描述符号: 由一个getter/setter对儿函数来描述一个属性。用get, set方法来读/写属性值

属性描述符号只能二选一。它们都是对象。

 

get:一个函数,作为一个getter为属性服务。当属性被访问时,getter被调用。 this设置给对象

set:一个函数, 作为一个setter为属性服务。当属性被分配时,setter和一个参数value被调用, 参数分配给属性。 this设置给属性被分配的对象。

例子:

var o = {a: 37}; // 创建一个新对象

// 在对象中添加一个属性与存取描述符的示例
var bValue;
Object.defineProperty(o, "b", {
  get : function(){
    return bValue;
  },
  set : function(newValue){
    bValue = newValue;
  },
  enumerable : true,    #可以改变该描述符
  configurable : true    #该属性可以出现在对象的枚举属性中
});

o.b = 38;
// 对象o拥有了属性b,值为38

// o.b的值现在总是与bValue相同,除非重新定义o.b

 

 

检查变化的注意事项

Vue在初始化实例时对属性执行getter/setter转化过程。

之后给实例添加的属性是非react的,因为没有getter/setter方法。也就没办法监听watcher。

如果想要响应的属性,必须使用vm.$set(target, key, value)方法。新增属性到嵌套对象上。

猜测这个方法又调用了Object.defineProperty()。

 


 

 

声明响应属性

Vue不可以动态添加根级别的相应属性。所以在初始化实例前需要声明一个根级别的相应属性。可以是空值。

var vm = new Vue({
data: {
// 声明 message 为一个空值字符串
message: ''
},
template: '<div>{{ message }}</div>'
})
// 之后设置 `message`
vm.message = 'Hello!'

 

 


 

 

异步更新队列

(未理解)

猜测:

posted @ 2018-09-16 20:58  Mr-chen  阅读(427)  评论(0编辑  收藏  举报