【面试 - 遇到的问题】Vue 里 router-view 使用 key + 关闭页面后重新打开页面-获取的数据赋值到旧组件问题(钩子执行顺序)

devtools/2024/12/21 23:08:44/

目录

  • 【1】问题描述
  • 【2】问题排查前 - 页面渲染、tag 页签渲染 逻辑梳理
    • 页面渲染
      • 【借用别人的描述】`<router-view :key="key" />`
        • 1. 不设置key 属性
        • 2. 设置 key 属性值为 $route.path
          • /page/1 => /page/2
          • /page?id=1 => /page?id=2,
        • 3. 设置 key 属性值为 $route.fullPath
          • /page/1 => /page/2
          • /page?id=1 => /page?id=2
    • tag 页签渲染
  • 【3】问题排查
  • 【4】解决

【1】问题描述

  1. 首次打开页面,弹框中有数据在这里插入图片描述
  2. 点击 tag 页签关闭当前页面
    ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6056d67fceb249b983066dc077dea36e.png
  3. 再次打开弹框,数据不展示在这里插入图片描述

【2】问题排查前 - 页面渲染、tag 页签渲染 逻辑梳理

页面渲染

<keep-alive><router-view :key="key" />
</keep-alive>
  • key 作为路由页面唯一标识,这里 key 为页面 fullPath 拼接当前时间戳 ,拼接时间戳以确保唯一性,避免不同页面 fullPath 一致

【借用别人的描述】<router-view :key="key" />

https://blog.51cto.com/knifeedge/5627137

  • Vue 会 复用相同组件,对于路由有 多个子路由 来说,当在 子路由来回切换 时,会导致 页面不刷新 的问题,因为不再执行 created 和 mounted 这些钩子函数。<router-view :key=“key“/> 中的 key 即可解决这个问题。
    • 官网里边有一句:Vue 为你提供了一种方式来表达 “这两个元素是完全独立的,不要复用它们” 。只需添加一个具有唯一值的 key attribute 即可
    • 缺点:加了路由的key值,Vue就会认为这不是同一个组件,update的时候会删除这个组件再重新加载一个新的组件,有严重的性能问题。比如:
      • 在后台系统中,点击侧导航菜单子菜单时,设置了:key="$route.path"会导致菜单关闭又打开,视觉效果不好。且如果新的组件未加载完成时获取数据,则会导致新加载的组件内没有得到数据赋值。 ------ 最后这句和本文章所描述问题有关

代码示例

<template><section class="app-main"><transition name="fade-transform" mode="out-in"><router-view :key="key" /></transition></section>
</template><script>javascript">
export default {name: 'AppMain',computed: {key() {return this.$route.fullPath}}
}
</script>
1. 不设置key 属性

Vue 会复用相同组件, 即: /page/1 => /page/2 或者 /page?id=1 => /page?id=2 这类链接跳转时, 不执行created, mounted之类的钩子, 这时候你需要在路由组件中添加beforeRouteUpdate钩子来执行相关方法拉去数据

相关钩子函数为: beforeRouteUpdate

2. 设置 key 属性值为 $route.path
/page/1 => /page/2

由于这两个路由的$route.path不一样, 所以组件被强制不复用, 相关钩子加载顺序为: beforeRouteUpdate => created => mounted

/page?id=1 => /page?id=2,

由于这两个路由的$route.path一样, 所以和没设置 key 属性一样, 会复用组件, 相关钩子加载顺序为: beforeRouteUpdate

3. 设置 key 属性值为 $route.fullPath
/page/1 => /page/2

由于这两个路由的$route.fullPath不一样, 所以组件被强制不复用, 相关钩子加载顺序为: beforeRouteUpdate => created => mounted

/page?id=1 => /page?id=2

由于这两个路由的$route.fullPath不一样, 所以组件被强制不复用, 相关钩子加载顺序为: beforeRouteUpdate => created => mounted

tag 页签渲染

项目中每访问一个页面就将页面路由信息保存在 visitedViews 数据中,tag 页签 就是 通过 visitedViews 数据,使用 router-link 来渲染,从而实现点击 tag 页签 页面路由跳转的效果。

【3】问题排查

在这里插入图片描述

上图 紫色框问题描述1 中页面组件, 红色框问题描述3 中页面组件,经过 问题描述2 后,问题描述1 的组件不会被复用(因为 <router-view :key="key" />key ),再次进入页面时,产生了一个新的页面组件,也就是 红色框

【问题排查过程】

  • 仔细排查代码发现 → 问题描述 中页面未展示的 数据获取 是在 beforeRouteEnter 中进行的,此时还 未产生新的组件红色框的组件)→ 所以获取到的数据其实 赋值给了旧的不被复用组件 中(紫色框的组件) → 导致红色组件加载渲染完毕后, beforeRouteEnter 中获取的数据并未正确展示展示。
  • 新旧组件 => 两个组件其实 展示的页面是一个,只不过因为 <router-view :key="key" /> 中 有 key 所以导致当前页面 第一次被关掉 之后在打开的时候 key 中拼接的 时间戳 与第一次打开的组件key中的 时间戳不一致,所以回产生一个 新的组件,而 不会复用旧组件

【4】解决

beforeRouteEnter 中获取数据 改为 在 mounted 钩子中获取数据, mounted 是页面渲染完成后调用的钩子,也就是新组件此时已加载完毕,此时获取数据并进行赋值操作都是在新组件中进行。


http://www.ppmy.cn/devtools/144205.html

相关文章

Spring Boot 2.1.7 数据源自动加载过程详解

在 Spring Boot 中&#xff0c;数据源的自动配置是框架中一个关键功能&#xff0c;本文将以 Spring Boot 2.1.7 版本为例&#xff0c;详细讲解在单数据源情况下数据源是如何自动加载的。我们通过源码分析&#xff0c;追踪整个加载流程。 1. 自动配置类的发现 Spring Boot 使用…

自然语言处理的不同流派

基于规则的专家系统&#xff1a; 在早期的NLP研究中&#xff0c;基于规则的方法占据主导地位。这种方法依赖于语言学家和计算机科学家手工编写的一系列规则来指导计算机如何理解和生成语言。这些规则通常基于语言学理论&#xff0c;如乔姆斯基的转换生成语法。优点是系统在规则…

多个Echart遍历生成 / 词图云

echart官网 安装 如果版本报错推荐安装以下版本 npm install echarts4.8.0 --savenpm uninstall echarts//这个是卸载命令以下安装成功后是局部引入:多个Echart遍历生成 vue3echart单个页面多个图表循环渲染展示:<template><div class"main"><div …

作业Day4: 链表函数封装 ; 思维导图

目录 作业&#xff1a;实现链表剩下的操作&#xff1a; 任意位置删除 按位置修改 按值查找返回地址 反转 销毁 运行结果 思维导图 作业&#xff1a;实现链表剩下的操作&#xff1a; 1>任意位置删除 2>按位置修改 3>按值查找返回地址 4>反转 5>销毁 任意…

metagpt中ActionNode的用法

目录 整体流程1. 基础组件&#xff1a;2. SIMPLE_THINK_NODE 和 SIMPLE_CHECK_NODE&#xff1a;3. THINK_NODES 类&#xff1a;4. ThinkAction 类&#xff1a;5. SimplePrint 类&#xff1a;6. Printer 类&#xff1a;7. main 函数&#xff1a;总结&#xff1a;主要执行流程&am…

04、Vue与Ajax

4.1 发送AJAX异步请求的方式 发送AJAX异步请求的常见方式包括&#xff1a; 4.1.1. 原生方式 使用浏览器内置的JS对象XMLHttpRequest const xhr new XMLHttpRequest() xhr.open() xhr.send() xhr.onreadystatechange function(){} 4.1.2. 原生方式 使用浏览器内置的JS函…

基于阿里云日志服务的程序优化策略与实践

背景 我们的服务端程序日志现已全面迁移至阿里云&#xff0c;这一举措极大地便利了我们通过阿里云的日志工具来深入洞察接口的调用状况。 content是个json对象&#xff0c;request和path是content对象下的字段。我的需求是统计每个请求一分钟调用次数。以此为依据考虑优化的方…

RTC实时时钟

BKP&#xff08;备份寄存器&#xff09; 1. 什么是BKP&#xff1f; 备份寄存器是42个16位的寄存器&#xff0c;可用来存储84个字节的用户应用程序数据。他们处在备份域里&#xff0c;当VDD电 源被切断&#xff0c;他们仍然由VBAT维持供电。当系统在待机模式下被唤醒&#xff…