美文网首页
温故而知新之VUE(一)

温故而知新之VUE(一)

作者: lmmy123 | 来源:发表于2018-11-03 16:17 被阅读1次

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

生命周期

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

  • new Vue({}) --- init Events & LifeCycle
  • beforeCreate --- init injections & reactivity
  • created --- has 'template' options?
    yes: compile template into render Function
    no: compile el's outerHTML as template
    在实例创建完成后调用,$el属性目前不可见
  • beforeMount --- create vm.$el and replace 'el' with it
    该钩子在服务器端渲染期间不能被调用
  • mounted 该钩子在服务器端渲染期间不能被调用
    不会承诺所有的子组件都会一起被重绘,如果你希望整个视图都重绘完毕,可以使用vm.$nextTick(function(){})
  • beforeDestroy -- 组件销毁之前
  • destroyed
  • beforeUpdate - Virtual DOM re-render and patch
  • updated
  • activated --- keep-alive 组件激活时调用
  • deactivated ---keep-alive组件停用时调用
  • errorCaptured ---2.5.0新增 捕获一个来自子孙组件的错误时被调用

渲染流程

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节点

相关文章

网友评论

      本文标题:温故而知新之VUE(一)

      本文链接:https://www.haomeiwen.com/subject/wbyxxqtx.html