============== vue ==================
- jiongks.name/blog/vue-co…
- 在进行DOM树的渲染时,render渲染函数的优先级最高,template次之且需编译成渲染函数,而挂载点el属性对应的元素若存在,则在前两者均不存在时,其outerHTML才会用于编译与渲染。
vue 生命周期:
1. new Vue()
- init Events & lifecycle
2. beforeCreate -
init injections & reactivity
// resolve injections before data/props
// resolve provide after data/props
3. created - 依赖收集 data, method 已经有init
获取挂载的DOM 父节点
4. beforeMount - virtual dom 已经创建
compile template or el , 通过render 函数,vnode -> virdom tree
挂载dom
5. mounted - dom 已经挂载, 监听update
5.1 beforeupdate
virtual dom re-render and patch
5.2 updated
6. beforeDestroy
7. destroyed
Vue.prototype._init(opt){
... 合并选项
... 设置初始值 ,事件 等数据
initLifecycle(vm)
callHook(vm, 'beforeCreate');
... 初始化选项等数据,依赖收集
callHook(vm, 'created');
...获取挂载的DOM 父节点
callHook(vm, 'beforeMount');
...解析模板成渲染函数,并执行渲染函数,生成DOM插入页面
vm._isMounted = true;
callHook(vm, 'mounted');
}
vue options :
- option/数据: data, props, computed, watch, methods, propsData - 只能用与 new Vue()实例中,区别于component
- option/dom : el, template, render, renderError - developer 模式有效
- option/lifehook: lifecycle
- option/res: directives - 自定义指令, filters - | 连接多个filter, components - 组件
- option/组合:mixins, parent - , extends - 扩展一个组件, provide/inject
mixins - 数组 extends: 单个
Vue api
全局:
- Vue.component
- Vue.use
- Vue.extend
- Vue.filter
- Vue.complile
- Vue.set
- Vue.delete
- Vue.mixin
- Vue.directive
- Vue.nextTick
响应式原理:
- 核心Observer,Dep, Watcher;
- Observer 进行数据监听绑定, get 收集依赖, set 触发 watcher 回调
问题
- 数据怎么实现监听? - defineObjectProperty{ set, get}, proxy
- 数据改变,要更新哪些视图 - 依赖收集, get (页面、watch/computed)
- 什么时间更新 - set 依赖更新
源码实现
- defineObjectProperty 重写 set/get, set - 监听变化, get - 依赖收集
- data 每个属性, 都有一个 依赖收集器 dep - { id: , subs: [watcher]}
- watcher 监听,更新视图
Observer, Dep, Watcher 关系:
Observer 提供数据监听能力
Dep 保存data依赖,
Watcher
- Observer : collect dependencies and dispatch updates.
- Dep:
- Watcher:
export class Observer {
dep: Dep;
}
/**
* A watcher parses an expression, collects dependencies,
* and fires callback when the expression value changes.
* This is used for both the $watch() api and directives.
*/
export default class Watcher {
addDep() {
// 我这个Watcher要被Observer塞到Dep里去了~~
},
update() {
// Dep通知我更新呢~~
},
}
/**
* A dep is an observable that can have multiple
* directives subscribing to it.
*/
export default class Dep {
static target: ?Watcher;
id: number;
subs: Array<Watcher>;
constructor () {
this.id = uid++
this.subs = []
}
addSub (sub: Watcher) {
this.subs.push(sub)
}
removeSub (sub: Watcher) {
remove(this.subs, sub)
}
depend () {
if (Dep.target) {
Dep.target.addDep(this)
}
}
notify () {
// stabilize the subscriber list first
const subs = this.subs.slice()
for (let i = 0, l = subs.length; i < l; i++) {
subs[i].update()
}
}
}