• Vue2.0原理-模板解析


    下面这段代码,vue内部做了什么操作?我去源码里面找找看

    new Vue({
        el: '#app'
    })
    

    入口

    vue 的入口文件在 src/core/instance/index.js, 里面一进来就执行了很多初始化的操作。

    import { initMixin } from './init'
    import { stateMixin } from './state'
    import { renderMixin } from './render'
    import { eventsMixin } from './events'
    import { lifecycleMixin } from './lifecycle'
    import { warn } from '../util/index'
    
    function Vue (options) {
      if (process.env.NODE_ENV !== 'production' &&
        !(this instanceof Vue)
      ) {
        warn('Vue is a constructor and should be called with the `new` keyword')
      }
      this._init(options)
    }
    
    initMixin(Vue)
    stateMixin(Vue)
    eventsMixin(Vue)
    lifecycleMixin(Vue)
    renderMixin(Vue)
    
    export default Vue
    

    进入 initMixin 方法看看,这个方法内部只做了一件事,定义 Vue.prototype._init , 这个 _init 方法又做了什么呢?

    ...
    // 各种初始化开始
    initProxy(vm)
    initLifecycle(vm)
    initEvents(vm)
    initRender(vm)
    callHook(vm, 'beforeCreate')
    initInjections(vm) // resolve injections before data/props
    initState(vm)
    initProvide(vm) // resolve provide after data/props
    callHook(vm, 'created')
    // 各种初始化完毕
    ...
    // 解析模板
    if (vm.$options.el) {
      vm.$mount(vm.$options.el)
    }
    

    解析

    进入 src/platforms/web/entry-runtime-with-compiler.js 文件,看看 $mount 方法是怎么处理模板的。

    • 判断 el 是否为body或者html根节点,是的话,提示错误。
      if (el === document.body || el === document.documentElement) {
        process.env.NODE_ENV !== 'production' && warn(
          `Do not mount Vue to <html> or <body> - mount to normal elements instead.`
        )
        return this
      }
    
    • 如果没有render函数,则开始解析模板
    // 模板也分为多种
    1,当使用 template 属性时,支持:
        1.1, 字符串模板
        1.2,一个script模板的id
        1.3,一个dom对象
    
    2,当使用 el 属性时,获取对应dom的outerHTML 作为template
    
    
    • 调用 src/compiler/index.js 对模板进行AST解析和静态优化,并重建render方法

    对于模板解析,这篇文章分析的很详细 Vue 模板编译原理

    • 在解析完模板之后,调用的是 runtime/index.js 中的 $mount 方法。

    $mount 方法调用 src/core/instance/lifecycle.js 中的 mountComponent 方法

    mountComponent() {
        // 1,经过上面的一系列初始化动作,render肯定已经有了,如果没有,返回一个节点并警告。
        callHook(vm, 'beforeMount')
        // 2,通过vm._render()方法把模板转化成vNode
        // 3,通过vm._update()更新dom节点
        callHook(vm, 'mounted')
    }
    

    和VUE1的区别

    在vue1.0种,模板的解析是通过 createDocumentFragment 对dom进行代理实现的,到了2.0时代,考虑到服务端渲染,采用了jquery作者开发的 html-parse 库进行字符串模板解析。

  • 相关阅读:
    Flask + WSGI + Nginx 环境
    sql字段合并与分组聚合
    杭州优科豪马轮胎有限公司北京经销商
    国家与大洲对应关系json数据
    【C#】编码史记
    【C#】Unicode的流言终结者和编码大揭秘
    【WPF】生成二维码
    【WPF】WriteableBitmap和BitmapImage的相互转换
    TPL之延续任务
    【C#】日期格式转换
  • 原文地址:https://www.cnblogs.com/small-coder/p/9177817.html
Copyright © 2020-2023  润新知