Maison  >  Article  >  interface Web  >  Partagez une solution de tenue de pages Vue extrêmement confortable

Partagez une solution de tenue de pages Vue extrêmement confortable

藏色散人
藏色散人avant
2023-04-10 16:29:031414parcourir

Cet article vous apporte des connaissances pertinentes sur Vue. Il partage principalement avec vous une solution de conservation de pages Vue extrêmement confortable. Les amis intéressés peuvent y jeter un œil ci-dessous.

Pour rendre la page keep-alive plus stable, que faites-vous ?

Je l'ai implémenté avec une ligne de configuration

Partagez une solution de tenue de pages Vue extrêmement confortable

Vue page keep-alive signifie qu'après que l'utilisateur quitte la page actuelle, l'état de la dernière page consultée peut être restauré lors de son retour. Cette technologie permet aux utilisateurs de profiter d’une expérience de navigation plus fluide et naturelle sans être dérangé par des opérations fastidieuses.

Pourquoi devons-nous garder la page vivante ?

Le maintien des pages en vie peut améliorer l'expérience utilisateur. Par exemple, lorsque l'utilisateur passe d'une page de tableau avec pagination ([Page A]) à la page de détails des données ([Page B]), et après avoir consulté les données, lorsque l'utilisateur revient de [Page B] à [Page A ] , s'il n'y a pas de page conservée, [Page A] se rechargera et passera à la première page, ce qui ennuiera beaucoup les utilisateurs car ils devront resélectionner la page et les données. Par conséquent, grâce à la technologie de maintien de page, lorsque l'utilisateur revient à la [Page A], le numéro de page et les données précédemment sélectionnés peuvent être restaurés, rendant l'expérience utilisateur plus fluide.

Comment faire vivre la page ?

State Storage

Cette solution est la plus intuitive. Le principe est de stocker manuellement l'état qui doit être conservé en vie avant de quitter la [Page A]. L'état peut être stocké dans LocalStore, SessionStore ou IndexedDB. Dans le hook onMounted du composant [Page A], vérifiez si l'état précédent existe et si c'est le cas, restaurez l'état à partir du stockage externe. 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></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

Des questions ?

  • Perte d'esprit (problèmes/inquiétudes). Le problème avec cette solution est que vous devez savoir clairement lors de l'écriture du composant pour stocker l'état lors du passage à certaines pages.
  • Impossible de résoudre l'état du composant enfant. Vous pouvez également enregistrer l'état des composants de page dans les composants de page, mais comment enregistrer les sous-composants. Il est impossible de conserver tous les états des sous-composants dans le composant page car une telle structure n'est pas raisonnable.

Cache de composants🎜Utilisez le composant intégré de Vue <keepalive></keepalive> code> cache Le composant de commutation dynamique qu'il contient (c'est-à-dire le composant <component></component>). <keepalive></keepalive>Lors de l'encapsulation de composants dynamiques, les composants inactifs seront mis en cache au lieu de les détruire. Lorsqu'un composant est basculé dans <keepalive></keepalive>, les hooks de cycle de vie activés et désactivés remplacent le code monté > et les hooks non montés. La chose la plus importante est que <keepalive></keepalive> s'applique non seulement au nœud racine du composant encapsulé, mais également à ses nœuds descendants. 🎜🎜<keepalive></keepalive> peut être utilisé avec vue-router pour maintenir la page en vie. Le code d'implémentation est le suivant : 🎜
<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>

Quel est le problème ?

  • La conservation de la page est inexacte. Bien que la méthode ci-dessus permette de conserver la page, elle ne peut pas répondre aux exigences de production. Par exemple : [Page A] est la page d'accueil de l'application, [Page B] est la page de liste de données et [Page C] est la page de détails des données. La ligne mobile permettant aux utilisateurs d'afficher les détails des données est la suivante : [Page A]->[Page B]->[Page C]. Dans cette ligne mobile, [Page B]->[Page C] doit être mise en cache. [Page B], lorsque vous passez de [Page C] à [Page B], vous devez restaurer [Page B] à partir de celle-ci. Cependant, lorsque [Page B] -> [Page A], il n'est pas nécessaire de mettre en cache [Page B]. La méthode ci-dessus ne peut pas réaliser une telle configuration.

Meilleure pratique🎜🎜🎜Le moyen le plus idéal de rester en vie est d'obtenir un résultat à la demande grâce à une configuration simple sans envahir le code du composant. maintenu en vie. 🎜🎜🎜[Aucune intrusion dans le code du composant] Cela exclut la mise en œuvre de la première méthode. La deuxième méthode [mise en cache des composants] n'est vaincue que par [conservation de la page à la demande]. Transformez ensuite la deuxième manière, en configurant le keep-alive à la demande sur la configuration de routage du router, puis fournissez une configuration de lecture combinée avec <keepalive></keepalive> Le L'attribut include est suffisant. 🎜

Configuration du routage

🎜src/router/index.ts🎜
import &#39;vue-router&#39;;

export type LeaveCaches = string[];

declare module &#39;vue-router&#39; {
  interface RouteMeta {
    leaveCaches?: LeaveCaches;
  }
}

Gardez en vie Stockage des composants

🎜src/stroe/router.ts🎜rrreee

Cache de pages

🎜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视频教程》】

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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer