美文网首页
温故而知新之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