vue-3.2.30\packages\vue\examples\composition新建test.html文件,内容如下:<script src="../../dist/vue.global.js"></script>
<div id="demo">
<section>
<h1>{{count}}</h1>
</section>
</div>
<script>
const { createApp, ref } = Vue
var app = createApp({
setup() {
const count = ref(1)
return { count }
}
})
app.mount('#demo')
</script>
ctrl + p,输入runtime-core/src/apiCreateApp.ts,回车找到该文件ctrl + f,输入function createAppAPI,回车找到该文件位置,在浏览器中给该位置打断点//用户执行了创建实例代码,其实是为了得到app实例对象,就是执行了一下函数createAppAPI内部返回的createApp方法,且返回app实例,app实例是一个对象,上面也挂载了mount等方法
var app = createApp({})
ctrl + f,输入const vnode = createVNode(,回车找到该文件位置,在浏览器中给该位置打断点ctrl + f,输入render(vnode, rootContainer, isSVG),回车找到该文件位置,在浏览器中给该位置打断点// 当执行挂载方法 就会触发步骤4 和 步骤5的断点
app.mount('#demo')
ctrl + p,输入runtime-core/src/renderer.ts,回车找到该文件ctrl + f,输入createAppAPI(render, hydrate),回车找到该文件位置,按住ctrl+左键点击render函数,找到render函数的声明的位置ctrl + f,输入patch(container._vnode,回车找到该文件位置,打上断点const render = (vnode, container, isSVG) => {// 首次vnode有值
if (vnode == null) {
if (container._vnode) {
unmount(container._vnode, null, null, true)
}
} else { // 首次container._vnode 没有值
patch(container._vnode || null, vnode, container, null, null, null, isSVG)
}
flushPostFlushCbs()
container._vnode = vnode // 首次container._vnode被赋值,供给下一次使用
}
ctrl + 左键,点击patch函数,找到patch函数声明的位置ctrl + f,输入processElement(,回车找到该文件位置,打上断点ctrl + f,输入processComponent(,回车找到该文件位置,打上断点Resume script execution,可以看到patch的递归过程ctrl + f,输入createComponentInstance(,回车找到该文件位置,打上断点,创建实例ctrl + f,输入setupComponent(instance),回车找到该文件位置,打上断点,初始化工作执行setup,并且将结果响应式化
ctrl + f,输入setupRenderEffect( , 回车找到该文件位置,打上断点,ctrl + p,输入runtime-core\src\component.ts,回车找到该文件,ctrl + f,输入proxyRefs(setupResult),回车找到该文件位置,打上断点,将setup函数执行的结果setupResult,做代理,然后赋值给instance.setupStateconst createApp = function(...args){
const app = ensureRenderer().createApp(...args)
const mount = app.mount
app.mount = function(v){
return mount(v)
}
return app
}
let renderer;
function ensureRenderer(){
return (renderer || renderer = createRenderer())
}
function createRenderer(){
return baseCreateRenderer()
}
function baseCreateRenderer(){
const render = (vnode,container,isSVG){
if(vnode == null){
if(container._vnode){
unmount(container._vnode,null,null,true)
} else{
patch(container._vnode || null,vnode,container,null,null,null,isSVG)
}
}
}
return {
render,
createApp:createAppAPI(render) // createApp()时,就会执行createAppAPI函数
}
}
function createAppAPI(render){
const context = createAppContext()
return function createApp(rootComponent,rootProps = null){ // createApp()时,返回app
const app = (context.app = {
mount(rootContainer){// 等到用户调用了app.mount()才会执行内部的mount函数
const vnode = createVNode(
rootComponent,
rootProps
)
render(vnode,rootContainer,isSVG)
}
})
return app
}
}
流程图
