国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁(yè) > news >正文

怎么做網(wǎng)站計(jì)劃寧波企業(yè)網(wǎng)站seo

怎么做網(wǎng)站計(jì)劃,寧波企業(yè)網(wǎng)站seo,學(xué)服裝設(shè)計(jì)后悔死了,全國(guó)十大數(shù)字展館設(shè)計(jì)公司目錄 說(shuō)明組件是如何被緩存的,什么時(shí)候被激活對(duì)于KeepAlive 中組件 如何完成激活的對(duì)于KeepAlive 中組件 如何完成休眠的 總結(jié) 說(shuō)明 Vue 內(nèi)置了 KeepAlive 組件,實(shí)現(xiàn)緩存多個(gè)組件實(shí)例切換時(shí),完成對(duì)卸載組件實(shí)例的緩存,從而使得組…

目錄

  • 說(shuō)明
    • 組件是如何被緩存的,什么時(shí)候被激活
    • 對(duì)于KeepAlive 中組件 如何完成激活的
    • 對(duì)于KeepAlive 中組件 如何完成休眠的
  • 總結(jié)

說(shuō)明

Vue 內(nèi)置了 KeepAlive 組件,實(shí)現(xiàn)緩存多個(gè)組件實(shí)例切換時(shí),完成對(duì)卸載組件實(shí)例的緩存,從而使得組件實(shí)例在來(lái)會(huì)切換時(shí)不會(huì)被重復(fù)創(chuàng)建。

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

當(dāng)動(dòng)態(tài)組件在隨著 xxx 變化時(shí),如果沒(méi)有 KeepAlive 做緩存,那么組件在來(lái)回切換時(shí)就會(huì)進(jìn)行重復(fù)的實(shí)例化,這里就是通過(guò) KeepAlive 實(shí)現(xiàn)了對(duì)不活躍組件的緩存,只有第一次加載會(huì)初始化 instance,后續(xù)會(huì)使用 緩存的 vnode 再?gòu)?qiáng)制patch 下 防止遺漏 有 組件 props 導(dǎo)致的更新,省略了(初始化 instance 和 全量生成組件dom 結(jié)構(gòu)的過(guò)程)。

組件是如何被緩存的,什么時(shí)候被激活

先得看下 KeepAlive 的實(shí)現(xiàn) ,它本身是一個(gè)抽象組件,會(huì)將子組件渲染出來(lái)

const KeepAliveImpl = {// 組件名稱name: `KeepAlive`,// 區(qū)別于其他組件的標(biāo)記__isKeepAlive: true,// 組件的 props 定義props: {include: [String, RegExp, Array],exclude: [String, RegExp, Array],max: [String, Number]},setup(props, {slots}) {// ...// setup 返回一個(gè)函數(shù) 就是 組件的render 函數(shù) return () => {// ...}}

每次 子組件改變 就會(huì)觸發(fā) render 函數(shù)

看下 render 函數(shù)的詳情

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// ...// 獲取子節(jié)點(diǎn)const children = slots.default()const rawVNode = children[0]if (children.length > 1) {// 子節(jié)點(diǎn)數(shù)量大于 1 個(gè),不會(huì)進(jìn)行緩存,直接返回current = nullreturn children} else if (!isVNode(rawVNode) ||(!(rawVNode.shapeFlag & ShapeFlags.STATEFUL_COMPONENT) &&!(rawVNode.shapeFlag & ShapeFlags.SUSPENSE))) {current = nullreturn rawVNode}// suspense 特殊處理,正常節(jié)點(diǎn)就是返回節(jié)點(diǎn) 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}// 緩存相關(guān),定義緩存 keyconst key = vnode.key == null ? comp : vnode.key// 從緩存中取值const cachedVNode = cache.get(key)// clone vnode,因?yàn)樾枰赜?/span>if (vnode.el) {vnode = cloneVNode(vnode)if (rawVNode.shapeFlag & ShapeFlags.SUSPENSE) {rawVNode.ssContent = vnode}}// 給 pendingCacheKey 賦值,將在 beforeMount/beforeUpdate 中被使用pendingCacheKey = key// 如果存在緩存的 vnode 元素if (cachedVNode) {// 復(fù)制掛載狀態(tài)// 復(fù)制 DOMvnode.el = cachedVNode.el// 復(fù)制 componentvnode.component = cachedVNode.component// 增加 shapeFlag 類型 COMPONENT_KEPT_ALIVEvnode.shapeFlag |= ShapeFlags.COMPONENT_KEPT_ALIVE// 把緩存的 key 移動(dòng)到到隊(duì)首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 節(jié)點(diǎn)return isSuspense(rawVNode.type) ? rawVNode : vnode}}
}

props.max 會(huì)確定 緩存組件的最大數(shù)量 默認(rèn)沒(méi)有上限,但是組件會(huì)占用內(nèi)存 所以并不是 max越大越好
props.include 表示包含哪些組件可被緩存
props.exclude 表示排除那些組件

組件緩存的時(shí)機(jī):
組件切換的時(shí)候 會(huì)保存 上一個(gè)組件的vnode 到 cache Map 中 key 是 vnode.key

組件卸載時(shí)機(jī):
緩存組件數(shù)量超過(guò)max,會(huì)刪除活躍度最低的緩存組件,或者 整個(gè)KeepAlive 組件被unmount的時(shí)候

對(duì)于KeepAlive 中組件 如何完成激活的

當(dāng) component 動(dòng)態(tài)組件 is 參數(shù)發(fā)生改變時(shí) ,

執(zhí)行 KeepAlive組件 componentUpdateFn 就會(huì)執(zhí)行 上一步的render 函數(shù) 會(huì) 生成 新的vnode (
然后再 走 patch
再走到 processComponent

再看下 processComponent中 針對(duì) vnode.shapeFlag 為COMPONENT_KEPT_ALIVE(在keepalive render 函數(shù)中 組件類型 會(huì)被設(shè)置成COMPONENT_KEPT_ALIVE ) 有特殊處理

在這里插入圖片描述
其中 parentComponent 其實(shí)指向的是 KeepAlive 組件, 得出 processComponent 實(shí)際調(diào)用的是 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 下面(節(jié)約了 重新生成dom的 時(shí)間 ),在強(qiáng)制patch 一下 避免遺漏 有props 改變引發(fā)的更新。這時(shí)候 緩存的組件就被激活了。

對(duì)于KeepAlive 中組件 如何完成休眠的

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

is 發(fā)生改變 會(huì)導(dǎo)致 上一次的組件執(zhí)行unmount 操作

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

同理 也會(huì)走到。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)}}

卸載態(tài)函數(shù) deactivate 核心工作就是將頁(yè)面中的 DOM 移動(dòng)到一個(gè)隱藏不可見(jiàn)的容器 storageContainer 當(dāng)中,這樣頁(yè)面中的元素就被移除了。當(dāng)這一切都執(zhí)行完成后,最后再通過(guò) queuePostRenderEffect 函數(shù),將用戶定義的 onDeactivated 鉤子放到狀態(tài)更新流程后

總結(jié)

1.組件是通過(guò)類似于 LRU 的緩存機(jī)制來(lái)緩存的,并為緩存的組件 vnode 的 shapeFlag 屬性打上 COMPONENT_KEPT_ALIVE 屬性,當(dāng)組件在 processComponent 掛載時(shí),如果存在COMPONENT_KEPT_ALIVE 屬性,則會(huì)執(zhí)行激活函數(shù),激活函數(shù)內(nèi)執(zhí)行具體的緩存節(jié)點(diǎn)掛載邏輯。

2.緩存不是越多越好,因?yàn)樗械木彺婀?jié)點(diǎn)都會(huì)被存在 cache 中,如果過(guò)多,則會(huì)增加內(nèi)存負(fù)擔(dān)。

3.丟棄的方式就是在緩存重新被激活時(shí),之前緩存的 key 會(huì)被重新添加到隊(duì)首,標(biāo)記為最近的一次緩存,如果緩存的實(shí)例數(shù)量即將超過(guò)指定的那個(gè)最大數(shù)量,則最久沒(méi)有被訪問(wèn)的緩存實(shí)例將被丟棄。

http://aloenet.com.cn/news/45429.html

相關(guān)文章:

  • 凡科做網(wǎng)站友情鏈接怎么做百度seo刷排名網(wǎng)址
  • 網(wǎng)站建設(shè)私單合同seo建站系統(tǒng)
  • 織夢(mèng)制作手機(jī)網(wǎng)站模板泉州關(guān)鍵詞優(yōu)化軟件
  • 獵頭做mapping網(wǎng)站百度關(guān)鍵詞查詢排名
  • 做文件的網(wǎng)站手機(jī)免費(fèi)建站系統(tǒng)
  • 公司網(wǎng)站開(kāi)發(fā)流程百度首頁(yè)純凈版
  • 長(zhǎng)沙網(wǎng)頁(yè)設(shè)計(jì)網(wǎng)站seo是什么意思
  • 泰興做網(wǎng)站公司外貿(mào)營(yíng)銷平臺(tái)
  • 網(wǎng)站中醫(yī)建設(shè)搜索引擎推廣的基本方法有
  • 搭建網(wǎng)站的流程和方法濰坊做網(wǎng)站哪家好
  • 站酷網(wǎng)下載武漢seo關(guān)鍵字優(yōu)化
  • 天津做做網(wǎng)站公眾號(hào)運(yùn)營(yíng)
  • 免費(fèi)海報(bào)在線制作網(wǎng)站河南鄭州最新消息
  • 公司網(wǎng)站怎么更新維護(hù)搜外滴滴友鏈
  • 網(wǎng)站 框架網(wǎng)頁(yè)建設(shè)軟文的概念是什么
  • 招聘網(wǎng)站源碼下載色盲測(cè)試圖
  • 精品課程網(wǎng)站建設(shè)論文重慶網(wǎng)站seo技術(shù)
  • 本地網(wǎng)站建設(shè)電話線上營(yíng)銷課程
  • 晉中網(wǎng)站開(kāi)發(fā)關(guān)鍵詞智能優(yōu)化排名
  • 申請(qǐng)一個(gè)域名可以做多少網(wǎng)站廣東seo外包服務(wù)
  • 專業(yè)網(wǎng)站制作設(shè)計(jì)公司哪家好sem培訓(xùn)班
  • 淄博市臨淄區(qū)建設(shè)局網(wǎng)站哪些網(wǎng)站推廣不收費(fèi)
  • 濰坊專業(yè)空心活塞桿win10優(yōu)化大師有用嗎
  • 天長(zhǎng)企業(yè)網(wǎng)站制作軟件開(kāi)發(fā)公司有哪些
  • 網(wǎng)站被人做跳轉(zhuǎn)了民生熱點(diǎn)新聞
  • app開(kāi)發(fā)和網(wǎng)站建設(shè)區(qū)別怎么注冊(cè)一個(gè)自己的網(wǎng)站
  • 怎么用電腦做網(wǎng)站寧波優(yōu)化系統(tǒng)
  • 校園網(wǎng)站建設(shè)的意義百度云官網(wǎng)登錄首頁(yè)
  • 深圳微信網(wǎng)站app拉新渠道
  • 做app網(wǎng)站制作上海牛巨微網(wǎng)絡(luò)科技有限公司