Vue 笔记

391 阅读2分钟

============== 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

响应式原理:

  1. 核心Observer,Dep, Watcher;
  2. Observer 进行数据监听绑定, get 收集依赖, set 触发 watcher 回调

问题

  • 数据怎么实现监听? - defineObjectProperty{ set, get}, proxy
  • 数据改变,要更新哪些视图 - 依赖收集, get (页面、watch/computed)
  • 什么时间更新 - set 依赖更新

源码实现

  1. defineObjectProperty 重写 set/get, set - 监听变化, get - 依赖收集
  2. data 每个属性, 都有一个 依赖收集器 dep - { id: , subs: [watcher]}
  3. 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()
    }
  }
}

virtual dom diff实现:

Vue computed 属性:

vue watch 属性 :