搜尋
首頁web前端Vue.js聊聊對vue內建組件keep-alive的理解
聊聊對vue內建組件keep-alive的理解Dec 14, 2022 pm 08:15 PM
javascript前端vue.jskeep-alive

Keep-alive 是什麼?以下這篇文章帶大家聊聊對vue內建元件keep-alive的理解,希望對大家有幫助!

聊聊對vue內建組件keep-alive的理解

一、Keep-alive 是什麼

keep-alivevue中的內建元件,能在元件切換過程中將狀態保留在記憶體中,防止重複渲染DOMvuejs影片教學、web前端開發

#keep-alive

keep-alive可以設定以下props屬性:

  • include
  • exclude
  • max

關於keep-alive的基本用法:

<keep-alive>
  <component :is="view"></component>
</keep-alive>

使用includesexclude

<keep-alive include="a,b">
  <component :is="view"></component>
</keep-alive>

<!-- 正则表达式 (使用 `v-bind`) -->
<keep-alive :include="/a|b/">
  <component :is="view"></component>
</keep-alive>

<!-- 数组 (使用 `v-bind`) -->
<keep-alive :include="[&#39;a&#39;, &#39;b&#39;]">
  <component :is="view"></component>
</keep-alive>

符合先檢查元件本身的 namename components

設定了keep-alive 快取的元件,會多出兩個生命週期鉤子(activated deactivated):

  • 第一次進入元件時:beforeRouteEnterbeforeCreatecreated## > created## > created# mountedactivated ... ... > beforeRouteLeave#deactivated#再次進入元件時: beforeRouteEnter
  • activated ... ... > 

    beforeRouteLeavedeactivated

    #1 #二、使用場景

    使用原則:當我們在某些​​場景下不需要讓頁面重新載入時我們可以使用

    keepalive舉個栗子:當我們從首頁

    –>

    列表頁–>商詳頁–>再返回,這時候列表頁應該是需要keep-alive

    首頁–>列表頁–>商詳頁

    –>

    回到列表頁(需要快取)–>回到首頁(需要快取)

    –>

    再次進入列表頁(不需要快取),這時候可以按需來控制頁面的keep-alive

    在路由中設定###keepAlive###屬性判斷是否需要緩存###
    {
      path: &#39;list&#39;,
      name: &#39;itemList&#39;, // 列表页
      component (resolve) {
        require([&#39;@/pages/item/list&#39;], resolve)
     },
     meta: {
      keepAlive: true,
      title: &#39;列表页&#39;
     }
    }
    ###使用#########
    <div id="app" class=&#39;wrapper&#39;>
        <keep-alive>
            <!-- 需要缓存的视图组件 --> 
            <router-view v-if="$route.meta.keepAlive"></router-view>
         </keep-alive>
          <!-- 不需要缓存的视图组件 -->
         <router-view v-if="!$route.meta.keepAlive"></router-view>
    </div>
    ######三、原理分析############keep-alive# ##是###vue###中內建的一個元件######原始碼位置:src/core/components/keep-alive.js###
    export default {
      name: &#39;keep-alive&#39;,
      abstract: true,
    
      props: {
        include: [String, RegExp, Array],
        exclude: [String, RegExp, Array],
        max: [String, Number]
      },
    
      created () {
        this.cache = Object.create(null)
        this.keys = []
      },
    
      destroyed () {
        for (const key in this.cache) {
          pruneCacheEntry(this.cache, key, this.keys)
        }
      },
    
      mounted () {
        this.$watch(&#39;include&#39;, val => {
          pruneCache(this, name => matches(val, name))
        })
        this.$watch(&#39;exclude&#39;, val => {
          pruneCache(this, name => !matches(val, name))
        })
      },
    
      render() {
        /* 获取默认插槽中的第一个组件节点 */
        const slot = this.$slots.default
        const vnode = getFirstComponentChild(slot)
        /* 获取该组件节点的componentOptions */
        const componentOptions = vnode && vnode.componentOptions
    
        if (componentOptions) {
          /* 获取该组件节点的名称,优先获取组件的name字段,如果name不存在则获取组件的tag */
          const name = getComponentName(componentOptions)
    
          const { include, exclude } = this
          /* 如果name不在inlcude中或者存在于exlude中则表示不缓存,直接返回vnode */
          if (
            (include && (!name || !matches(include, name))) ||
            // excluded
            (exclude && name && matches(exclude, name))
          ) {
            return vnode
          }
    
          const { cache, keys } = this
          /* 获取组件的key值 */
          const key = vnode.key == null
            // same constructor may get registered as different local components
            // so cid alone is not enough (#3269)
            ? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : &#39;&#39;)
            : vnode.key
         /*  拿到key值后去this.cache对象中去寻找是否有该值,如果有则表示该组件有缓存,即命中缓存 */
          if (cache[key]) {
            vnode.componentInstance = cache[key].componentInstance
            // make current key freshest
            remove(keys, key)
            keys.push(key)
          }
            /* 如果没有命中缓存,则将其设置进缓存 */
            else {
            cache[key] = vnode
            keys.push(key)
            // prune oldest entry
            /* 如果配置了max并且缓存的长度超过了this.max,则从缓存中删除第一个 */
            if (this.max && keys.length > parseInt(this.max)) {
              pruneCacheEntry(cache, keys[0], keys, this._vnode)
            }
          }
    
          vnode.data.keepAlive = true
        }
        return vnode || (slot && slot[0])
      }
    }
    ###可以看到該元件沒有## #template###,而是用了###render###,在元件渲染的時候會自動執行###render###函數#########this.cache###是一個對象,用來儲存需要快取的元件,它將以如下形式儲存:###
    this.cache = {
        &#39;key1&#39;:&#39;组件1&#39;,
        &#39;key2&#39;:&#39;组件2&#39;,
        // ...
    }
    ###在元件銷毀的時候執行###pruneCacheEntry###函數###
    function pruneCacheEntry (
      cache: VNodeCache,
      key: string,
      keys: Array<string>,
      current?: VNode
    ) {
      const cached = cache[key]
      /* 判断当前没有处于被渲染状态的组件,将其销毁*/
      if (cached && (!current || cached.tag !== current.tag)) {
        cached.componentInstance.$destroy()
      }
      cache[key] = null
      remove(keys, key)
    }
    ###在### mounted###鉤子函數中觀測 ###include### 和 ###exclude### 的變化,如下:###
    mounted () {
        this.$watch(&#39;include&#39;, val => {
            pruneCache(this, name => matches(val, name))
        })
        this.$watch(&#39;exclude&#39;, val => {
            pruneCache(this, name => !matches(val, name))
        })
    }
    ###如果###include### 或###exclude## # 發生了變化,即表示定義需要快取的元件的規則或不需要快取的元件的規則發生了變化,那麼就執行###pruneCache###函數,函數如下:###
    function pruneCache (keepAliveInstance, filter) {
      const { cache, keys, _vnode } = keepAliveInstance
      for (const key in cache) {
        const cachedNode = cache[key]
        if (cachedNode) {
          const name = getComponentName(cachedNode.componentOptions)
          if (name && !filter(name)) {
            pruneCacheEntry(cache, key, keys, _vnode)
          }
        }
      }
    }
    ###在該函數內對###this.cache###物件進行遍歷,取出每一項的###name###值,用其與新的快取規則進行匹配,如果匹配不上,則表示在新的快取規則下該元件已經不需要被緩存,則呼叫###pruneCacheEntry###函數將其從###this.cache###物件剔除即可######關於###keep-alive ###最強大的快取功能是在###render###函數中實作######先取得元件的###key###值:###
    const key = vnode.key == null? 
    componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : &#39;&#39;)
    : vnode.key
    ###拿到# ##key###值後去###this.cache###物件中去尋找是否有該值,如果有則表示該元件有緩存,即命中緩存,如下:###
    /* 如果命中缓存,则直接从缓存中拿 vnode 的组件实例 */
    if (cache[key]) {
        vnode.componentInstance = cache[key].componentInstance
        /* 调整该组件key的顺序,将其从原来的地方删掉并重新放在最后一个 */
        remove(keys, key)
        keys.push(key)
    }

    直接从缓存中拿 vnodekey的顺序,将其从原来的地方删掉并重新放在this.keys中最后一个

    this.cache对象中没有该key值的情况,如下:

    /* 如果没有命中缓存,则将其设置进缓存 */
    else {
        cache[key] = vnode
        keys.push(key)
        /* 如果配置了max并且缓存的长度超过了this.max,则从缓存中删除第一个 */
        if (this.max && keys.length > parseInt(this.max)) {
            pruneCacheEntry(cache, keys[0], keys, this._vnode)
        }
    }

    表明该组件还没有被缓存过,则以该组件的key为键,组件vnode为值,将其存入this.cache中,并且把key存入this.keys

    此时再判断this.keys中缓存组件的数量是否超过了设置的最大缓存数量值this.max,如果超过了,则把第一个缓存组件删掉

    四、思考题:缓存后如何获取数据

    解决方案可以有以下两种:

    • beforeRouteEnter
    • actived

    beforeRouteEnter

    每次组件渲染的时候,都会执行beforeRouteEnter

    beforeRouteEnter(to, from, next){
        next(vm=>{
            console.log(vm)
            // 每次进入路由执行
            vm.getData()  // 获取数据
        })
    },

    actived

    keep-alive缓存的组件被激活的时候,都会执行actived钩子

    activated(){
       this.getData() // 获取数据
    },

    注意:服务器端渲染期间avtived不被调用

    (学习视频分享:vuejs入门教程编程基础视频

    以上是聊聊對vue內建組件keep-alive的理解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:掘金社区。如有侵權,請聯絡admin@php.cn刪除
vue中keep-alive的工作原理及使用方法详解vue中keep-alive的工作原理及使用方法详解Jul 21, 2023 am 11:58 AM

Vue.js是一个流行的前端框架,提供了一些方便的功能来优化性能和提升开发效率。其中一个功能是keep-alive,它可以帮助我们在组件之间保留状态,从而减少不必要的渲染和请求。本文将详细介绍keep-alive的工作原理以及使用方法,并提供一些代码示例。一、keep-alive的工作原理在Vue.js中,每当我们切换组件时,组件都会被重新创建

使用vue的keep-alive组件实现页面缓存更新策略使用vue的keep-alive组件实现页面缓存更新策略Jul 21, 2023 pm 05:58 PM

使用Vue的keep-alive组件实现页面缓存更新策略引言:在开发Web应用程序时,经常需要处理页面缓存和更新的策略。基于Vue的SPA(Single-PageApplication)应用程序,我们可以使用Vue的keep-alive组件来进行页面缓存和更新的控制。本文将介绍如何使用Vue的keep-alive组件实现页面缓存更新策略,并提供相应的代码示

如何使用vue的keep-alive优化单页应用的性能如何使用vue的keep-alive优化单页应用的性能Jul 21, 2023 am 09:25 AM

如何使用Vue的keep-alive优化单页应用的性能在开发现代Web应用时,性能一直是一个重要的关注点。随着前端框架的发展,Vue作为一款流行的JavaScript框架,为我们提供了许多工具和技术来优化应用的性能。其中之一就是Vue的keep-alive组件。Vue的keep-alive是一个抽象组件,可以将动态组件缓存起来,以避免重复渲染和销毁。使用ke

如何在vue中利用keep-alive提升前端开发效率如何在vue中利用keep-alive提升前端开发效率Jul 21, 2023 am 09:01 AM

如何在Vue中利用keep-alive提升前端开发效率前端开发的性能一直是开发人员关注的重点之一。为了提升用户体验和页面加载速度,我们经常要考虑如何优化前端渲染。Vue作为一款流行的前端框架,提供了keep-alive组件来解决非活动组件的性能问题。本文将介绍keep-alive的使用方法,并通过代码示例展示其在Vue中如何提升前端开发效率。keep-ali

Go语言中http.Transport的Keep-Alive配置与性能优化方法Go语言中http.Transport的Keep-Alive配置与性能优化方法Jul 22, 2023 am 09:13 AM

Go语言中http.Transport的Keep-Alive配置与性能优化方法在使用Go语言进行网络编程时,我们经常会使用到http.Transport来发送HTTP请求。其中,http.Transport提供了Keep-Alive的功能,可以在多个请求之间复用TCP连接,从而提高性能。本文将介绍如何在Go语言中配置http.Transport的Keep-A

Vue3中的keep-alive函数详解:优化应用性能的应用Vue3中的keep-alive函数详解:优化应用性能的应用Jun 18, 2023 pm 11:21 PM

Vue3中的keep-alive函数详解:优化应用性能的应用在Vue3中,keep-alive函数变得更加功能强大,可以实现更多的优化功能。通过keep-alive函数,可以将组件状态保留到内存中,避免组件的重复渲染,提升应用的性能和用户体验。本文将详细介绍Vue3中keep-alive函数的使用方法和优化策略。一、keep-alive函数介绍在Vue3中,

Vue3中的keep-alive函数:提升应用性能Vue3中的keep-alive函数:提升应用性能Jun 18, 2023 pm 02:56 PM

在Vue3中,为了优化应用性能,新增了一个名为keep-alive的函数。这个函数可以将组件缓存起来,避免在切换时重新渲染,从而提高应用的整体性能。一、keep-alive函数的作用在Vue3中,keep-alive函数可以用来缓存组件,等待再次使用。在渲染过程中,如果一个组件不被销毁,也就不需要重新初始化状态,以及重新计算计算属性等。这个函数接收一个

Vue 中如何使用 keep-alive 优化性能?Vue 中如何使用 keep-alive 优化性能?Jun 11, 2023 pm 01:04 PM

在开发Web应用程序时,我们都很关注应用程序的性能。其中一个常见的场景是点开一个页面,然后返回上一页,这个过程中,页面需要重新加载一遍。这对于用户体验来说是很不友好的,而且还会浪费服务器资源和用户的流量。为了避免这种情况,我们可以使用Vue中提供的keep-alive来进行缓存,从而提高应用程序的性能。什么是keep-alive?keep-al

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具