当前位置: 首页 > news >正文

建设网银登录网站哪些网站可以加锚文本

建设网银登录网站,哪些网站可以加锚文本,可以免费做宣传的网站,网站定制建设目录 说明组件是如何被缓存的,什么时候被激活对于KeepAlive 中组件 如何完成激活的对于KeepAlive 中组件 如何完成休眠的 总结 说明 Vue 内置了 KeepAlive 组件,实现缓存多个组件实例切换时,完成对卸载组件实例的缓存,从而使得组…

目录

  • 说明
    • 组件是如何被缓存的,什么时候被激活
    • 对于KeepAlive 中组件 如何完成激活的
    • 对于KeepAlive 中组件 如何完成休眠的
  • 总结

说明

Vue 内置了 KeepAlive 组件,实现缓存多个组件实例切换时,完成对卸载组件实例的缓存,从而使得组件实例在来会切换时不会被重复创建。

<template><KeepAlive> <component :is="xxx" /> </KeepAlive>
</template>

当动态组件在随着 xxx 变化时,如果没有 KeepAlive 做缓存,那么组件在来回切换时就会进行重复的实例化,这里就是通过 KeepAlive 实现了对不活跃组件的缓存,只有第一次加载会初始化 instance,后续会使用 缓存的 vnode 再强制patch 下 防止遗漏 有 组件 props 导致的更新,省略了(初始化 instance 和 全量生成组件dom 结构的过程)。

组件是如何被缓存的,什么时候被激活

先得看下 KeepAlive 的实现 ,它本身是一个抽象组件,会将子组件渲染出来

const KeepAliveImpl = {// 组件名称name: `KeepAlive`,// 区别于其他组件的标记__isKeepAlive: true,// 组件的 props 定义props: {include: [String, RegExp, Array],exclude: [String, RegExp, Array],max: [String, Number]},setup(props, {slots}) {// ...// setup 返回一个函数 就是 组件的render 函数 return () => {// ...}}

每次 子组件改变 就会触发 render 函数

看下 render 函数的详情

const KeepAliveImpl = {//...// cache sub tree after renderlet pendingCacheKey: CacheKey | null = nullconst cacheSubtree = () => {// fix #1621, the pendingCacheKey could be 0if (pendingCacheKey != null) {cache.set(pendingCacheKey, getInnerChild(instance.subTree))}}onMounted(cacheSubtree)onUpdated(cacheSubtree)onBeforeUnmount(() => {cache.forEach(cached => {const { subTree, suspense } = instanceconst vnode = getInnerChild(subTree)if (cached.type === vnode.type && cached.key === vnode.key) {// current instance will be unmounted as part of keep-alive's unmountresetShapeFlag(vnode)// but invoke its deactivated hook hereconst da = vnode.component!.dada && queuePostRenderEffect(da, suspense)return}unmount(cached)})})// ...setup(props, { slot }) {// ...return () => {// 记录需要被缓存的 keypendingCacheKey = null// ...// 获取子节点const children = slots.default()const rawVNode = children[0]if (children.length > 1) {// 子节点数量大于 1 个,不会进行缓存,直接返回current = nullreturn children} else if (!isVNode(rawVNode) ||(!(rawVNode.shapeFlag & ShapeFlags.STATEFUL_COMPONENT) &&!(rawVNode.shapeFlag & ShapeFlags.SUSPENSE))) {current = nullreturn rawVNode}// suspense 特殊处理,正常节点就是返回节点 vnodelet vnode = getInnerChild(rawVNode)const comp = vnode.type// 获取 Component.name 值const name = getComponentName(isAsyncWrapper(vnode) ? vnode.type.__asyncResolved || {} : comp)// 获取 props 中的属性const { include, exclude, max } = props// 如果组件 name 不在 include 中或者存在于 exclude 中,则直接返回if ((include && (!name || !matches(include, name))) ||(exclude && name && matches(exclude, name))) {current = vnodereturn rawVNode}// 缓存相关,定义缓存 keyconst key = vnode.key == null ? comp : vnode.key// 从缓存中取值const cachedVNode = cache.get(key)// clone vnode,因为需要重用if (vnode.el) {vnode = cloneVNode(vnode)if (rawVNode.shapeFlag & ShapeFlags.SUSPENSE) {rawVNode.ssContent = vnode}}// 给 pendingCacheKey 赋值,将在 beforeMount/beforeUpdate 中被使用pendingCacheKey = key// 如果存在缓存的 vnode 元素if (cachedVNode) {// 复制挂载状态// 复制 DOMvnode.el = cachedVNode.el// 复制 componentvnode.component = cachedVNode.component// 增加 shapeFlag 类型 COMPONENT_KEPT_ALIVEvnode.shapeFlag |= ShapeFlags.COMPONENT_KEPT_ALIVE// 把缓存的 key 移动到到队首keys.delete(key)keys.add(key)} else {// 如果缓存不存在,则添加缓存keys.add(key)// 如果超出了最大的限制,则移除最早被缓存的值if (max && keys.size > parseInt(max as string, 10)) {pruneCacheEntry(keys.values().next().value)}}// 增加 shapeFlag 类型 COMPONENT_SHOULD_KEEP_ALIVE,避免被卸载vnode.shapeFlag |= ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVEcurrent = vnode// 返回 vnode 节点return isSuspense(rawVNode.type) ? rawVNode : vnode}}
}

props.max 会确定 缓存组件的最大数量 默认没有上限,但是组件会占用内存 所以并不是 max越大越好
props.include 表示包含哪些组件可被缓存
props.exclude 表示排除那些组件

组件缓存的时机:
组件切换的时候 会保存 上一个组件的vnode 到 cache Map 中 key 是 vnode.key

组件卸载时机:
缓存组件数量超过max,会删除活跃度最低的缓存组件,或者 整个KeepAlive 组件被unmount的时候

对于KeepAlive 中组件 如何完成激活的

当 component 动态组件 is 参数发生改变时 ,

执行 KeepAlive组件 componentUpdateFn 就会执行 上一步的render 函数 会 生成 新的vnode (
然后再 走 patch
再走到 processComponent

再看下 processComponent中 针对 vnode.shapeFlag 为COMPONENT_KEPT_ALIVE(在keepalive render 函数中 组件类型 会被设置成COMPONENT_KEPT_ALIVE ) 有特殊处理

在这里插入图片描述
其中 parentComponent 其实指向的是 KeepAlive 组件, 得出 processComponent 实际调用的是 KeepAlive 组件上下文中的 activate 方法 去做挂载操作

 sharedContext.activate = (vnode, container, anchor, isSVG, optimized) => {const instance = vnode.component!// 先直接将 move(vnode, container, anchor, MoveType.ENTER, parentSuspense)// in case props have changedpatch(instance.vnode,vnode,container,anchor,instance,parentSuspense,isSVG,vnode.slotScopeIds,optimized)queuePostRenderEffect(() => {instance.isDeactivated = falseif (instance.a) {invokeArrayFns(instance.a)}const vnodeHook = vnode.props && vnode.props.onVnodeMountedif (vnodeHook) {invokeVNodeHook(vnodeHook, instance.parent, vnode)}}, parentSuspense)if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) {// Update components treedevtoolsComponentAdded(instance)}}

先直接将缓存的dom 先挂载到 container 下面(节约了 重新生成dom的 时间 ),在强制patch 一下 避免遗漏 有props 改变引发的更新。这时候 缓存的组件就被激活了。

对于KeepAlive 中组件 如何完成休眠的

<template><KeepAlive> <component :is="xxx" /> </KeepAlive>
</template>

is 发生改变 会导致 上一次的组件执行unmount 操作

const unmount = (vnode, parentComponent, parentSuspense, doRemove = false) => {// ...const { shapeFlag  } = vnodeif (shapeFlag & ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE) {;(parentComponent!.ctx as KeepAliveContext).deactivate(vnode)return}// ...
}

同理 也会走到。keepalive 上下文中的 deactivate 方法

sharedContext.deactivate = (vnode: VNode) => {const instance = vnode.component!move(vnode, storageContainer, null, MoveType.LEAVE, parentSuspense)queuePostRenderEffect(() => {if (instance.da) {invokeArrayFns(instance.da)}const vnodeHook = vnode.props && vnode.props.onVnodeUnmountedif (vnodeHook) {invokeVNodeHook(vnodeHook, instance.parent, vnode)}instance.isDeactivated = true}, parentSuspense)if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) {// Update components treedevtoolsComponentAdded(instance)}}

卸载态函数 deactivate 核心工作就是将页面中的 DOM 移动到一个隐藏不可见的容器 storageContainer 当中,这样页面中的元素就被移除了。当这一切都执行完成后,最后再通过 queuePostRenderEffect 函数,将用户定义的 onDeactivated 钩子放到状态更新流程后

总结

1.组件是通过类似于 LRU 的缓存机制来缓存的,并为缓存的组件 vnode 的 shapeFlag 属性打上 COMPONENT_KEPT_ALIVE 属性,当组件在 processComponent 挂载时,如果存在COMPONENT_KEPT_ALIVE 属性,则会执行激活函数,激活函数内执行具体的缓存节点挂载逻辑。

2.缓存不是越多越好,因为所有的缓存节点都会被存在 cache 中,如果过多,则会增加内存负担。

3.丢弃的方式就是在缓存重新被激活时,之前缓存的 key 会被重新添加到队首,标记为最近的一次缓存,如果缓存的实例数量即将超过指定的那个最大数量,则最久没有被访问的缓存实例将被丢弃。

http://www.yayakq.cn/news/346335/

相关文章:

  • 做外贸自己的公司网站新网站怎么做权重
  • 什么是网站风格策划的重点云南创网科技有限公司
  • 广东粤建设计院网站公司建一个网站
  • 网站建设验收评审标准西安手机网站建站
  • 网站建设 工作职责个人网站运营怎么做
  • 集团门户网站建设费用科目软文营销写作技巧有哪些?
  • 北京南昌企业网站制作淄博英文网站建设专业
  • 个人 可以做社交网站移动端网页界面设计
  • 网站建设是学哪个学科汕头提供关键词平台
  • 重庆网站建广州市公司网站建设平台
  • 网站怎么做才能让更多平台展现网站搭建教程
  • 山东省建设执业师之家官方网站wordpress 多demo
  • 无锡网站营销公司哪家好wordpress管理员与编辑可见
  • 徐州市制作网站常州做网站的
  • 网站建设翻译英文360建筑网怎么样
  • 网站头部seo范例门户网站建设管理总则
  • 做网站公奇闻司郑州汉狮微信小程序后台管理系统
  • 网站开发服务商平台做网站有什么书
  • 惠州附近公司做网站建设多少钱付公司制作网站费怎么做凭证
  • 上海网站建设推荐q479185700顶你做刷机网站赚钱吗
  • 游民星空是用什么做的网站餐饮公司网站建设
  • 国外有哪些优秀的网站沭阳三剑客做网站
  • 域名与网站建设net做公司网站
  • 现在建设网站都用什么软件微商城网站策划
  • 大连网站建设过程php网站语言切换功能如何做
  • 网站服务器租用多少钱才合理呢网站建站网站制作公司
  • 帝国网站网站手机版怎么做wordpress采集小红书
  • 大气金融投资企业网站模板.net做网站教程
  • 怎么用手机创建网站全新装修效果图大全
  • 西安网站开发软件中国旅游电子商务网站建设情况