v-7

2-12 createElement

还是接着_render方法讲:

vnode = render.call(vm._renderProxy, vm.$createElement)

之前讲了vm._renderProxy是怎么回事,现在学习一下vm.$createElement部分。
首先在core/instance/render.js中就可以看到vm.$creteElement的定义。

模板编译出来的代码会执行:

  vm._c = (a, b, c, d) => createElement(vm, a, b, c, d, false)

而我们用户手写的render函数会执行:

vm.$createElement = (a, b, c, d) => createElement(vm, a, b, c, d, true)

但其实无论是哪一块。最终都会执行createElement方法,区别在于最后一个参数。
createElement方法最终调用的是_createElement方法,相当于这里做了一层封装处理。

而_createElement的执行大概可以记为:

  1. 第一步是检查VNodeData是不是响应式的,vue定义vNode不能是响应式的。也就是说数据上不能存在_ob_,如果变量上存在_ob_说明这是一个响应式的。
  2. 如果是响应式的,就使用createEmptyVNode创建一个空的vnode
  3. 接下来会对children做一层normaliz。两个函数:simpleNormalizeChildren和normalizeChildren。第一个是假设render函数只有一层。第二个是假设有很多层然后借助normalizeArrayChildren递归的去使用。但其实两者的作用都是将render改为一维数组。

2-14 update 作用:将vnode渲染成真实dom。

首先看一下_update的实现方法在哪:core/instance/lifecycle.js

首先认清update在什么时期会执行1.初次渲染的时候会把vnode渲染成真实dom。2.之后的数据变化引起的视图dom的改变。

所以如果是首次加载的话,那么prevVnode其实是不存在的。所以会执行:

  vm.$el = vm.__patch__(vm.$el, vnode, hydrating, false /* removeOnly */)

那么patch方法便映入眼帘了。

patch方法的定义是在:platforms/web/runtime/index中进行挂载到Vue原型上的。

Vue.prototype.__patch__ = inBrowser ? patch : noop

export const patch: Function = createPatchFunction({ nodeOps, modules })
nodeOps:主要是封装一些操作dom的原声方法,modules:style class 相关的更改时的一些钩子函数的触发

当然作者在实现patch的时候使用一个技巧是函数颗粒化。我们只需要在初始化的时候使用到nodeOps, modules,没必要每次调用patch都需要初始化。所以这里使用了颗粒化的思想去解决这个问题。

接下来一个比较重要的函数是createElm。这个函数就是把vnode挂载到真实的dom上,先创建子节点,再创建父节点的一个过程

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lar_slw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值