首页 > 其他分享 >单页面下模拟路由跳转

单页面下模拟路由跳转

时间:2023-11-21 17:00:10浏览次数:29  
标签:vue push 跳转 组件 query 路由 页面

项目需求:一个路由页面下展示多个页面,且切换时要像真正的路由一样可以携带路由参数

三个前置知识:

  1. vue不允许在路由栈中推入同一URL地址,否则会告警:NavigationDuplicated: Avoided redundant navigation to current location: "/route".
  1. 在以react、vue为代表的SPA项目中,在万物皆组件的今天,所谓路由的切换其实仅是不同组件的切换而已。(写到这里,不由得想到一句话:我们从html学到了js再学到以vue/react为代表的生态框架,本质上也不过在一个div里打打闹闹而已,这个div叫#app...)
  1. 路由间跳转时如果有参且参数是query类型时,在刷新时将不会丢失参数

基于项目需求以及前置知识:

  1. 画出了思维导图
  2. 设计基础逻辑
// page.vue
<template>
  <div>
    <p1 v-if="currentNode === 1"/>
    <p2 v-if="currentNode  === 2"/>
    <p3 v-if="currentNode === 3"/>
  </div>
</template>
<script>
import p1 from './p1.vue'
import p2 from './p2.vue'
import p3 from './p3.vue'
export default {
  components: {
    p1,
    p2,
    p3
  },
  data() {
   return {
     currentNode : 1   // 当前展示组件
   }
  }

}
</script>

一:修复重复告警问题:
为了规避前置1产生的问题,重写了routerInstance方法

// ./router/index.js
// 重写路由push方法以规避`NavigationDuplicated: Avoided redundant navigation to current location: "/route".`告警
const originalPush = VueRouter.prototype.push;
VueRouter.prototype.push = function push(location) {
  return originalPush.call(this, location).catch((err) => err);
};

二:设计组件切换逻辑

这里其实想了很多种方法,原先想使用window.location.href + query的方式,但是由于此方法会导致页面白屏而放弃,后来又尝试在每个子组件中emit对应的值来使当前组件动态切换, 但总觉得不够优雅,遂将其作为兜底方案,直到后来想到了终极解决方案后便放弃了此方案

终极方案便是利用watch+routerQuery。
即:
index页监听routeQuery对象,各个子组件内像使用路由跳转一样跳转(仅支持push),而watch存在的目的在于通过监听query的参数以进行组件间的切换

  • 浅灰标识跳转至,深灰标识回退至

贴贴:

// page.vue
  watch: {
    // 模拟路由跳转 -》`routerInstance`重写了router的`push`方法,因而不会告警
    // 通过监听路由参数进行组件间的切换 子组件可以直接使用this.$router.push(xxx)以达到类路由跳转效果
    /**
     * A : 初始页: 去中间: query1  去末 query2
     * B:  中间页    去末:query1  + query2  回初始不带参
     * C:  末页    回中间:query2  回初始不带参
     * */
    "$route.query": {
      handler(n) {
        // 如果没有query,则展示组件1
        if (!Object.values(n).length) {
          this.currentNode = 1;
          return;
        }
        // 如果有组件2必须的query1参数且query参数为1,则展示组件2
        if (Object.values(n).length === 1 && `query1` in n) {
          this.currentNode = 2;
          return;
        }
        // 仅判断组件3必须参数query2,有则展示组件3
        if (`query2` in n) {
          this.currentNode = 3;
          return;
        }
        // 除此以外,均展示组件1
        this.currentNode = 1;
      },
      deep: true,
      immediate: true,
    },
  },

在从中间页前往末页时可能并不需要query1(中间页本身的参数),但是我们依然要加上去,这样传参的目的是为了区分末页的上一页是谁以实现back功能(见图2)

而当我们在page页中写好了以上逻辑以后,就可以在子组件内像跳转正常路由一样跳转了,不同的是跳转的是同一个路由页,只不过参数不同,这也是我们在写这一类场景时要注意的点之一

假设page页的路由名是/wzdxcsk(我真的想吃烧烤),则在组件1中想跳转组件2/组件3则可以:

//p1.vue
// 组件1动态跳转组件2/组件3
methods:{
  navToComp2(id,type){
    // 动态跳转
    const queryObj = {
      2: {
        query1: id,
      },
      3: {
        query2: id,
      },
    };
    this.$router.push({
      path: "/wzdxcsk",
      query: queryObj[type],
    });
  },
}

假设组件3想要回退至上一页则可以:

//p3.vue
// 组件3动态跳转组件2/组件1
methods:{
 // 回退
  back() {
    this.$router.push({
      path: "/wzdxcsk",
  // 回退校验
      query:
        `query1` in this.$route.query
          ? {
              query1: this.$route.query.query1,
            }
          : {},
    });
  },
}

整体逻辑:

在单页面中通过变量currentNode来控制子组件显隐,通过watch路由参数来控制具体哪个子组件显示,通过重写routerInstance实例的push方法来规避重复推入相同路由告警,子组件通过常规push方法实现回退&前进,前进回退时通过唯一query来判定跳转的子组件页面,由于url上有路由参数,则页面在刷新后依然可以根据watch自动展示不同的组件 。

希望读者在遇到此类需求时可以有一个参考

以上。

标签:vue,push,跳转,组件,query,路由,页面
From: https://www.cnblogs.com/hjk1124/p/17846986.html

相关文章

  • nuxt3设置404页面
    1.在你的page目录下新建一个[...slug].vue的文件,文件内容为自定为自定义的404内容<!--404页面--><template><divclass="error-page">404</div></template><scriptsetuplang="ts">setResponseStatus(404)</script>......
  • 笔记:华为路由器的使用方法与CTL终端基本操作
    使用华为路由器的方法与基本操作:在本文中可能出现下列命令行格式,它们所代表的含义如下。格式意义粗体命令行关键字(命令中保持不变、必须照输的部分)采用加粗字体表示。斜体命令行参数(命令中必须由实际值进行替代的部分)采用斜体表示。[]表示用“[......
  • pigx 单体 首页跳转
    <template> <divclass="layout-padding"> <divclass="layout-padding-autolayout-padding-view"> <div:style="'display:'+panalVisible.zkt1"><zkt1/></div> <div:style=&......
  • 路由层之简单路由配置 APPEND_SLASH
    1路由参数#第一个参数是正则表达式#第二个参数是视图函数内存地址#第三个参数是个字典{'name':lqz,'age':18},给视图函数传递默认值#第四个参数name,当前路由的别名,用作反向解析url(r'^home2/',views.home,{'name':'lqz','age':19},name='home�......
  • 聊聊如何利用springcloud gateway实现简易版灰度路由
    前言前阵子时间和朋友聊天,他们有个sass微服务,因为之前拆分过细,导致服务不仅调用链路过长,而且浪费服务资源,他们后面做了服务合并的重构,并即将上线。他觉得上线不能直接把线上的租户都全切到重构版的sass微服务,而是需要实现如下的效果他就问我说,有没有啥开源平台可以快速支持,因为......
  • vue3路由重定向失效
    页面刷新时遇到路由重定向无效的问题,可能是因为路由重定向是在客户端进行的,而页面刷新会重新加载整个应用程序,导致重定向逻辑丢失。为了解决这个问题,你可以使用服务器端的重定向来确保在页面刷新时也能正确地重定向到指定的路由。以下是一种常见的解决方案:在服务器端配置,确保......
  • $router.push()中通过path跳转和通过name跳转有什么区别
    今天在路由跳转传参时发现params传参接收到的总是为空,才发现通过path和name传参是有区别的path传参要完整的路径,不能带参数。name传参可以带params。params的传参页面刷新会丢失,query的传参不会丢失使用path进行跳转:当你使用path进行跳转时,你需要提供完整的路径字符串,包括......
  • 手撕Vue-Router-提取路由信息
    前言好了经过上一篇的学习,我们已经知道了如何监听Hash的变化,如何监听路径的一个变化,本篇我们就可以来实现我们自己的VueRouter了,那么怎么实现呢,在实现之前我们先来回顾一下官方的VueRouter是怎么使用的。VueRouter的使用首先需要去下载官方的VueRouter,如果是通过np......
  • 路由匹配
    #路由匹配url(r'test',views.test),url(r'testadd',views.testadd)"""url方法第一个参数是正则表达式 只要第一个参数正则表达式能够匹配到内容那么就会立刻停止往下匹配 直接执行对应的视图函数你在输入url的时候会默认加斜杠 django内部帮你做到重定向 一次匹配不行 url后......
  • boot3+JDK17+spring-cloud-gateway:4.0.0+spring-cloud:2022.0.0.0+Nacos2.2.1配置动
    项目依赖配置#Nacos帮助文档:https://nacos.io/zh-cn/docs/concepts.html#Nacos认证信息spring.cloud.nacos.config.username=nacosspring.cloud.nacos.config.password=nacosspring.cloud.nacos.config.contextPath=/nacos#设置配置中心服务端地址spring.cloud.naco......