內置組件 && vue中強大的緩存機制之keep-alive


vue中強大的緩存機制之keep-alive

  最近在用vue做項目,在切換頁面時發現切換回原來的頁面無法保存原來的狀態。 如A頁面需要ajax請求數據,然后切換到B頁面做某些事情,再切換回A頁面時,A頁面又再請求數據,但是作為前端,性能優化時必須要考慮的,並且,vue構建的單頁面應用,大多數情況下是不需要重新請求數據的,這時keep-alive就派上用場了。 

  

 

第一部分:vue中內置的組件

  在vue中,為了方便開發者更好的使用vue,減少不必要的代碼量,作者內置了一些組件,主要有:

  • component組件
  • transition組件
  • transition-group組件
  • keep-alive組件
  • slot組件 

 

(1). component組件

  • props
    • is 依照is的值,來決定使用哪個組件被渲染
    • inline-template 布爾值
var vm = new Vue({
  el: '#example',
  data: {
    currentView: 'home'
  },
  components: {
    home: { /* ... */ },
    posts: { /* ... */ },
    archive: { /* ... */ }
  }
})

 

    即在components下設置多個組件。

<component v-bind:is="currentView">
  <!-- 組件在 vm.currentview 變化時改變! -->
</component>

    也可以直接綁定在對象上:

var Home = {
  template: '<p>Welcome home!</p>'
}
var vm = new Vue({
  el: '#example',
  data: {
    currentView: Home
  }
})

 

    

 

(2) transition組件

  • props
    • name --- string,用於自動生成 CSS 過渡類名。例如:name: 'fade' 將自動拓展為.fade-enter.fade-enter-active等。默認類名為 "v"。
    • appear --- boolean, 是否在初始渲染時使用過渡。默認為false。
    • css --- boolean, 是否使用過渡類。默認為 true。如果設置為 false,將只通過組件事件觸發注冊的 JavaScript 鈎子。
    • type --- boolean, 過渡事件類型,偵聽過渡何時結束。有效值為 "transition" 和 "animation"。默認 Vue.js 將自動檢測出持續時間長的為過渡事件類型。
    • mode --- string,控制離開/進入的過渡時間序列。有效的模式有 "out-in" 和 "in-out";默認同時生效。
    • enter-class --- string
    • leave-class --- string
    • enter-active-class --- string
    • leave-active-class --- string
    • appear-class --- string
    • appear-active-class --- string
  • 事件
    • before-enter
    • enter
    • after-enter
    • before-leave
    • leave
    • after-leave
    • before-appear
    • appear
    • after-appear

   <transition> 元素作為單個元素/組件的過渡效果<transition> 不會渲染額外的 DOM 元素,也不會出現在檢測過的組件層級中。它只是將內容包裹在其中,簡單的運用過渡行為。

<!-- 簡單元素 -->
<transition>
  <div v-if="ok">toggled content</div>
</transition>
<!-- 動態組件 -->
<transition name="fade" mode="out-in" appear>
  <component :is="view"></component>
</transition>
<!-- 事件鈎子 -->
<div id="transition-demo">
  <transition @after-enter="transitionComplete">
    <div v-show="ok">toggled content</div>
  </transition>
</div>

  

new Vue({
  ...
  methods: {
    transitionComplete: function (el) {
      // 傳入 'el' 這個 DOM 元素作為參數。
    }
  }
  ...
}).$mount('#transition-demo')

 

 

 

 

(3). transition-group

  

  • tag - string, 默認為 span
  • move-class - 覆蓋移動過渡期間應用的 CSS 類。
  • 除了 mode,其他特性和 <transition> 相同。

  <transition-group> 元素作為多個元素/組件的過渡效果。<transition-group> 渲染一個真實的 DOM 元素。默認渲染 <span>,可以通過 tag 屬性配置哪個元素應該被渲染。

  注意,每個 <transition-group> 的子節點必須有 獨立的key ,動畫才能正常工作

  <transition-group> 支持通過 CSS transform 過渡移動。當一個子節點被更新,從屏幕上的位置發生變化,它將會獲取應用 CSS 移動類(通過 name 屬性或配置 move-class 屬性自動生成)。如果 CSS transform 屬性是“可過渡”屬性,當應用移動類時,將會使用 FLIP 技術 使元素流暢地到達動畫終點。

 

 

(4). slot

 不再贅述

 

 

 

 

第二部分: keep-alive

props包括:

  • include --- 字符串或正則表達式。只有匹配的組件會被緩存。
  • exclude --- 字符串或正則表達式。任何匹配的組件都不會被緩存。

用法:

  <keep-alive> 包裹動態組件時,會緩存不活動的組件實例,而不是銷毀它們。正如之前所說的,如果不使用keep-alive,每次切換到一個路由下的組件時,如果有請求,就會發起ajax請求,即在離開這個組件時就已經銷毀了這個組件。和 <transition> 相似,<keep-alive> 是一個抽象組件:它自身不會渲染一個 DOM 元素,也不會出現在父組件鏈中。 

  當組件在 <keep-alive> 內被切換,它的 activated 和 deactivated 這兩個生命周期鈎子函數將會被對應執行。主要用於保留組件狀態或避免重新渲染

<!-- 基本 -->
<keep-alive>
  <component :is="view"></component>
</keep-alive>
<!-- 多個條件判斷的子組件 -->
<keep-alive>
  <comp-a v-if="a > 1"></comp-a>
  <comp-b v-else></comp-b>
</keep-alive>
<!-- 和 <transition> 一起使用 -->
<transition>
  <keep-alive>
    <component :is="view"></component>
  </keep-alive>
</transition>

 

   include和exclude是vue2.1.0新增的:

<!-- 逗號分隔字符串 -->
<keep-alive include="a,b">
  <component :is="view"></component>
</keep-alive>
<!-- 正則表達式 (使用 v-bind) -->
<keep-alive :include="/a|b/">
  <component :is="view"></component>
</keep-alive>

  注意<keep-alive> 不會在函數式組件中正常工作,因為它們沒有緩存實例。

 

 

第三部分:

    <div id="app">
      <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設置為true的才可以被緩存:

routes: [
    {
      path: "/",
      redirect: "/commodity",
    },
    {
      path: '/Mall',
      component: Mall,
      name: "店鋪",
      meta: { keepAlive: false }
    },
    {
      path: '/personal-center',
      component: personalCenter,
      name: "個人中心",
    }, 
    {
      path: "/address",
      component: AddressManage,
      name: "地址管理"
    },
    {
      path: '/order',
      component: Myorder,
      name: "我的訂單"
    },
    {
      path: '/commodity',
      component: Commodity,
      name: "商品",
      meta: { keepAlive: true }
    },
    {
      path:"/Mall/payment",
      component: Ordersettlement,
      name: "支付信息"
    }
  ]

 

如下所示: 只有商品這一頁才可以被緩存,其他的都不能緩存。 

 

 在這里,無論怎么切換路由,都只有Commodity一直存在,並且顯示 inactive, 即不活躍,緩存的意思。

 

這時,我們可以在商品頁設置一個 activated 鈎子函數:

    activated: function () {
      alert("activated");
    },

 

這時,只要從別的頁面切換過來,都會alert activated,表示已經緩存了。 

而其他的頁面鈎子函數 deactive 會被調用

 參考文章: issue

 

 

 

 

 

第三部分: 遇到的坑

  使用keep-alive固然是好,但是並不是所有情況下都適合使用keep-alive,因為keep-alive意味着頁面省去了重新掛載渲染,這貌似很好,但是這更意味着我們沒法使用 created updated mounted 這些生命周期鈎子函數了,所以只有在固定不變的地方我們才建議使用keep-alive, 否則不適用。

  比如下面的這個頁面:

     

  僅僅是介紹了一些店鋪的基本信息,並沒有介紹到更多的內容,所以這時我們就可以使用keep-alive了,但是,這時使用keep-alive並不是萬能的,因為一旦用戶刷新了頁面,而我們的state是在首頁獲取的,就會出現問題。

 

      所以,更為普遍的方法是下面這樣的:  

    created () {this.updateMall();
    }

 

  即如果創建了新的頁面,那么一定會觸發created鈎子函數,然后我們再去請求數據,這樣就是一種很好的做法了。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

參考文章: 官網


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM