Skip to main content

视图渲染

组件渲染

渲染管线:https://cn.vuejs.org/guide/extras/rendering-mechanism.html#render-pipeline

  • 模板编译
  • mount。首次挂载
  • update。更新
    • pre。比如 watch、watchEffect
    • flushing。queueJob
    • post。比如 onMounted

批处理是怎么实现的?

每个 effect 会有一个 id 标识,相同 id 的 effect 会合并

生命周期

参考

模板编译

h --> createVNode --> 真实 DOM

现在有这样一个模板

<div id="app">
<p>{{name}}</p>
<p>{{age}}</p>
</div>

vue 会基于 AST 将其编译成 render 函数,该函数会返回一个虚拟 DOM 对象

function render() {
with (this) {
return _c(
"div",
{
attrs: {
id: "app",
},
},
[_c("p", [_v(_s(name))]), _c("p", [_v(_s(age))])]
);
}
}

slot 插槽

<div>
<slot name="header"></slot>
</div>

编译生成 render 函数如下:

import {
renderSlot as _renderSlot,
openBlock as _openBlock,
createElementBlock as _createElementBlock,
} from "vue";

export function render(_ctx) {
return (
_openBlock(),
_createElementBlock("div", null, [_renderSlot(_ctx.$slots, "header")])
);
}

nextTick

加入微任务队列

export function nextTick<T = void>(
this: T,
fn?: (this: T) => void
): Promise<void> {
const p = currentFlushPromise || resolvedPromise;
return fn ? p.then(this ? fn.bind(this) : fn) : p;
}

使用 nextTick 需要放在修改响应式数据之后,就是为了让 nextTick 的回调添加到微任务队列时,排在 flusobs 方法之后,保证能够在 nextTick 回调中拿到最新的 dom

参考

内置组件【WIP】

KeepAlive

参考 https://juejin.cn/post/7069422231387439111

  • 隐藏 DOM 节点,缓存实例(但是仍然会比较 props 的变化)
  • LRU 策略

Suspense

Transition

Teleport