目錄
為什麼需要頁面保活?
如何實現頁面保活?
狀態儲存
有什麼問題?
元件快取
最佳實踐
路由設定
保活元件儲存
頁面快取
TypeScript提升配置体验
该方案的问题
总结
首頁 web前端 Vue.js 分享一個極致舒適的Vue頁面保活方案

分享一個極致舒適的Vue頁面保活方案

Apr 10, 2023 pm 04:29 PM
vue.js vue-router

這篇文章為大家帶來了關於Vue的相關知識,其中主要跟大家分享一個極致舒適的Vue頁面保活方案,有代碼示例,有興趣的朋友下面一起來看一下吧,希望對大家有幫助。

為了讓頁面保活更穩定,你們是怎麼做的?

我用一行設定實作了

分享一個極致舒適的Vue頁面保活方案

Vue頁面保活是指在使用者離開目前頁面後,可以在回傳時恢復上一次瀏覽頁面的狀態。這種技術可以讓使用者享受更流暢自然的瀏覽體驗,而不會被繁瑣的操作打擾。

為什麼需要頁面保活?

頁面保活可以提高使用者的體驗感。例如,當使用者從一個有分頁的表格頁面(【頁面A】)跳到資料詳情頁面(【頁面B】),並查看了資料之後,當使用者從【頁面B】返回【頁面A】時,如果沒有頁面保活,【頁面A】會重新載入並跳到第一頁,這會讓使用者感到非常煩惱,因為他們需要重新選擇頁面和資料。因此,使用頁面保活技術,當使用者返回【頁面A】時,可以恢復先前選擇的頁碼和數據,讓使用者的體驗更加流暢。

如何實現頁面保活?

狀態儲存

這個方案最為直觀,原理就是在離開【頁面A】之前手動儲存需要保活的狀態。可以將狀態儲存到LocalStoreSessionStoreIndexedDB。在【頁面A】元件的onMounted鉤子中,偵測是否存在先前的狀態,如果存在從外部儲存中將狀態恢復回來。

有什麼問題?

  • 浪費心智(麻煩/操心)。這個方案存在的問題是,需要在編寫元件的時候就明確的知道跳到某些頁面時進行狀態儲存。
  • 無法解決子元件狀態。在頁面元件中還可以做到保存頁面元件的狀態,但是如何保存子元件呢。不可能所有的子元件狀態都在頁面元件中維護,因為這樣的結構並不是合理。

元件快取

利用Vue的內建元件<keepalive></keepalive>快取包裹在其中的動態切換元件(也就是<component></component>元件)。 <keepalive></keepalive>包裹動態元件時,會快取不活躍的元件,而不是銷毀它們。當一個元件在<keepalive></keepalive>中被切換時,activateddeactivated生命週期鉤子會替換mountedunmounted鉤子。最關鍵的是,<keepalive></keepalive>不僅適用於被包裹組件的根節點,也適用於其子孫節點。

<keepalive></keepalive>搭配vue-router即可實現頁面的保活,實作程式碼如下:

<template>
  <RouterView v-slot="{ Component }">
    <KeepAlive>
      <component :is="Component"/>
    </KeepAlive>
  </RouterView>
</template>
登入後複製

有什麼問題?

  • 頁面保活不準確。上面的方式雖然實現了頁面保活,但是並不能滿足生產要求,例如:【頁面A】是應用程式首頁,【頁面B】是資料列表頁,【頁面C】是資料詳情頁。使用者查看資料詳情的動線是:【頁面A】->【頁面B】->【頁面C】,在這條動線中【頁面B】->【頁面C】的時候需要快取【頁面B】,當從【頁面C】->【頁面B】的時候需要從換從中恢復【頁面B】。但是【頁面B】->【頁面A】的時候又不需要快取【頁面B】,上面的這個方法並不能做到這樣的設定。

最佳實踐

最理想的保活方式是,在不入侵元件程式碼的情況下,透過簡單的配置實現按需的頁面保活。

【不入侵元件程式碼】這條即可排除第一種方式的實現,第二種【元件快取】的方式只是敗在了【按需的頁面保活】。那麼改造第二種方式,透過在router的路由配置上進行按需保活的配置,再提供一種讀取配置結合<KeepAlive/>include屬性即可。

路由設定

src/router/index.ts

#
import useRoutersStore from &#39;@/store/routers&#39;;

const routes: RouteRecordRaw[] = [
  {
    path: &#39;/&#39;,
    name: &#39;index&#39;,
    component: () => import(&#39;@/layout/index.vue&#39;),
    children: [
      {
        path: &#39;/app&#39;,
        name: &#39;App&#39;,
        component: () => import(&#39;@/views/app/index.vue&#39;),
      },
      {
        path: &#39;/data-list&#39;,
        name: &#39;DataList&#39;,
        component: () => import(&#39;@/views/data-list/index.vue&#39;),
        meta: {
          // 离开【/data-list】前往【/data-detail】时缓存【/data-list】
          leaveCaches: [&#39;/data-detail&#39;],
        }
      },
      {
        path: &#39;/data-detail&#39;,
        name: &#39;DataDetail&#39;,
        component: () => import(&#39;@/views/data-detail/index.vue&#39;),
      }
    ]
  }
];

router.beforeEach((to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext) => {
  const { cacheRouter } = useRoutersStore();
  cacheRouter(from, to);
  next();
});
登入後複製

保活元件儲存

src/stroe /router.ts

import { RouteLocationNormalized } from &#39;vue-router&#39;;

const useRouterStore = defineStore(&#39;router&#39;, {
  state: () => ({
    cacheComps: new Set<string>(),
  }),
  actions: {
    cacheRouter(from: RouteLocationNormalized, to: RouteLocationNormalized) {
      if(
        Array.isArray(from.meta.leaveCaches) && 
        from.meta.leaveCaches.inclued(to.path) && 
        typeof from.name === &#39;string&#39;
      ) {
        this.cacheComps.add(form.name);
      }
      if(
        Array.isArray(to.meta.leaveCaches) && 
        !to.meta.leaveCaches.inclued(from.path) && 
        typeof to.name === &#39;string&#39;
      ) {
        this.cacheComps.delete(to.name);
      }
    },
  },
  getters: {
    keepAliveComps(state: State) {
      return [...state.cacheComps];
    },
  },
});
登入後複製

頁面快取

src/layout/index.vue

<template>
  <RouterView v-slot="{ Component }">
    <KeepAlive :include="keepAliveComps">
      <component :is="Component"/>
    </KeepAlive>
  </RouterView>
</template>

<script setup>
import { storeToRefs } from &#39;pinia&#39;;
import useRouterStore from &#39;@/store/router&#39;;

const { keepAliveComps } = storeToRefs(useRouterStore());
</script>
登入後複製

TypeScript提升配置体验

import &#39;vue-router&#39;;

export type LeaveCaches = string[];

declare module &#39;vue-router&#39; {
  interface RouteMeta {
    leaveCaches?: LeaveCaches;
  }
}
登入後複製

该方案的问题

  • 缺少通配符处理/*/**/index
  • 无法缓存/preview/:address这样的动态路由。
  • 组件名和路由名称必须保持一致。

总结

通过<routerview v-slot="{ Component }"></routerview>获取到当前路由对应的组件,在将该组件通过<component :is="Component"></component>渲染,渲染之前利用<keepalive :include="keepAliveComps"></keepalive>来过滤当前组件是否需要保活。 基于上述机制,通过简单的路由配置中的meta.leaveCaches = [...]来配置从当前路由出发到哪些路由时,需要缓存当前路由的内容。【推荐学习:《vue.js视频教程》】

如果大家有其他保活方案,欢迎留言交流哦!

以上是分享一個極致舒適的Vue頁面保活方案的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

圖文詳解如何在Vue專案中整合Ace程式碼編輯器 圖文詳解如何在Vue專案中整合Ace程式碼編輯器 Apr 24, 2023 am 10:52 AM

Ace 是一個用 JavaScript 寫的可嵌入程式碼編輯器。它與 Sublime、Vim 和 TextMate 等原生編輯器的功能和效能相符。它可以很容易地嵌入到任何網頁和 JavaScript 應用程式中。 Ace 被維護為Cloud9 IDE的主要編輯器 ,並且是 Mozilla Skywriter (Bespin) 專案的繼承者。

Vue應用程式中遇到vue-router的錯誤「NavigationDuplicated: Avoided redundant navigation to current location」 – 怎麼解決? Vue應用程式中遇到vue-router的錯誤「NavigationDuplicated: Avoided redundant navigation to current location」 – 怎麼解決? Jun 24, 2023 pm 02:20 PM

Vue應用程式中遇到vue-router的錯誤「NavigationDuplicated:Avoidedredundantnavigationtocurrentlocation」–怎麼解決? Vue.js作為快速且靈活的JavaScript框架在前端應用開發中越來越受歡迎。 VueRouter是Vue.js的一個程式碼庫,用來進行路由管理。然而,有時

探討如何在Vue3中撰寫單元測試 探討如何在Vue3中撰寫單元測試 Apr 25, 2023 pm 07:41 PM

在當今前端開發中,Vue.js 已經成為了一個非常流行的框架。隨著 Vue.js 的不斷發展,單元測試變得越來越重要。今天,我們將探討如何在 Vue.js 3 中編寫單元測試,並提供一些最佳實踐和常見的問題及解決方案。

Vue中JSX語法和模板語法的簡單比較(優劣勢分析) Vue中JSX語法和模板語法的簡單比較(優劣勢分析) Mar 23, 2023 pm 07:53 PM

在Vue.js中,開發人員可以使用兩種不同的語法來建立使用者介面:JSX語法和範本語法。這兩種文法各有優劣,以下就來探討它們的差異和優劣勢。

淺析vue怎麼實現檔案切片上傳 淺析vue怎麼實現檔案切片上傳 Mar 24, 2023 pm 07:40 PM

在實際開發專案過程中有時候需要上傳比較大的文件,然後呢,上傳的時候相對來說就會慢一些,so,後台可能會要求前端進行文件切片上傳,很簡單哈,就是把比如說1個G的檔案流切割成若干個小的檔案流,然後分別請求介面傳遞這個小的檔案流。

聊聊vue3怎麼使用高德地圖api 聊聊vue3怎麼使用高德地圖api Mar 09, 2023 pm 07:22 PM

在我們使用高德地圖的時候,官方給我們推薦了很多案例,demo,但是這些案例都是使用原生方法接入,並沒有提供vue或者react 的demo,vue2的接入網上也很多人都有寫過,以下這篇文章就來看看vue3怎麼使用常用的高德地圖api,希望對大家有幫助!

實例詳解vue3實現chatgpt的打字機效果 實例詳解vue3實現chatgpt的打字機效果 Apr 18, 2023 pm 03:40 PM

在做 chatgpt 鏡像站的時候,發現有些鏡像站是沒做打字機的遊標效果的,就只是文字輸出,是他們不想做嗎?反正我想做。於是我仔細研究了一下,實現了打字機效果加遊標的效果,現在分享一下我的解決方案以及效果圖~

手把手教你使用Vue3實作一個飄逸元素拖曳功能 手把手教你使用Vue3實作一個飄逸元素拖曳功能 Mar 30, 2023 pm 08:57 PM

怎麼實現元素拖曳功能?以下這篇文章一步一步帶大家了解如何使用Vue3實作一個飄逸元素拖曳功能,並在實例中了解相關知識點,希望對大家有幫助!

See all articles