打开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方法