真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

keep-alive組件的緩存原理是什么-創(chuàng)新互聯(lián)

本篇文章為大家展示了keep-alive組件的緩存原理是什么,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過(guò)這篇文章的詳細(xì)介紹希望你能有所收獲。

網(wǎng)頁(yè)設(shè)計(jì)是網(wǎng)站建設(shè)的前奏,好的網(wǎng)頁(yè)設(shè)計(jì)更深度的剖析產(chǎn)品和設(shè)計(jì)風(fēng)格定位,結(jié)合最新的網(wǎng)頁(yè)設(shè)計(jì)流行趨勢(shì),與WVI應(yīng)用標(biāo)準(zhǔn),設(shè)計(jì)出具企業(yè)表現(xiàn)力,大器而深穩(wěn)的網(wǎng)站界面設(shè)。成都創(chuàng)新互聯(lián)公司公司2013年成立,是成都網(wǎng)站建設(shè)公司:提供企業(yè)網(wǎng)站設(shè)計(jì),高端網(wǎng)站設(shè)計(jì),營(yíng)銷(xiāo)型企業(yè)網(wǎng)站建設(shè)方案,響應(yīng)式網(wǎng)站設(shè)計(jì),小程序制作,專(zhuān)業(yè)建站公司做網(wǎng)站。

官方API介紹和用法


  • 包裹動(dòng)態(tài)組件時(shí),會(huì)緩存不活動(dòng)的組件實(shí)例,而不是銷(xiāo)毀它們。

  • 相似, 是一個(gè)抽象組件:它自身不會(huì)渲染一個(gè) DOM 元素,也不會(huì)出現(xiàn)在組件的父組件鏈中。

  • 當(dāng)組件在 內(nèi)被切換,它的 activated 和 deactivated 這兩個(gè)生命周期鉤子函數(shù)將會(huì)被對(duì)應(yīng)執(zhí)行。

官網(wǎng)的例子是 tab 切換保存了用戶(hù)的操作,實(shí)際中還可能遇到從列表頁(yè)跳轉(zhuǎn)去了詳情頁(yè),再跳轉(zhuǎn)回列表頁(yè)需要保存用戶(hù)進(jìn)行過(guò)的篩選操作,這就需要用到 ,這樣也能避免重新渲染,提高頁(yè)面性能。


用法及props的講解

// keep-alive組件搭配動(dòng)態(tài)組件的用法,還要其他的用法參見(jiàn)官網(wǎng)

 
  • include - 字符串或正則表達(dá)式或數(shù)組,name匹配上的組件會(huì)被緩存

  • exclude - 字符串或正則表達(dá)式或數(shù)組,name匹配上的組件都不會(huì)被緩存

  • max - 字符串或數(shù)字,緩存組件實(shí)例的較大數(shù),最久沒(méi)有被訪問(wèn)的實(shí)例會(huì)被銷(xiāo)毀掉


注意:


  • 只渲染其直系的一個(gè)組件,因此若在 中用 v-for,則其不會(huì)工作,若多條件判斷有多個(gè)符合條件也同理不工作。

  • include 和 exclude 匹配時(shí),首先檢查組件的 name 選項(xiàng),若 name 選項(xiàng)不可用,則匹配它的局部注冊(cè)名稱(chēng) (即父組件 components 選項(xiàng)的鍵值)。匿名組件不能被匹配。

  • 不會(huì)在函數(shù)式組件中正常工作,因?yàn)樗鼈儧](méi)有緩存實(shí)例。

源碼解讀

先貼一張?jiān)创a圖

keep-alive組件的緩存原理是什么

總共125行,收起來(lái)一看其實(shí)東西也比較少。前面是引入一些需要用到的方法,然后定義了一些  keep-alive 組件自己會(huì)用到的一些方法,最后就是向外暴露一個(gè) name 為 keep-alive 的組件選項(xiàng),這些選項(xiàng)除了 abstract 外,其他的我們都比較熟悉了,其中, render 函數(shù)就是緩存原理最重要的部分,也能看出 keep-alive 組件是一個(gè)函數(shù)式組件。


// isRegExp函數(shù)判斷是不是正則表達(dá)式,remove移除數(shù)組中的某一個(gè)成員
// getFirstComponentChild獲取VNode數(shù)組的第一個(gè)有效組件
import { isRegExp, remove } from 'shared/util'
import { getFirstComponentChild } from 'core/vdom/helpers/index'

type VNodeCache = { [key: string]: ?VNode }; // 緩存組件VNode的緩存類(lèi)型

// 通過(guò)組件的name或組件tag來(lái)獲取組件名(上面注意的第二點(diǎn))
function getComponentName (opts: ?VNodeComponentOptions): ?string {
 return opts && (opts.Ctor.options.name || opts.tag)
}

// 判斷include或exclude跟組件的name是否匹配成功
function matches (pattern: string | RegExp | Array, name: string): boolean {
 if (Array.isArray(pattern)) {
 return pattern.indexOf(name) > -1 // include或exclude是數(shù)組的情況
 } else if (typeof pattern === 'string') {
 return pattern.split(',').indexOf(name) > -1 // include或exclude是字符串的情況
 } else if (isRegExp(pattern)) {
 return pattern.test(name) // include或exclude是正則表達(dá)式的情況
 }
 return false // 都沒(méi)匹配上(上面注意的二三點(diǎn))
}

// 銷(xiāo)毀緩存
function pruneCache (keepAliveInstance: any, filter: Function) {
 const { cache, keys, _vnode } = keepAliveInstance // keep-alive組件實(shí)例
 for (const key in cache) {
 const cachedNode: ?VNode = cache[key] // 已經(jīng)被緩存的組件
 if (cachedNode) {
  const name: ?string = getComponentName(cachedNode.componentOptions)
  // 若name存在且不能跟include或exclude匹配上就銷(xiāo)毀這個(gè)已經(jīng)緩存的組件
  if (name && !filter(name)) {
  pruneCacheEntry(cache, key, keys, _vnode)
  }
 }
 }
}

// 銷(xiāo)毀緩存的入口
function pruneCacheEntry (
 cache: VNodeCache,
 key: string,
 keys: Array,
 current?: VNode
) {
 const cached = cache[key] // 被緩存過(guò)的組件
 // “已經(jīng)被緩存的組件是否繼續(xù)被緩存” 有變動(dòng)時(shí)
 // 若組件被緩存命中過(guò)且當(dāng)前組件不存在或緩存命中組件的tag和當(dāng)前組件的tag不相等
 if (cached && (!current || cached.tag !== current.tag)) {
 // 說(shuō)明現(xiàn)在這個(gè)組件不需要被繼續(xù)緩存,銷(xiāo)毀這個(gè)組件實(shí)例
 cached.componentInstance.$destroy()
 }
 cache[key] = null // 把緩存中這個(gè)組件置為null
 remove(keys, key) // 把這個(gè)組件的key移除出keys數(shù)組
}

// 示例類(lèi)型
const patternTypes: Array = [String, RegExp, Array]

// 向外暴露keep-alive組件的一些選項(xiàng)
export default {
 name: 'keep-alive', // 組件名
 abstract: true, // keep-alive是抽象組件

 // 用keep-alive組件時(shí)傳入的三個(gè)props
 props: {
 include: patternTypes,
 exclude: patternTypes,
 max: [String, Number]
 },

 created () {
 this.cache = Object.create(null) // 存儲(chǔ)需要緩存的組件
 this.keys = [] // 存儲(chǔ)每個(gè)需要緩存的組件的key,即對(duì)應(yīng)this.cache對(duì)象中的鍵值
 },

 // 銷(xiāo)毀keep-alive組件的時(shí)候,對(duì)緩存中的每個(gè)組件執(zhí)行銷(xiāo)毀
 destroyed () {
 for (const key in this.cache) {
  pruneCacheEntry(this.cache, key, this.keys)
 }
 },

 // keep-alive組件掛載時(shí)監(jiān)聽(tīng)include和exclude的變化,條件滿(mǎn)足時(shí)就銷(xiāo)毀已緩存的組件
 mounted () {
 this.$watch('include', val => {
  pruneCache(this, name => matches(val, name))
 })
 this.$watch('exclude', val => {
  pruneCache(this, name => !matches(val, name))
 })
 },

 // 重點(diǎn)來(lái)了
 render () {
 const slot = this.$slots.default // keep-alive組件的默認(rèn)插槽
 const vnode: VNode = getFirstComponentChild(slot) // 獲取默認(rèn)插槽的第一個(gè)有效組件
 // 如果vnode存在就取vnode的選項(xiàng)
 const componentOptions: ?VNodeComponentOptions = vnode && vnode.componentOptions
 if (componentOptions) {
  //獲取第一個(gè)有效組件的name
  const name: ?string = getComponentName(componentOptions)
  const { include, exclude } = this // props傳遞來(lái)的include和exclude
  if (
  // 若include存在且name不存在或name未匹配上
  (include && (!name || !matches(include, name))) ||
  // 若exclude存在且name存在或name匹配上
  (exclude && name && matches(exclude, name))
  ) {
  return vnode // 說(shuō)明不用緩存,直接返回這個(gè)組件進(jìn)行渲染
  }
  
  // 匹配上就需要進(jìn)行緩存操作
  const { cache, keys } = this // keep-alive組件的緩存組件和緩存組件對(duì)應(yīng)的key
  // 獲取第一個(gè)有效組件的key
  const key: ?string = vnode.key == null
  // 同一個(gè)構(gòu)造函數(shù)可以注冊(cè)為不同的本地組件
  // 所以?xún)H靠cid是不夠的,進(jìn)行拼接一下
  ? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '')
  : vnode.key
  // 如果這個(gè)組件命中緩存
  if (cache[key]) {
  // 這個(gè)組件的實(shí)例用緩存中的組件實(shí)例替換
  vnode.componentInstance = cache[key].componentInstance
  // 更新當(dāng)前key在keys中的位置
  remove(keys, key) // 把當(dāng)前key從keys中移除
  keys.push(key) // 再放到keys的末尾
  } else {
  // 如果沒(méi)有命中緩存,就把這個(gè)組件加入緩存中
  cache[key] = vnode
  keys.push(key) // 把這個(gè)組件的key放到keys的末尾
  // 如果緩存中的組件個(gè)數(shù)超過(guò)傳入的max,銷(xiāo)毀緩存中的LRU組件
  if (this.max && keys.length > parseInt(this.max)) {
   pruneCacheEntry(cache, keys[0], keys, this._vnode)
  }
  }

  vnode.data.keepAlive = true // 設(shè)置這個(gè)組件的keepAlive屬性為true
 }
 // 若第一個(gè)有效的組件存在,但其componentOptions不存在,就返回這個(gè)組件進(jìn)行渲染
 // 或若也不存在有效的第一個(gè)組件,但keep-alive組件的默認(rèn)插槽存在,就返回默認(rèn)插槽的第一個(gè)組件進(jìn)行渲染
 return vnode || (slot && slot[0])
 }
}

上述內(nèi)容就是keep-alive組件的緩存原理是什么,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。


當(dāng)前題目:keep-alive組件的緩存原理是什么-創(chuàng)新互聯(lián)
本文URL:http://weahome.cn/article/dgppei.html

其他資訊

在線咨詢(xún)

微信咨詢(xún)

電話(huà)咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部