1.initstate创建响应式数据
属性劫持
- 如果有data的话就会进行initData
- initData内判断是否为函数是函数的话调用并将this指向vm
- 之后调用observe函数 会返回一个Observe对象
- 内部判断是数组的话循环数组每一项对他进行劫持(调用observe)并重写数组的__proto__修改七个会改变原数组的方法
- 是对象的话就直接劫持
模版解析
- 如果传入了模版参数就调用$mound开始解析ast语法树
- 然后根据语法树生成render方法调用字符串(_v('div').....)
- 并使用with(this)使这个函数指向当前vm从而可以读取到变量
- 最后通过new Function转为真正的函数调用式
- 通过 实现_v createElementVNode _c createTextVNode _s方法 最后render方法会生成一个虚拟节点
- 通过_update函数接受 render 会先插入由虚拟dom生成的节点再将当前节点的dom删除
- 为当前组件生成一个watcher
数据及页面同步更新
在get时为每个模版中使用到的数据生成一个dep再的wat添加进当前的watcher中并通过防抖杜绝多次收集依赖 为当前的watcher添加对应的dep(watcher于dep是多对多的关系) 在更新时会调用dep.notify();会通过循环更新当前dep涉及到的所有watcher 在更新时会将所有需要更新的watcher收集起来通过防抖只触发一次(异步更新)
nextTick
因为有settimeout和.then等等不是同步执行的任务导致有可能用户更新数据但是拿到的数据不同步 所以vue使用nextTick来统一非异步任务。
nextTick会维护一个任务队列将要执行的函数按顺序排放,再统一通过api来调用(优雅降级Promise.resolve().then==》MutationObserver==》setImmediate==》setTimeout)