主体
实例方法归类:
data 数据方法
dom dom方法
event 事件处理
lifecycl 生命周期函数
init 初始化vue页面
全局方法:
derectives filters
init过程
data : observer deps computed watch
|| watcher
template: fragment [ directive repeat if component transition filter ]
重点:
把数据(Model) 和视图(View) 建立关联
1. 通过observer 对 data 监听, 包括监听data 任何属性变化
2. 把 template 解析成一段 文档对象, 然后解析其中的directive,
得到每一个指令所依赖的东西 [包括 数据, 和这个数据更新到页面的原始方法 ]
比如 v-text=‘mess‘ 被解析后
1. 所依赖的数据项 this.$data.mess data1
2. 响应视图的更新方法 span.textContent = this.$data.mess fn1
3. 通过 watcher 把上述的两部分结合起来, 即把 directive中的依赖 对应 observer;
这样有数据更新, 就会触发observer, 如果发现数据 data1 有变化,
就会通知指令 触发 fn1更新视图
整个vm 核心, 就是实现了 observer(观察数据变化) parser(解析依赖) watcher(观察到的数据通知指令的执行更新相应页面方法) 这三个东西
具体实现
数据监听机制
如何监听某一个对象属性的变化呢?我们很容易想到 Object.defineProperty
这个 API,
为此属性设计一个特殊的 getter/setter,然后在 setter 里触发一个函数,就可以达到监听的效果。
[ ‘push‘, ‘pop‘, ‘shift‘, ‘unshift‘, splice‘, ‘sort‘, ‘reverse‘].forEach(function( method){ var original = arrayProto[method] // Array.prototype.sort //数组的方法执行的时候, 会触发下面这个函数 _.define( arrayMethods, method, function mutator(){ //先在原生的数组原型方法中按传入的参数执行一遍, 得到结果 var result = original.apply(this , args); var ob = this.__ob__; var inserted switch (method){ case ‘push‘: inserted = args ;break case ‘unshift‘: inserted = args ; break case ‘splice‘: inserted = args.slice(2); } //不解 if(inserted) ob.observeArray(inserted) ob.notify() return result }) })
同时 Vue.js 提供了两个额外的“糖方法” arr.$set[0] = "c"
和 $remove(index)
来弥补这方面限制带来的不便。
个人理解是把这$set 和 $remove 添加到数组原型中,
因为defineproperty可以监听到数组所有原型方法, 包括用户新增的原型方法
所以用户调用$set 的时候, 会被劫持到
path 解析器
var path = ‘a.b[1].v‘
var obj = {
a: { b:[ {v:1}, {v:2}, {v:3} ] }
}
parse( obj, path ) // => 2
如何解析 这个字符串 成为 js语句 是关键
vue.js 是通过状态机管理 来实现对路径的解析的