1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        請(qǐng)闡述keep-alive組件的作用和原理

        共 3765字,需瀏覽 8分鐘

         ·

        2021-06-01 03:50



        前端獵手
         鏈接每一位開發(fā)者,讓編程更有趣兒!
        關(guān)注


        ?? keep-alive 作用

        keep-live組件是vue的內(nèi)部組件,主要用于緩存內(nèi)部組件實(shí)例。這樣做的目的在于keep-alive內(nèi)部組件切換時(shí),不需要重新創(chuàng)建組件實(shí)例,比如說使用v-if來決定在滿足什么條件下使用哪個(gè)組件,還有就是路由切換,有個(gè)<router-view></router-view>,它會(huì)根據(jù)路由的配置,將選擇其中一個(gè)組件渲染到這個(gè)位置,當(dāng)路由切換后,當(dāng)前組件銷毀,它又會(huì)渲染另一個(gè)組件。

        如果將keep-alive嵌套在最外層,就像這樣:

        <keepAlive>
            <Component1 v-if="xxx"/>
            <Component2 v-else-if="xxx"/>
            <Component1 v-else/>
        </KeepAlive>

        這樣keepAlive內(nèi)部的組件來回切換時(shí),就不需要重新創(chuàng)建組件實(shí)例,而是直接使用緩存中的實(shí)例,一方面可以避免創(chuàng)建組件帶來的效率開銷,另一方面可以保留組件的狀態(tài)。但同時(shí)也有不好的地方,就是當(dāng)組件里面包含大量的內(nèi)容的時(shí)候會(huì)占用更多的內(nèi)存空間,keepAlive相當(dāng)于是空間換時(shí)間的做法。

        keepAliveincludeexclude屬性,這兩個(gè)屬性決定哪些組件可以進(jìn)入緩存。另外還有一個(gè)max屬性,通過它可以設(shè)置最大緩存數(shù),當(dāng)緩存的實(shí)例超過設(shè)置的數(shù)時(shí),vue會(huì)移除最久沒有使用的組件緩存。

        受keep-alive的影響,其內(nèi)部所有嵌套的組件都具有兩個(gè)生命周期鉤子函數(shù),分別是activateddeactivated,它們分別在組件激活和失活的時(shí)候觸發(fā),第一次activated觸發(fā)是在mounted之后

        ?? keep-alive 原理

        在具體實(shí)現(xiàn)上,keep-alive在內(nèi)部維護(hù)了一個(gè)key數(shù)組和一個(gè)緩存對(duì)象

        //keep-alive 內(nèi)部聲明周期函數(shù)
          created () {
            this.cache = Object.create(null)
            this.keys = []
          },

        key數(shù)組記錄目前緩存的組件key值,如果組件沒有指定key值,會(huì)自動(dòng)生成一個(gè)唯一的key值

        cache對(duì)象會(huì)以key值為鍵,vnode為值,用于緩存組件對(duì)應(yīng)的虛擬DOM

        在keep-alive的渲染函數(shù)中,其基本邏輯是判斷當(dāng)前渲染的vnode是否有對(duì)應(yīng)的緩存,如果有,會(huì)從緩存中讀取到對(duì)應(yīng)的組件實(shí)例,如果沒有就會(huì)把它緩存。

        當(dāng)緩存的數(shù)量超過max設(shè)置的數(shù)值時(shí),keep-alive會(huì)移除key數(shù)組中的第一個(gè)元素

         render () {
            const slot = this.$slots.default; //獲取默認(rèn)插槽
            const vnode = getFirstComponentChild(slot); //得到插槽中第一個(gè)組件的vnode
            const name = getComponentName(vnode.componentOptions); //獲取組件名字
           
            const { cache, keys } = this//獲取當(dāng)前的混村內(nèi)對(duì)象和key數(shù)組
            const key: ?string = vnode.key == null
                ? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '')
                : vnode.key; //獲取組件的key值,如果沒有key值,會(huì)按照規(guī)則自動(dòng)生成
              if (cache[key]) {
              //有緩存
              //重用組件實(shí)例
                vnode.componentInstance = cache[key].componentInstance    
                remove(keys, key); //刪除key值
                //將key值加入到數(shù)組末尾,這樣是為了保證最近使用的組件在數(shù)組中靠后,主要是為了方便設(shè)置的max值刪除很久沒使用的組件
                keys.push(key)
              } else {
              //沒有緩存的則進(jìn)行緩存
                cache[key] = vnode
                keys.push(key)
                // prune oldest entry
                if (this.max && keys.length > parseInt(this.max)) {
                //超過最大緩存數(shù)量,移除第一個(gè)key對(duì)應(yīng)的緩存
                  pruneCacheEntry(cache, keys[0], keys, this._vnode)
                }
              }

              vnode.data.keepAlive = true
            }
            return vnode || (slot && slot[0])
          }

        ?? 好了, 以上就是我的分享,歡迎大家在評(píng)論區(qū)討論鴨~

        希望小伙伴們點(diǎn)贊 ?? 支持一下哦~ ??,我會(huì)更有動(dòng)力的 ??

         

        瀏覽 70
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            日韩超碰在线 | 美女被操一区二区 | 午夜激情网址 | 欧美在线日韩在线 | 纲手扒开腿做同人游戏 | 久久久GOGO无码啪啪艺术 | 插菊花综合 | 粉嫩小泬p国产粉嫩馒头 | 日韩国产欧美在线观看 | 午夜婷婷色 |