image.png

  1. import { createApp, h } from 'vue'
  2. createApp({
  3. data: () => ({ count: 3 }),
  4. render() {
  5. return h('div', { class: 'box' }, [
  6. h('h1', {}, 'hello world' + this.count),
  7. h('button', { onClick: () => this.count++ }, 'Click'),
  8. h({
  9. data:()=>({msg:'child'}),
  10. render(){
  11. return h('h2',{},this.msg)
  12. }
  13. })
  14. ])
  15. }
  16. }).mount('#app')
  17. /*
  18. h函数
  19. - 参数1:标签名或者组件对象
  20. - 参数2: 属性对象
  21. - 参数3: 孩子(或者孩子构成的数组)
  22. */

查看虚拟DOM的运行情况

image.png

打印App:
image.png
这些东西是什么呢
实际上,在我们import App.vue的时候,vue-loader对App.vue进行了解析和处理,会分成三部分。
第一部分是模版的处理:他把所有的模版,都放在render函数里了
打印一下看看:

console.log(App.render.toString());
  1. function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
  2. const _component_Child = _resolveComponent("Child")
  3. return (_openBlock(), _createElementBlock("div", _hoisted_1, [
  4. _createElementVNode("h1", null, "hello world " + _toDisplayString($data.count), 1 /* TEXT */),
  5. _createElementVNode("button", {
  6. onClick: _cache[0] || (_cache[0] = $event => ($data.count++))
  7. }, "Add"),
  8. _createVNode(_component_Child)
  9. ]))
  10. }

比如说模版里面有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