温故而知新之VUE(一)

2018-11-03  本文已影响1人  lmmy123

VUE 是一个构建用户界面的渐进式前端框架

生命周期

生命周期钩子中的this上下文指向它的VUE实例
图示:

渲染流程

Vue.prototype._init = function(options){
  var vm = this
  vm._uid = uid$1++; //默认自增
  vm._isVue = true;
  // merge options
  if(options && options._isComponent){
    ...
  }else{
    vm.$options = mergeOptions(
        resolveConstructorOptions(vm.constructor), // 获取Vue实例 base  options
        options || {},
        vm
    )
  }
 initProxy(vm)  // 初始化 代理 达到的效果 vm._renderProxy = new Proxy(vm,handlers)
vm._self = vm
initLifecycle(vm) // 设置 vm.$parent  vm.$root vm.$children vm.$refs 什么的
initEvents(vm) // 初始化vm.events
initRender(vm)  // vm._c  vm.$createElement
callHook(vm, 'beforeCreate')
initInjections(vm)
initState(vm) // initProps initMethods initData(vm) initData 中 初始化数据并且 new Observer(value)  new Observer({msg: 'Hello word'}) 
// this.dep = new Dep() 生成依赖收集器 
// 如果传参是数组,this.observeArray(value)
// 不是 this.walk(value) => 遍历value  defineReactive(value,keys[i],value[keys[i]])
//defineReactive 调用 Object.defineProperty()设置数据访问器属性
// get:  if(Dep.target){ dep.depend()} 如果有子元素 遍历添加依赖
// set: dep.notify //  发布消息
}
initProvide(vm) //vm._provide
callHook(vm, 'created')
if(vm.$options.el){
    vm.$mount(vm.$options.el) // 挂载dom
}
//  vm.$mount(vm.$options.el) 这个方法中 判读有没有 'el' ,有没有 ‘template’
//  compileToFunctions(template,{...},this) // 编译成函数 返回 { render, staticRenderFns}
// compile 函数 解析成 AST抽象语法树
// render => vnode  在 mountComponent方法  调用了 vnode = render.call(vm._renderProxy, vm.$createElement)
/**vm.$el= el
* callHook(vm, 'beforeMount')
* var updateComponent
* vm._watcher = new Watcher(vm, updateComponent, noop)
* if(vm.$node == null){
      vm._isMounted = true;
      callHook(vm, 'mounted')
}*/
// vm._update(vm._render(),hydrating)
// vm._render() 返回一个 vnode 使用的是 vm.$createElement 创建的vnode
// 接下来 vnode =》 真实的el节点  通过 vm.$el = vm._patch(prevVnode, vnode)

// compile parse 函数的生成
export const createCompiler = createCompilerCreator(function baseCompile(
  template: string,
  optionss: CompilerOptions 
):CompiledResult{
  const ast = parse(template.trim(), options) // 1.parse
  optimize(ast, options) // 2.optimize
  const code = generate(ast, options) //3.generate
  return {
    ast,
    render: code.render,
    staticRenderFns: code.staticRenderFns
  }
})
// 1. parse  生成 AST抽象语法树 
// 2. optimize 将AST节点进行静态节点标记(static,staticRoot),为后面patch过程对比新旧vnode做优化,标记为static的节点在diff算法中被忽略  使用深度优先遍历算法
// 3.generate 生成render函数 

// patch 方法 将vnode生成真实的dom
// vm.$el = vm._patch_(vm.$el,vnode...)  初始化时
// vm.$el = vm._pathc_(prevVnode,vnode) update时
完整版其大致过程为: html字符串 → render函数 → vnode → 真实dom节点 而运行时渲染(runtime版本)即所谓的去掉编译器的过程:render函数 → vnode → 真实dom节点
上一篇下一篇

猜你喜欢

热点阅读