首頁>技術>

keep-alive

有時候我們不希望元件被重新渲染影響使用體驗;或者處於效能考慮,避免多次重複渲染降低效能。而是希望元件可以快取下來,維持當前的狀態。這時候就可以用到keep-alive元件。

官網解釋:<keep-alive> 包裹動態元件時,會快取不活動的元件例項,而不是銷燬它們。和 <transition> 相似,<keep-alive> 是一個抽象元件:它自身不會渲染一個 DOM 元素,也不會出現在父元件鏈中。 當元件在 <keep-alive> 內被切換,它的 activated 和 deactivated 這兩個生命週期鉤子函式將會被對應執行。 在 2.2.0 及其更高版本中,activated 和 deactivated 將會在 <keep-alive> 樹內的所有巢狀元件中觸發。 主要用於保留元件狀態或避免重新渲染

應用場景

如果未使用keep-alive元件,則在頁面回退時仍然會重新渲染頁面,觸發created鉤子,使用體驗不好。 在以下場景中使用keep-alive元件會顯著提高使用者體驗,選單存在多級關係,多見於列表頁+詳情頁的場景如:

商品列表頁點選商品跳轉到商品詳情,返回後仍顯示原有資訊訂單列表跳轉到訂單詳情,返回,等等場景。keep-alive的生命週期初次進入時:created > mounted > activated;退出後觸發 deactivated再次進入:會觸發 activated;事件掛載的方法等,只執行一次的放在 mounted 中;元件每次進去執行的方法放在 activated 中專案實踐

1.更改App.vue

<div id="app" class='wrapper'>

<keep-alive>

<router-view v-if="$route.meta.keepAlive"></router-view>

</keep-alive>

<router-view v-if="!$route.meta.keepAlive"></router-view>

</div>

2.在路由中設定keepAlive

{

path: 'list',

name: 'itemList', // 商品管理

component (resolve) {

require(['@/pages/item/list'], resolve)

},

meta: {

keepAlive: true,

title: '商品管理'

}

}

3.更改 beforeEach鉤子

這一步是為了清空無用的頁面快取。 假設現在A、B兩個頁面都開啟的快取:

若第一次進入A頁面後退出,再次進入頁面時,頁面不會重新整理。這和目前的業務邏輯不符。我們想要的結果是A頁面前進後返回,頁面保持不變,而不是退出後重新進入保持不變。在進入過A頁面後進入B頁面,經過測試後發現,B頁面竟然會顯示A頁面的快取,儘管url已經改變

為了解決這個問題,需要判斷頁面是在前進還是後退。 在beforeEach鉤子新增程式碼:

let toDepth = to.path.split('/').length

let fromDepth = from.path.split('/').length

if (toDepth < fromDepth) {

console.log('back...')

from.meta.keepAlive = false

to.meta.keepAlive = true

}

記錄頁面滾動位置

keep-alive並不會記錄頁面的滾動位置,所以我們在跳轉時需要記錄當前的滾動位置,在觸發activated鉤子時重新定位到原有位置。 具體設計思路:

在deactivated鉤子中記錄當前滾動位置,使用localStorage:

deactivated () {

window.localStorage.setItem(this.key, JSON.stringify({

listScrollTop: this.scrollTop

}))

}

在activated鉤子中滾動:

this.cacheData = window.localStorage.getItem(this.key) ?JSON.parse(window.localStorage.getItem(this.key)) : null

$('.sidebar-item').scrollTop(this.cacheData.listScrollTop)

最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • Vue+Ant Design Vue+Mockjs----mock篇