学vue源码-createApp

7 阅读1分钟

打开packages\vue\examples\transition\modal.html文件;
断点分析
位置packages\runtime-dom\src\index.ts

  debugger
  
  const app = ensureRenderer().createApp(...args)

  if (__DEV__) {
    // 判断是否是原生标签
    injectNativeTagCheck(app)
    // 注入编译选项检查
    injectCompilerOptionsCheck(app)
  }

  const { mount } = app
  // 重写 mount 方法 containerOrSelector为挂载容器
  app.mount = (containerOrSelector: Element | ShadowRoot | string): any => {
    const container = normalizeContainer(containerOrSelector)
    if (!container) return
    // 获取组件 createApp的参数
    const component = app._component
    if (!isFunction(component) && !component.render && !component.template) {
      // __UNSAFE__
      // Reason: potential execution of JS expressions in in-DOM template.
      // The user must make sure the in-DOM template is trusted. If it's
      // rendered by the server, the template should not contain any user data.
      component.template = container.innerHTML
      // 2.x compat check
      if (__COMPAT__ && __DEV__ && container.nodeType === 1) {
        for (let i = 0; i < (container as Element).attributes.length; i++) {
          const attr = (container as Element).attributes[i]
          if (attr.name !== 'v-cloak' && /^(v-|:|@)/.test(attr.name)) {
            compatUtils.warnDeprecation(
              DeprecationTypes.GLOBAL_MOUNT_CONTAINER,
              null,
            )
            break
          }
        }
      }
    }

    // clear content before mounting
    // 重置挂载容器
    // 如果是元素节点,清空内容
    // nodeType 1 元素节点
    // nodeType 3 文本节点
    // nodeType 8 注释节点
    // nodeType 9 document
    // nodeType 11 documentFragment
    // nodeType 12 doctype
    // nodeType 2 属性节点
    //  nodeType 4 CDATASection
    //  nodeType 5 entityReference
    //  nodeType 6 entity
    //  nodeType 7 processingInstruction
    //  nodeType 10 documentType
    if (container.nodeType === 1) {
      container.textContent = ''
    }
    // 挂载组件
    const proxy = mount(container, false, resolveRootNamespace(container))
    if (container instanceof Element) {
      container.removeAttribute('v-cloak')
      container.setAttribute('data-v-app', '')
    }
    return proxy
  }

  return app
}) as CreateAppFunction<Element>

总结:
1.生成app对象
2.开发环境中添加函数来判断标签是否是原生标签;注入编译选项检查
3.重写mount方法