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

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

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

  

 

第一部分: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下設置多個組件。vue

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

    也能夠直接綁定在對象上:git

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 元素,也不會出如今檢測過的組件層級中。它只是將內容包裹在其中,簡單的運用過渡行爲。github

<!-- 簡單元素 -->
<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 屬性配置哪一個元素應該被渲染。ajax

  注意,每一個 <transition-group> 的子節點必須有 獨立的key ,動畫才能正常工做正則表達式

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

 

 

(4). slotapi

 再也不贅述緩存

 

 

 

 

第二部分: 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鉤子函數,而後咱們再去請求數據,這樣就是一種很好的作法了。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

參考文章: 官網

相關文章
相關標籤/搜索