import { createApp, h } from 'vue'
createApp({
data: () => ({ count: 3 }),
render() {
return h('div', { class: 'box' }, [
h('h1', {}, 'hello world' + this.count),
h('button', { onClick: () => this.count++ }, 'Click'),
h({
data:()=>({msg:'child'}),
render(){
return h('h2',{},this.msg)
}
})
])
}
}).mount('#app')
/*
h函数
- 参数1:标签名或者组件对象
- 参数2: 属性对象
- 参数3: 孩子(或者孩子构成的数组)
*/
查看虚拟DOM的运行情况
打印App:
这些东西是什么呢
实际上,在我们import App.vue的时候,vue-loader对App.vue进行了解析和处理,会分成三部分。
第一部分是模版的处理:他把所有的模版,都放在render函数里了
打印一下看看:
console.log(App.render.toString());
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_Child = _resolveComponent("Child")
return (_openBlock(), _createElementBlock("div", _hoisted_1, [
_createElementVNode("h1", null, "hello world " + _toDisplayString($data.count), 1 /* TEXT */),
_createElementVNode("button", {
onClick: _cache[0] || (_cache[0] = $event => ($data.count++))
}, "Add"),
_createVNode(_component_Child)
]))
}
比如说模版里面有div,他就createElementBlock div
其实就是模版进行解析之后,变成了一个渲染函数
这样的话,当我们通过任何方式去操作数据的时候(改变data),实际上会调用它render函数的执行。render函数的执行,会调用对应的方法,去创建虚拟dom的节点,虚拟dom会进行后续的diff操作,会去做patch,之后渲染成一个真实的dom
与vue3响应式的思考
这个是很关键的,比如说为什么在学vue响应式原理的时候,不理解effect到底是什么,到这里就明白了。effect就是这里的渲染函数(也可能是其中一种effect)。当跟踪到data的更新后,会通过proxy拦截并执行effect(渲染函数依赖到了data,data的proxy的setter就会执行渲染函数)
触发getter:存effect到deps里面
触发setter:遍历deps执行里面的effect