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

news2024/11/15 8:27:53

场景:移动端有 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>

三、总结:

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

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

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

相关文章

Linux安装Nginx配置Keepalived高可用

Vmwaire 安装 Linux 解决启动没有IP地址问题 cd /etc/sysconfig/network-scripts vi ifcfg-ens33# 重启linux reboot # 再次查看ip ip addrLinux 镜像地址下载 ps: 发现阿里有一个工具箱&#xff0c;里面有各种镜像 阿里镜像地址 https://developer.aliyun.com/mirror/ 安装…

计算机设计大赛 深度学习图像修复算法 - opencv python 机器视觉

文章目录 0 前言2 什么是图像内容填充修复3 原理分析3.1 第一步&#xff1a;将图像理解为一个概率分布的样本3.2 补全图像 3.3 快速生成假图像3.4 生成对抗网络(Generative Adversarial Net, GAN) 的架构3.5 使用G(z)生成伪图像 4 在Tensorflow上构建DCGANs最后 0 前言 &#…

windows安装部署node.js以及搭建运行第一个Vue项目

一、官网下载安装包 官网地址&#xff1a;https://nodejs.org/zh-cn/download/ 二、安装程序 1、安装过程 如果有C/C编程的需求&#xff0c;勾选一下下图所示的部分&#xff0c;没有的话除了选择一下node.js安装路径&#xff0c;直接一路next 2、测试安装是否成功 【winR】…

cv_bridge连接自定义版本的opencv

在ros noetic版本中&#xff0c;默认的cv_bridge依赖的opencv版本为4.2.0&#xff0c;若要升级opencv版本&#xff0c;则无法使用cv_bridge&#xff0c;所以需要重新自编译cv_bridge。 一. 编译cv_bridge 1.通过网站 https://github.com/ros-perception/vision_opencv/tree/n…

MYSQL的优化学习,从原理到索引,在到事务和锁机制,最后的主从复制、读写分离和分库分表

mysql的优化学习 为什么选择Mysql不选择其他的数据库&#xff1f;还有哪些&#xff0c;有什么区别&#xff1f; Mysql&#xff1a;开源免费版本可用&#xff0c;适用于中小型应用 Oracle&#xff1a;适用于大型企业级应用&#xff0c;复杂的业务场景和大量数据的处理&#xf…

Acwing 每日一题 空调 差分 贪心

&#x1f468;‍&#x1f3eb; 空调 &#x1f468;‍&#x1f3eb; 参考题解 import java.util.Scanner;public class Main {static int N (int) 1e5 10;static int[] a new int[N];static int n;public static void main(String[] args){Scanner sc new Scanner(System.…

智能家居控制系统(51单片机)

smart_home_control_system 51单片机课设&#xff0c;智能家居控制系统 使用及转载请标明出处&#xff08;最好点个赞及star哈哈&#xff09; Github地址&#xff0c;带有PPT及流程图 Gitee码云地址&#xff0c;带有PPT及流程图 ​ 以STC89C52为主控芯片&#xff0c;以矩阵键…

【OpenCV C++】Mat img.total() 和img.cols * img.rows 意思一样吗?二者完全相等吗?

文章目录 1 结论及区别2 Mat img的属性 介绍1 结论及区别 在大多数情况下,img.total() 和 img.cols * img.rows 是相等的,但并不总是完全相等的。下面是它们的含义和一些区别: 1.img.total() 表示图像中像素的总数,即图像的总像素数量。2.img.cols * img.rows 也表示图像中…

C++学习笔记:二叉搜索树

二叉搜索树 什么是二叉搜索树?搜索二叉树的操作查找插入删除 二叉搜索树的应用二叉搜索树的代码实现K模型:KV模型 二叉搜索树的性能怎么样? 什么是二叉搜索树? 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: 若它的左子树…

【go语言开发】swagger安装和使用

本文主要介绍go-swagger的安装和使用&#xff0c;首先介绍如何安装swagger&#xff0c;测试是否成功&#xff1b;然后列出常用的注释和给出使用例子&#xff1b;最后生成接口文档&#xff0c;并在浏览器上测试 文章目录 安装注释说明常用注释参考例子 文档生成格式化文档生成do…

代码随想录算法训练营第二十八天|93.复原IP地址 、78.子集、90.子集II

文章目录 [1.复原 IP 地址](https://leetcode.cn/problems/restore-ip-addresses/description/)2.子集[3.子集 II](https://leetcode.cn/problems/subsets-ii/) 1.复原 IP 地址 切割问题可以使用回溯&#xff0c;本题分别两步&#xff0c;切割字符串和判断IP 切割逻辑如下&…

微信小程序 --- 分包加载

分包加载 1. 什么是分包加载 什么是分包加载 ❓ 小程序的代码通常是由许多页面、组件以及资源等组成&#xff0c;随着小程序功能的增加&#xff0c;代码量也会逐渐增加&#xff0c;体积过大就会导致用户打开速度变慢&#xff0c;影响用户的使用体验。 分包加载是一种小程序…

MATLAB图像噪声添加与滤波

在 MATLAB 中添加图像噪声和进行滤波通常使用以下函数&#xff1a; 添加噪声&#xff1a;可以使用imnoise函数向图像添加各种类型的噪声&#xff0c;如高斯噪声、椒盐噪声等。 滤波&#xff1a;可以使用各种滤波器对图像进行滤波处理&#xff0c;例如中值滤波、高斯滤波等。 …

(三)电机控制之方波驱动无刷直流电机(BLDC)与正弦波驱动无刷直流电机(PMSM)的详细对比

电流控制方式和波形&#xff1a; 方波驱动&#xff1a;在每个换相周期内&#xff0c;定子绕组中的电流被切换为高或低两个状态&#xff0c;形成矩形波。通常采用六步换向法&#xff0c;即每60度电角度换相一次&#xff0c;从而产生转矩。正弦波驱动&#xff1a;定子绕组中流过的…

Doris实战——拈花云科的数据中台实践

前言 拈花云科 NearFar X Lab 团队调研并引进 Doris 作为新架构下的数据仓库选型方案。本文主要介绍了拈花云科数据中台架构从 1.0 到 2.0 的演变过程&#xff0c;以及 Doris 在交付型项目和 SaaS 产品中的应用实践。 一、业务背景 拈花云科的服务对象主要是国内各个景区、景点…

安卓虚拟机ART和Dalvik

目录 一、JVM和Dalvik1.1 基于栈的虚拟机字节码指令执行过程 1.2 基于寄存器的虚拟机 二、ART与Dalvikdex2aotAndroid N的运作方式 三、总结 一、JVM和Dalvik Android应用程序运行在Dalvik/ART虚拟机&#xff0c;并且每一个应用程序对应有一个单独的Dalvik虚拟机实例。 Dalvik…

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

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

爬取博客的图片并且将它存储到响应的目录

目录 前言 思想 注意 不多说解释了&#xff0c;贴代码吧 config.json Get_blog_img.py 把之前的写的代码也贴上 Get_blog_id.py 主函数 main.py 运行结果 前言 在上一篇博客中我们介绍了如何爬取博客链接 利用python爬取本站的所有博客链接-CSDN博客文章浏览阅读74…

CSS转换(2D)transform属性及animation动画

1、倾斜效果&#xff0c;旋转效果 <style type"text/css"> .transrorm_bar{ padding:150px; display: flex; align-items: center;} .transrorm_bar div{ width: 120px; height: 120px; background-color: #eee; margin: 10px; display: flex; align-items: c…

爬虫入门到精通_实战篇8(分析Ajax请求并抓取今日头条美食美图)_界面上抓取Ajax方式

1 目标 目标&#xff1a; 抓取今日头条美食美图&#xff0c;如下&#xff1a; 一些网页直接请求得到的HTML代码并没有在网页中看到的内容&#xff0c;因为一些信息是通过Ajax加载&#xff0c;并通过js渲染生成的&#xff0c;这时就需要通过分析网页的请求来获取想要爬取的内容…