内建组件
白菜 2025/3/11 Vue3组件
# KeepAlive
keepAlive 是为了避免频繁的销毁,创建带来的性能消耗。它的本质是缓存管理,加上特殊的挂载/卸载逻辑。
- 缓存当前的实例
- 构建一个隐藏容器,失活时从移动到隐藏容器中,激活时从隐藏容器中复原
- 默认插槽即是被缓存的组件
- 组件挂载时,尝试从缓存中读取,读取到了,则说明挂载过了,需要激活;没有读取到,则添加到缓存中
vnode添加shouldKeepAlive标识,在组件卸载的时候,只是让其时活,而并非真的卸载- 为组件添加
keptAlive标识,如果存在,在挂载的时候,让其激活,不会触发组件的挂载逻辑 props接收include,exclude,max属性,控制组件的缓存
# Teleport
通常情况下,将虚拟 DOM 渲染为真实 DOM 时,最终渲染的真层 DOM 的层级结构与虚拟 DOM 的层级结构一致。
<div id="box" style="z-index: -1;">
<Overlay />
</div>
这个例子中,即使 Overlay 的层级再高,他也无法遮挡父级的内容。如果可以把 Overlay 渲染到 body 上,那么 Overlay 就可以覆盖整个页面。
- 含有
__isTeleport标识的组件类型,process函数处理渲染逻辑 - 如果旧的节点
n1不存在,则全部挂载,否则执行更新 - 更新可能是
to属性变化引起的,需要对比to属性,如果变化了,则需要对内容进行移动处理
Teleport/TeleportImpl (opens new window)
# Transition
原理:
- 当 DOM 被挂载时,将动效附加到该元素上,
- 当 DOM 被卸载时,等附加到该元素上的动效执行完毕后,再卸载该元素。
他本身不会渲染任何额外的内容,只是通过默认插槽读取过渡元素,并渲染。
它的作用就是在过度元素的虚拟节点上添加 transform 相关的钩子函数。
实现:
- 基于虚拟 DOM 实现的,整个过程分为 3 个大阶段, before, leave, appear, 每个阶段分为 4 个部分,比如:beforeEnter, enter, afterEnter, enterCancelled
- 在挂载阶段,会根据节点来判断是否需要添加动效,则调用 transform.beforeEnter 钩子函数,在卸载阶段,则调用 transform.afterLeave 钩子函数
const transition = {
neame: 'transition',
setup(props, { slots }) {
return () => {
const innerVnode = slots.default()
innerVnode.transition = {
beforeEnter(el) {
// 设置初始状态
el.classList.add('enter-from')
el.classList.add('enter-active')
},
enter(el){
// 下一帧切换到结束
nextFrame(()=>{
el.classList.remove('enter-from')
el.classList.add('enter-to')
// 监听过渡结束
el.addEventListener('transitionend', ()=>{
el.classList.remove('enter-to')
el.classList.remove('enter-active')
})
})
},
leave(){
// 重置初始状态
el.classList.add('enter-from')
el.classList.add('enter-active')
// 强制 reflow ,使初始状态生效
document.body.offsetHeight
nextFrame(()=>{
el.classList.remove('enter-from')
el.classList.add('enter-to')
el.addEventListener('transitionend', ()=>{
el.classList.remove('enter-to')
el.classList.remove('enter-active')
// 调用 transform.leave 钩子的函数的第二个参数,完成 dom 的卸载
performRemove()
})
})
}
}
}
}
}