vue2 设置keepAlive之后怎么刷新页面数据

场景:移动端有 A、B、C 三个页面,A、B 页面路由设置了keepAlive属性,有下面两个场景:

1、A 页面 --> B 页面,B 页面刷新。

2、C 页面 --> B页面,B 页面不刷新。

一、分为以下两个情况讨论:

情况一、B 页面的代码未做组件封装,B 页面的核心代码如下:

<template>
  <div class="demo" ref="pageWrapRef">
    <div v-for="item in arr" :key="item.id">{{ item.name }}</div>
  </div>
</template>

<script>
export default {
  name: 'demo',
  data() {
    return {
      name: 'zhangsan',
      id: '1',
      arr: [],
      pageSourceName: ''
    };
  },
  mounted() {
    for (let i = 0; i < 100; i++) {
      this.arr.push({
        id: i,
        name: `张三${i}`
      });
    }
  },
  beforeRouteEnter(to, from, next) {
    next((vm) => {
      vm.pageSourceName = from.name;
    });
  },
  activated() {
    if (this.pageSourceName == 'A') {
      // 处理刷新数据的逻辑
      this.resetParams();
      this.initData();
    } else {
      // 滚动到指定位置
      const scrollTop = sessionStorage.getItem('scrollTop');
      if (scrollTop) {
        this.$refs.pageWrapRef.scrollTop = scrollTop;
      }
    }
  },
  beforeRouteLeave(to, from, next) {
    if (to.name == 'A') {
      sessionStorage.removeItem('scrollTop');
    } else {
      sessionStorage.setItem('scrollTop', this.$refs.pageWrapRef.scrollTop);
    }
    next();
  },
  methods: {
    initData() {
      console.log('初始化页面的接口请求');
    },

    resetParams() {
      this.name = 'zhangsan';
      this.id = '1';
      console.log('由于页面数据缓存了 所以要把变量重置');
    }
  }
};
</script>

<style scoped>
.demo {
  padding: 0.16rem 0;
  height: calc(100vh - 0.8rem);
  overflow-y: scroll;
  background-color: #fff;
}
</style>

情况二、B 页面的代码做了组件封装,比如说将 B 页面中的模块拆分成更小的业务组件,每个业务组件单独处理业务逻辑。如下图:

当 B 页面嵌套好几层组件时,这时在处理刷新跨层组件的数据时,如果使用常规的传值,传方法,会有一定的难度。

经过对各种方案的实验,选择了这种方案,B 页面的顶层组件通过 provide 属性向外暴露数顶层组件的页面数据,页面内的业务子组件通过 inject 属性接收顶层组件的数据。

页面交互如下:

二、以下分为三个部分:页面路由配置、页面代码、组件代码,如下:

1、页面路由配置:

export default [
  {
    path: '/demo/demoA',
    name: 'demoA',
    meta: { keepAlive: true },
    component: () => import('@/page/demo/demoA')
  },
  {
    path: '/demo/demoB',
    name: 'demoB',
    meta: { keepAlive: true },
    component: () => import('@/page/demo/demoB')
  },
  {
    path: '/demo/demoC',
    name: 'demoC',
    component: () => import('@/page/demo/demoC')
  }
];

2、三个页面的代码:

A 页面:

<template>
  <div class="demo-a" ref="pageWrapRef">
    demoA 页面
    <div
      class="item"
      v-for="(item, index) in list"
      :key="index"
      @click="handleJump(item)"
      >{{ item.id }}--{{ item.name }}</div
    >
  </div>
</template>

<script>
export default {
  name: 'demoA',
  data() {
    return {
      list: []
    };
  },
  activated() {
    const scrollTop = sessionStorage.getItem('scrollTopDemoA');
    if (scrollTop) {
      this.$refs.pageWrapRef.scrollTop = scrollTop;
    }
  },
  beforeRouteLeave(to, from, next) {
    sessionStorage.setItem('scrollTopDemoA', this.$refs.pageWrapRef.scrollTop);
    next();
  },
  mounted() {
    for (let i = 0; i < 100; i++) {
      this.list.push({
        id: `${i}`,
        name: `demoA`
      });
    }
  },
  methods: {
    handleJump(item) {
      this.$router.push({
        path: '/demo/demoB',
        query: {
          id: item.id
        }
      });
    }
  }
};
</script>

<style scoped>
.demo-a {
  background-color: #fff;
  height: 100vh;
  overflow-y: scroll;
}

.item {
  height: 44px;
  line-height: 44px;
  border-bottom: 1px #eee solid;
  padding: 0 15px;
}

.item:nth-child(odd) {
  background-color: paleturquoise;
}
</style>

B 页面

<template>
  <div class="demo-a" ref="pageWrapRef">
    demoB 页面
    <demoGrandfather />
  </div>
</template>

<script>
import demoGrandfather from './demoGrandfather.vue';

export default {
  name: 'demoB',
  provide() {
    return {
      demoB: this
    };
  },
  components: { demoGrandfather },
  data() {
    return {
      needRefresh: false
    };
  },
  activated() {
    const scrollTop = sessionStorage.getItem('scrollTopDemoB');
    if (scrollTop) {
      this.$refs.pageWrapRef.scrollTop = scrollTop;
    }
  },
  beforeRouteEnter(to, from, next) {
    if (to.name == 'demoB' && from.name == 'demoA') {
      next((vm) => {
        vm.needRefresh = true;
      });
    } else {
      next((vm) => {
        vm.needRefresh = false;
      });
    }
    next();
  },
  beforeRouteLeave(to, from, next) {
    if (to.name == 'demoA') {
      sessionStorage.removeItem('scrollTopDemoB');
    } else {
      sessionStorage.setItem(
        'scrollTopDemoB',
        this.$refs.pageWrapRef.scrollTop
      );
    }
    next();
  },
  methods: {}
};
</script>

<style scoped>
.demo-a {
  background-color: #fff;
  height: 100vh;
  overflow-y: scroll;
}

.item {
  height: 44px;
  line-height: 44px;
  border-bottom: 1px #eee solid;
  padding: 0 15px;
}

.item:nth-child(odd) {
  background-color: paleturquoise;
}
</style>

C 页面

<template>
  <div class="demo-c">
    demoC 页面
  </div>
</template>

<script>
export default {
  name: 'demoC'
};
</script>

<style scoped>
.demo-c {
}
</style>

3、B 页面中使用到的三个组件

顶层组件,demoGrandfather.vue 

<template>
  <div class="demo-grandfather">
    grandfather page
    <DemoParent />
  </div>
</template>

<script>
import DemoParent from './demoParent.vue';

export default {
  name: 'demoGrandfather',
  components: { DemoParent },
  data() {
    return {
      name: 'zhangsan',
      pageSourceName: ''
    };
  }
};
</script>

<style scoped>
.demo {
  padding: 0.16rem 0;
  height: calc(100vh - 0.8rem);
  overflow-y: scroll;
  background-color: #fff;
}
</style>

中间组件,demoParent.vue

<template>
  <div class="demo-parent">
    parent page
    <DemoChildren />
  </div>
</template>

<script>
import DemoChildren from './demoChildren.vue';

export default {
  name: 'demoParent',
  components: { DemoChildren },
  data() {
    return {
      name: 'zhangsan',
      id: '1',
      arr: [],
      pageSourceName: ''
    };
  },
  mounted() {
    for (let i = 0; i < 100; i++) {
      this.arr.push({
        id: i,
        name: `张三${i}`
      });
    }
  },
  methods: {
    initData() {
      console.log('初始化页面的接口请求');
    },

    resetParams() {
      this.name = 'zhangsan';
      this.id = '1';
      console.log('由于页面数据缓存了 所以要把变量重置');
    }
  }
};
</script>

<style scoped>
.demo {
  padding: 0.16rem 0;
  height: calc(100vh - 0.8rem);
  overflow-y: scroll;
  background-color: #fff;
}
</style>

底层组件,demoChildren.vue

<template>
  <div class="demo-children">
    <!-- 隐藏域 -->
    <div style="display: none;">{{ refresh }}</div>

    <div
      class="item"
      v-for="(item, index) in list"
      :key="index"
      @click.stop="handleJump(item)"
    >
      {{ item.id }} ----- {{ item.name }}</div
    >
  </div>
</template>

<script>
export default {
  name: 'demoChildren',
  inject: ['demoB'],
  data() {
    return {
      list: [],
      id: '0',
      refreshExecuted: false // 是否已刷新,默认未刷新
    };
  },
  deactivated() {
    this.refreshExecuted = false; // 更新为未刷新状态
  },
  computed: {
    refresh() {
      if (this.demoB.needRefresh) {
        if (this.$route.name == 'demoB' && !this.refreshExecuted) {
          this.refreshExecuted = true;
          this.resetParams();
          this.initData();
        }
      }
      return this.demoB.needRefresh;
    }
  },
  methods: {
    initData() {
      console.log('初始化页面的接口请求');
      for (let i = 0; i < 100; i++) {
        this.list.push({
          id: `${i}`,
          name: `demoB`
        });
      }
    },

    resetParams() {
      console.log('由于页面数据缓存了 所以要把变量重置');
    },

    handleJump(item) {
      this.$router.push({
        path: '/demo/demoC',
        query: {
          id: item.id
        }
      });
    }
  }
};
</script>

<style scoped>
.demo-a {
  background-color: #fff;
  height: 100vh;
  overflow-y: scroll;
}

.item {
  height: 44px;
  line-height: 44px;
  border-bottom: 1px #eee solid;
  padding: 0 15px;
}

.item:nth-child(odd) {
  background-color: paleturquoise;
}
</style>

三、总结:

我们在接到一个需求时,往往只会针对当前的需求进行代码开发,很少有意识去进行开发前的规划工作,这就导致我们在前期开发的有多开心,后期在改动时就有多痛苦。而本次的分享也是基于最近工作中遇到的一个场景,这个问题的出现,让我逐渐意识到规划的重要性,规划就是凡事谋定而后动,前期规划的越多,后期在进行迭代时,限制条件就会越少。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

cAdvisor+Prometheus+Grafana 搞定Docker容器监控平台

cAdvisorPrometheusGrafana cAdvisorPrometheusGrafana 搞定Docker容器监控平台1、先给虚拟机上传cadvisor2、What is Prometheus?2.1、架构图 3、利用docker安装普罗米修斯4、安装grafana cAdvisorPrometheusGrafana 搞定Docker容器监控平台 1、先给虚拟机上传cadvisor cAd…

fastjson反序列化漏洞

fastjson反序列化漏洞 文章目录 fastjson反序列化漏洞1.漏洞原理2.探测方式2.1 查看回显2.2 LDAP/RMI服务测试 3.LDAP/RMI服务搭建要求4.漏洞复现4.1 fastjson <1.2.47 反序列化导致任意命令执行漏洞4.1.1 环境准备4.1.2 复现过程 4.2 fastjson <1.2.24 反序列化导致任意…

OpenHarmony、HarmonyOS打开编辑 PDF 等操作的三方组件使用教程

项目场景: 随着数字化时代的发展,PDF 文档成为广泛应用于各行业的重要文件格式。为了提高OpenHarmony/HarmonyOS生态系统的功能性和用户体验,我们需要一款支持打开、编辑PDF文件的应用程序。 使用户能够轻松打开、浏览和编辑PDF文件。该应用将充分利用OpenHarmony/HarmonyO…

激光雷达原理

全球汽车行业正在进行自动化变革&#xff0c;这将彻底改变交通运输的安全和效率水平。 戴姆勒在S级豪华车型中引入L3级自动驾驶&#xff08;L3&#xff0c;在特定条件下自动驾驶&#xff0c;人类驾驶员一旦被请求就会随时接管&#xff09;是自动驾驶革命的一个重大突破。其他多…

Zoho Projects 8.0震撼来袭,项目管理再升级! 全方位功能变化解读

有效的项目管理方法保证项目按照进度、成本、质量要求进行交付&#xff0c;是针对单个项目或项目群的管理&#xff0c;从而确保项目符合企业的战略目标&#xff0c;实现企业收益最大化。 对于项目管理工作来说&#xff0c;我们通常会认为只有专业的经理才能胜任&#xff0c;软件…

k8s中容器的调度与创建:CRI,cgroup

container调度与创建 选自&#xff1a;K8s、CRI与container - packy的文章 - 知乎 https://zhuanlan.zhihu.com/p/102897620 Cgroup创建&#xff1a; cgexec -g cpu,memory:$UUID \ > unshare -uinpUrf --mount-proc \ > sh -c "/bin/hostname $UUID &…

力扣hot100题解(python版36-40题)

36、二叉树的中序遍历 给定一个二叉树的根节点 root &#xff0c;返回 它的 *中序 遍历* 。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,3,2]示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[]示例 3&#xff1a; 输入&am…

四、西瓜书——支持向量机

第六章 支持向量机 1.间隔与支持向量 支持向量机的原理是寻找与支持向量具有最大间隔的划分超平面。支持向量机具有一个重要性质: 训练完成后,大部分的训练样本都不需保留,最终模型仅与支持向量有关. 首先&#xff0c;超平面的方程为&#xff1a; 点到超平面的距离为&#xff…

如何通过Jenkins进行自动化构建项目

1. 介绍 Jenkins 是一个开源的持续集成&#xff08;CI&#xff09;和持续交付&#xff08;CD&#xff09;工具&#xff0c;旨在自动化软件开发过程中的构建、测试和部署。它是一个基于 Java 编写的自动化服务器&#xff0c;在软件开发生命周期的各个阶段提供自动化支持。 官方…

c语言经典测试题10

1.题1 int fun( int x) {int n 0;while (x 1){n;x x | (x 1);}return n; } int main() {int ret fun(2014);printf("%d", ret);return 0; } 上述代码运行结果是什么呢&#xff1f; 我们来分析一下&#xff1a;这里的fun函数有一个while循环&#xff0c;其判断…

改造小技巧:如何将客厅与阳台完美连通?福州中宅装饰,福州装修

问1&#xff1a;什么户型结构更适合客厅打通阳台&#xff1f; 一般来说&#xff0c;现代、简约或者开放式的户型结构更适合将客厅与阳台打通。这样可以通过移除非承重墙来增加室内采光和空间感。需要注意的是&#xff0c;在打通之前&#xff0c;需要考虑房屋的结构和承重墙的位…

Qt下使用modbus-c库实现PLC线圈/保持寄存器的读写

系列文章目录 提示&#xff1a;这里是该系列文章的所有文章的目录 第一章&#xff1a;Qt下使用ModbusTcp通信协议进行PLC线圈/保持寄存器的读写&#xff08;32位有符号数&#xff09; 第二章&#xff1a;Qt下使用modbus-c库实现PLC线圈/保持寄存器的读写 文章目录 系列文章目录…

【活动】前端世界的“祖传代码”探秘:从古老魔法到现代重构

作为一名前端工程师&#xff0c;我时常在项目中邂逅那些被岁月打磨过的“祖传代码”。它们就像古老的魔法书页&#xff0c;用HTML标签堆砌起的城堡、CSS样式表中的炼金术&#xff0c;以及JavaScript早期版本中舞动的符咒。这些代码承载着先驱们的探索精神和独特智慧&#xff0c…

内网信息搜集

目录 内网基础知识 基本流程图 怎么判断是否在域内 常规信息类收集-应用&服务&权限等 cs信息搜集 bloodhound安装及使用 内网基础知识 工作组&#xff1a;将不同的计算机按照功能分别列入不同的组&#xff0c;想要访问某个部门的资源&#xff0c;只要在【网络】里…

种地,成了“糊咖”最好的医美

在《种地吧&#xff0c;少年》&#xff08;后简称《种地吧》&#xff09;第二季上线后&#xff0c;这部综艺开启了在骨朵、猫眼、灯塔、艺恩各大综艺榜单的持续霸榜。上线至今&#xff0c;有一半的时间占据在日榜单热度TOP1的位置。 根据灯塔专业版数据显示&#xff0c;《种地…

《TCP/IP详解 卷一》第8章 ICMPv4 和 ICMPv6

目录 8.1 引言 8.1.1 在IPv4和IPv6中的封装 8.2 ICMP 报文 8.2.1 ICMPv4 报文 8.2.2 ICMPv6 报文 8.2.3 处理ICMP报文 8.3 ICMP差错报文 8.3.1 扩展的ICMP和多部报文 8.3.2 目的不可达和数据包太大 8.3.3 重定向 8.3.4 ICMP 超时 8.3.5 参数问题 8.4 ICMP查询/信息…

selenium爬虫

方法选择和安装包 在动态网页并且登陆过程中不需要进行过于复杂的密码验证的时候使用selenium会非常的方便 安装准备过程也相对简单&#xff1a; 下载对应版本的chromedriver并且通过如下代码找到路径下载到python所在的目录&#xff1a; import sysprint(sys.executable) …

Bert-as-service 学习

pip3 install --user --upgrade tensorflow 安装遇到的问题如下&#xff1a; pip3 install --user --upgrade tensorflow 1052 pip uninstall protobuf 1053 pip3 uninstall protobuf 1054 pip3 install protobuf3.20.* 1055 pip3 install open-clip-torch2.8.2 1…

C++/数据结构:AVL树

目录 一、AVL树的概念 二、AVL树的实现 2.1节点定义 2.2节点插入 三、AVL树的旋转 3.1新节点插入较高左子树的左侧&#xff1a;右单旋 3.2新节点插入较高右子树的右侧&#xff1a;左单旋 3.3新节点插入较高左子树的右侧---左右&#xff1a;先左单旋再右单旋 3.4新节点插…

数据结构篇十:红黑树

文章目录 前言1. 红黑树的概念2. 红黑树的性质3. 红黑树节点的定义4. 红黑树的插入4.1 情况一&#xff1a; cur为红&#xff0c;p为红&#xff0c;g为黑&#xff0c;u存在且为红4.2 情况二: cur为红&#xff0c;p为红&#xff0c;g为黑&#xff0c;u不存在/u存在且为黑。4.2.1 …