记录--极致舒适的Vue页面保活方案

news2024/11/16 7:53:03

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

为了让页面保活更加稳定,你们是怎么做的?

我用一行配置实现了

Vue页面保活是指在用户离开当前页面后,可以在返回时恢复上一次浏览页面的状态。这种技术可以让用户享受更加流畅自然的浏览体验,而不会被繁琐的操作打扰。

为什么需要页面保活?

页面保活可以提高用户的体验感。例如,当用户从一个带有分页的表格页面(【页面A】)跳转到数据详情页面(【页面B】),并查看了数据之后,当用户从【页面B】返回【页面A】时,如果没有页面保活,【页面A】会重新加载并跳转到第一页,这会让用户感到非常烦恼,因为他们需要重新选择页面和数据。因此,使用页面保活技术,当用户返回【页面A】时,可以恢复之前选择的页码和数据,让用户的体验更加流畅。

如何实现页面保活?

状态存储

这个方案最为直观,原理就是在离开【页面A】之前手动将需要保活的状态存储起来。可以将状态存储到LocalStoreSessionStoreIndexedDB。在【页面A】组件的onMounted钩子中,检测是否存在此前的状态,如果存在从外部存储中将状态恢复回来。

有什么问题?

  • 浪费心智(麻烦/操心)。这个方案存在的问题就是,需要在编写组件的时候就明确的知道跳转到某些页面时进行状态存储。
  • 无法解决子组件状态。在页面组件中还可以做到保存页面组件的状态,但是如何保存子组件呢。不可能所有的子组件状态都在页面组件中维护,因为这样的结构并不是合理。

组件缓存

利用Vue的内置组件<KeepAlive/>缓存包裹在其中的动态切换组件(也就是<Component/>组件)。<KeepAlive/>包裹动态组件时,会缓存不活跃的组件,而不是销毁它们。当一个组件在<KeepAlive/>中被切换时,activateddeactivated生命周期钩子会替换mountedunmounted钩子。最关键的是,<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 '@/store/routers';

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

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

保活组件存储

src/stroe/router.ts

import { RouteLocationNormalized } from 'vue-router';

const useRouterStore = defineStore('router', {
  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 === 'string'
      ) {
        this.cacheComps.add(form.name);
      }
      if(
        Array.isArray(to.meta.leaveCaches) && 
        !to.meta.leaveCaches.inclued(from.path) && 
        typeof to.name === 'string'
      ) {
        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 lang='ts' setup>
import { storeToRefs } from 'pinia';
import useRouterStore from '@/store/router';

const { keepAliveComps } = storeToRefs(useRouterStore());
</script>

TypeScript提升配置体验

import 'vue-router';

export type LeaveCaches = string[];

declare module 'vue-router' {
  interface RouteMeta {
    leaveCaches?: LeaveCaches;
  }
}

该方案的问题

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

总结

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

本文转载于:

https://juejin.cn/post/7216262593718173752

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/504404.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

shell脚本4函数

文章目录 shell脚本函数1 函数概述2 定义2.1 形式2.2 使用原则2.3 函数传参2.4 函数变量的作用范围 3 递归3.1 阶乘 4 函数库5 实验5.1 阶乘5.2 递归目录5.3 调用函数库 shell脚本函数 1 函数概述 1、将命令序列按格式写在一起 2、可方便重复使用命令序列 使用函数可以避免代码…

FS4067升压充电8.4V锂电池充电IC电流3A

FS4067升压型5V升压充电8.4V两串锂电池充电IC&#xff0c;工作电压范围于 2.7V 到 6.5V 的 PFM 升压型两节锂电池充电控制集成电路。 FS4067采用恒流和恒压模式对电池进行充电管理&#xff0c;内部集成有基准电压源&#xff0c; 电感电流检测单元&#xff0c;电池电压检测电路和…

【原创】强烈推荐三个可视化模块,绘制的图表真的很酷炫!!

Matplotlib是Python编程语言中最受欢迎的绘图库之一。它提供了一套面向对象的API&#xff0c;可将图表嵌入到使用通用GUI工具包&#xff08;如Tkinter、wxPython、Qt或GTK&#xff09;的应用程序中。Matplotlib还常用于创建静态、动画和交互式的Python数据可视化。它能够绘制各…

【Unity】在Unity下使用websocket的一些经验

首先&#xff0c;先上大家都知道的简介&#xff0c;这一版是我认为比较清晰的。。。虽然在度娘的教导和知乎的教导下&#xff0c;总算认识了websocket&#xff0c;但这个过程比较艰辛&#xff0c;给大家发出来看一下&#xff1a; --------------------------------------------…

精准测试之过程与实践 | 京东云技术团队

作者&#xff1a;京东工业 宛煜昕 一、怎样的技术 •百度百科&#xff1a; 精准测试是一套计算机测试辅助分析系统。 精准测试的核心组件包含的软件测试示波器、用例和代码的双向追溯、智能回归测试用例选取、覆盖率分析、缺陷定位、测试用例聚类分析、测试用例自动生成系统…

苹果(ios)家庭APP广告推送,照片,相册,日历消息推送,【iMessage苹果推】,【苹果家庭推群发】,【imessage相册推送】

解决方案 若是你完全担任苹果的这个默许功效&#xff0c;那就不必要去编削任何代码。 如果&#xff0c;你原本就比较细心&#xff0c;曾经配置了modalPresentationStyle的值&#xff0c;那你也不会有这个影响。 对于想要找回本来默认交互的同学&#xff0c;直接设置以下便可&am…

携手共赢 HashData亮相华为合作伙伴大会

5月8日-9日&#xff0c;以“因聚而生 众志有为”为主题的“华为中国合作伙伴大会2023”在深圳国际会展中心举办。 HashData作为国内云原生数据仓库的代表企业&#xff0c;也是华为重要的生态合作伙伴。在本次大会上&#xff0c;HashData展示了云数仓领域最新前沿技术以及联合…

Java经典笔试题—day04

Java经典笔试题—day04 &#x1f50e;选择题&#x1f50e;编程题&#x1f95d;计算糖果&#x1f95d;进制转换 &#x1f50e;结尾 &#x1f50e;选择题 (1)下列与队列结构有关联的是&#xff08;&#xff09; A. 函数的递归调用 B. 数组元素的引用 C. 多重循环的执行 D. 先到…

Windows系统运行速度优化(系统内存扩充)!

之前有几篇文章&#xff0c;讲述了一些关于提升Windows系统运行速度的方法。链接如下&#xff1a; 如何让Windows系统10秒开机&#xff1f; 电脑运行卡顿怎么办&#xff1f;一招让Windows系统运行流畅 Windows系统重新安装后必须要做的优化 这里还有一个Windows系统的优化方法…

技术领先、“忠”于业务,用友走出多维数据库的价值之路

本文转自科技商业 作者 于洪涛 对于当今的企业而言&#xff0c;精细化管理&#xff0c;已经成为发展之源&#xff0c;甚至是生存之本。 尤其是随着数字化和智能化转型的推进&#xff0c;在企业经营管理过程中&#xff0c;数据正在日益发挥更为关键的要素作用。 相比过去&…

【Linux】Shell脚本之函数的操作+实战详解(建议收藏⭐)

&#x1f341;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; 文章目录 shell脚本函数设置函数的意义函数的基…

物联网|蓝牙4.0BLE协议栈简介|IAR集成开发环境简介|IAR各版本下载链接|物联网之蓝牙4.0 BLE基础-学习笔记(2)

文章目录 129-142暂停&#xff0c;待续3、蓝牙4.0BLE协议栈简介4、IAR集成开发环境简介Tips: BLE协议结构图介绍Tips IAR各版本下载链接 129-142暂停&#xff0c;待续 3、蓝牙4.0BLE协议栈简介 问题: 1、什么是LE协议栈?BLE协识栈与BLE协议的关系&#xff1f; 协议&#xff…

数据结构与算法(Java版) | 队列的应用场景和介绍

队列的一个应用场景 给大家介绍完稀疏数组这种数据结构之后&#xff0c;接下来我再来给大家介绍另外一种数据结构&#xff0c;即队列。 队列&#xff0c;听其名而知其义&#xff0c;相信大家应该都在现实生活中见过&#xff0c;比如在火车站排队买票&#xff0c;或者在麦当劳…

轻NAS搭建 - 使用微力同步搭建私人云盘,无需公网IP也能远程访问

文章目录 1.前言2. 微力同步网站搭建2.1 微力同步下载和安装2.2 微力同步网页测试2.3 cpolar的安装和注册 3.本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 1.前言 私有云盘作为云存储概念的延伸&#xff0c;虽然谈不上多么新颖&#xff0c;但是其…

图神经网络:在Cora数据集上动手实现图神经网络

文章说明&#xff1a; 1)参考资料&#xff1a;PYG官方文档。超链。 2)博主水平不高&#xff0c;如有错误还望批评指正。 3)我在百度网盘上传了这篇文章的jupyter notebook。超链。提取码8888。 文章目录 代码实操1&#xff1a;GCN的复杂实现代码实操2&#xff1a;GCN的简单实现…

IntelliJ Platform-Plugins-获取方法相关信息(PsiElement/PsiMethodImpl)

PsiElement接口是文件中光标所在的那个字段&#xff0c;或者光标所在的那个方法的抽象&#xff0c;例如下图中PsiElement就是public String getName()&#xff0c;它的实现类是PsiMethodImpl 下面的代码会演示&#xff1a;如果光标在方法上&#xff0c;就打印方法名字&#x…

「Cpolar」内网穿透实现在外远程连接MongoDB数据库【端口映射】

&#x1f482;作者简介&#xff1a; THUNDER王&#xff0c;一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学本科在读&#xff0c;同时任汉硕云&#xff08;广东&#xff09;科技有限公司ABAP开发顾问。在学习工作中&#xff0c;我通常使用偏后端的开发语言A…

第二十四章 Unity 纹理贴图

通常情况下&#xff0c;3D网格模型只能展示游戏对象的几何形状&#xff0c;而表面的细节则纹理贴图提供。纹理贴图通过UV坐标“贴附”在模型的表面。当然&#xff0c;这个过程不需要我们在Unity中完成&#xff0c;而是在建模软件中完成的。通常情况下&#xff0c;我们通过3ds m…

鸿蒙Hi3861学习九-Huawei LiteOS-M(互斥锁)

一、简介 互斥锁又被称为互斥型信号量&#xff0c;是一种特殊的二值信号量&#xff0c;用于实现对共享资源的独占式处理。 任意时刻互斥锁的状态只有两种&#xff1a;开锁或闭锁。 当有任务占用公共资源时&#xff0c;互斥锁处于闭锁状态&#xff0c;这个任务获得该互斥锁的使用…

C++系列六:一文打尽C++运算符

C运算符 1. 算术运算符2. 关系运算符3. 逻辑运算符4. 按位运算符5. 取地址运算符6. 取内容运算符7. 成员选择符8. 作用域运算符9. 总结 1. 算术运算符 算术运算符用于执行基本数学运算&#xff0c;例如加减乘除和取模等操作。下表列出了C中支持的算术运算符&#xff1a; 运算…