vue-router个人的记录

这里说明一下,这里我得出了两个结论,关于编程式导航的push()方法的使用总结,具体看编程式导航 | Vue Router (vuejs.org) 。我在使用动态路由的过程中,发现了一些对自己有用的问题。
在vue-router的编程式导航中,

router.push(“/XXX”)

以斜杠开头的是,跳转到从/(斜杠)根路径,开始一个层级一个层级路由找下去并展示。

router.push(“XXX”)

没有从斜杆开始,跳转到的路由是当前路由的子路由,或者是当前路由的同级路由。所以这里有两种写跳转路由是分两种情况。

一种是router.push(“/XXX”),
另外一种是router.push(“XXX”)。

这里从父路由跳转到子路由,或者跳转到同级路由亦可以使用

router.push(“/XXX/XXX”)

这种形式写完整路径,也可以使用

router.push(“XXX”)

这种相对路径,如果是使用router.push()不同级别的路由相互跳转,记得把完整路径跳转,这样可以在一定程度上避免问题。这里建议写完整的路径,可以一眼看出路由的关系,方便阅读,至少跟容易知道跳转到的是那个路由的内容。
后面是,自己在使用vue-router是遇到问题的模拟过程,也是得出上述结论的过程。具体看后面的内容

个人在使用vue-router时的问题记录

代码后面后截图说明,可以看到对应的效果

vue-router的官网地址

因为我使用的是vite+vue+ts,所以这里需要使用到vue-router@4
开始 | Vite 官方中文文档 (vitejs.dev) 这里有创建vue项目的教程
安装 | Vue Router (vuejs.org)
npm安装

npm install vue-router@4

项目文件位置和截图如下所示

在这里插入图片描述
其中,router目录放的是路由相关的配置,views目录放的是路由组件

App.vue的代码如下所示

<template>
  <div>
    <!-- 路由占位 -->
    <router-view></router-view>
  </div>
</template>

<script setup lang="ts">

</script>


<style scoped>

</style>

路由组件index.vue代码如下

<template>
  <div>
    <div>
      <h2>这个是index.vue的首页,也是App.vue中的路由子组件之一,即App.vue中的router-view标签展示的内容</h2>
    </div>
    <div>以下是这个index.vue组件的子路由组件展示,即index.vue中router-view标签展示的内容</div>
    <hr>
    <!-- 路由占位 -->
    <router-view></router-view>
  </div>
</template>

<script setup lang="ts">

</script>

<style scoped>

</style>

路由组件ChildrenOne.vue代码如下

<template>
  <div class="children-one">
    <h1>这是index.vue的路由子组件111111111</h1>
  </div>
</template>

<script setup lang="ts">
</script>

<style scoped>
.children-one {
  background-color: aqua;
}
</style>

路由组件ChildrenTow.vue代码如下

<template>
  <div class="children-tow">
    <h1>这是index.vue的路由子组件2222</h1>
  </div>
</template>

<script setup lang="ts">
</script>

<style scoped>
.children-tow {
  background-color: pink;
}
</style>

路由组件ChildrenThree.vue代码如下

<template>
  <div class="children-three">
    <h1>这是index.vue的路由子组件3333</h1>
  </div>
</template>

<script setup lang="ts">
</script>

<style scoped>
.children-three {
  background-color: orange;
}
</style>

路由组件404.vue代码如下

<template>
  <div>
    <h1>404页面</h1>
  </div>
</template>

<script setup lang="ts">
</script>

<style scoped>
</style>

路由配置index.ts代码

注意看代码中,关于子路由的路径配置,有时候少一个斜杆(/)或者多一个斜杆(/)都不行,我在代码中说明了,什么情况下加斜杠(/)什么情况下不加斜杠(/)能正常通过路由访问

import { createRouter, createWebHashHistory } from "vue-router";

// 常规路由
const clientRoutes = [
  {
    path: '/',
    name:'app',
    // 路由重定向
    redirect: '/index',
  }, 
  {
    path: '/index',
    name: 'index.vue路由组件首页',
    component: () => import('../views/index.vue'),
     // 在这里,之后一种写法,如下所示:写法二第一次可以重定向,但是第二次就有问题了,具体看后面的GIF图
    // 写法一:
    // redirect: '/index/childrenOne', // 重定向,路由地址可以正常访问,在浏览器中重新输入地址也可以,也就是说这里只能写这种
    // 如果,不想无端端报错的话
    // 写法二:
    redirect: 'index/childrenOne', // 重定向,路由地址第一次可以正常访问,
    // 但是地址栏重新输入就不能跳转了,不加/(斜杆)。所以这种写法是有问题的,第二次输入路由地址就相当于找当前路由的子路由的
    children: [
      {
        // 在子集路由中也有两种写法,也是可以正常访问的
        // path: 'childrenOne', // 写法1,可以正常访问,访问的时候加上父路径如/index/childrenOne
        path: '/index/childrenOne', // 写法2,可以正常访问,访问的时候加上父路径如/index/childrenOne

        // 但是注意了,下面这两种写法是不行的,不能正常访问的
        // path: '/childrenOne', // 无法访问写法1,无法正常访问路由,这里就多了一个  /  就不能正常访问路由
        // path: 'index/childrenOne', // 无法访问写法2,无法正常访问路由,这里就少了一个  /  就不能正常访问路由
        name: '路由子组件1', // 路由名称要保证唯一性,不然会有问题,就是无法访问对应的同名的路由路径
        component: () => import('../views/ChildrenOne.vue')
      },
      {
        path: 'childrenTwo',
        name: '路由子组件2',
        component: () => import('../views/ChildrenTow.vue')
      },
      {
        path: 'childrenThree',
        name: '路由子组件3',
        component: () => import('../views/ChildrenThree.vue')
      }
    ]
  },
  {
    path: '/404',
    name: '404',
    component: () => import('../views/404.vue')
  },
  /**
   * 如果路由没有,就跳转到404页面,路由匹配规则
   */
  {
    path: '/:pathMatcher(.*)*',
    name: 'remaining',
    redirect: '/404'
  },
]

const router = createRouter({
  history: createWebHashHistory(),
  routes: clientRoutes
})

export default router

从index.ts路由配置中可以看出,路由路径中path的/ 和/index、/404是在同一级别的路由,也就是App.vue中router-view占位展示的路由组件内容。而 path: ‘/index/childrenOne’、 path: ‘childrenTwo’、path: ‘childrenThree’ 是path: '/index’的子路由,它们属于同一级别的内容,也就是在index.vue中router-view占位展示的路由组件内容。所以这里的路由关系就是App.vue展示index.vue和404.vue的内容,然后index.vue展示的是childrenOne.vue、ChildrenTow.vue、childrenThree.vue的内容。如下图所示
在这里插入图片描述
通过vue的开发工具,可以看到当前项目中的路由信息
在这里插入图片描述

其访问的结果如下图所示

在这里插入图片描述
因为路由配置中,也就是router目录下的index.ts这个路由配置文件,路由index的重定向,没有加/(斜杠),所以这里重新在地址栏中输入index的时候,重定向到子组件1,如下所示
在这里插入图片描述.同时注释掉:
在这里插入图片描述
其结果如下所示:
在这里插入图片描述
然后如果我使用了正确的重定向,如下所示,修改路由配置文件的重定向为正确的路径
在这里插入图片描述
其结果如下所示:
在这里插入图片描述

编程式导航

编程式导航的官网地址:编程式导航 | Vue Router (vuejs.org)
在这里插入图片描述

父路由到子路由编程式导航

修改index.vue的内容如下所示
<template>
  <div>
    <div>
      <h2>这个是index.vue的首页,也是App.vue中的路由子组件之一,即App.vue中的router-view标签展示的内容</h2>
    </div>

    <div class="index-router-to-children">
      <div class="to-children" @click="goIndexChildrenTwo_1">跳转路由子组件2, router.push('/index/childrenTwo')的形式</div>
      <div class="to-children" @click="goIndexChildrenTwo_3">跳转路由子组件2, router.push('index/childrenTwo')的形式</div>
      <div class="to-children" @click="goIndexChildrenTwo_2">跳转路由子组件2, router.push('childrenTwo')的形式</div>
      <div class="to-children" @click="goIndexChildrenTwo_4">跳转路由子组件2, router.push('/childrenTwo')的形式</div>
    </div>

    <div>以下是这个index.vue组件的子路由组件展示,即index.vue中router-view标签展示的内容</div>
    <hr>
    <!-- 路由占位 -->
    <router-view></router-view>
  </div>
</template>

<script setup lang="ts">
// 路由编程式导航
import { useRouter } from 'vue-router';
const router = useRouter()

const goIndexChildrenTwo_1 = () => {
  router.push('/index/childrenTwo')
}

const goIndexChildrenTwo_2 = () => {
  router.push('childrenTwo')
}

const goIndexChildrenTwo_3 = () => {
  router.push('index/childrenTwo')
}

const goIndexChildrenTwo_4 = () => {
  router.push('/childrenTwo')
}

</script>

<style scoped>

.index-router-to-children .to-children {
  padding: 10px;
  margin: 10px; 
  background-color: rgb(204, 230, 230);
}
</style>
路由的配置文件不变,注释掉一些内容就可以了

在router目录下的index.ts中注释掉配置,就是没有路由路径时跳转到404那个,这里为了方便观察,所以需要这样

import { createRouter, createWebHashHistory } from "vue-router";

// 常规路由
const clientRoutes = [
  {
    path: '/',
    name:'app',
    // 路由重定向
    redirect: '/index',
  }, 
  {
    path: '/index',
    name: 'index.vue路由组件首页',
    component: () => import('../views/index.vue'),
    // 在这里,之后一种写法,如下所示:写法二第一次可以重定向,但是第二次就有问题了,具体看后面的GIF图
    // 写法一:
    // redirect: '/index/childrenOne', // 重定向,路由地址可以正常访问,在浏览器中重新输入地址也可以,也就是说这里只能写这种
    // 如果,不想无端端报错的话
    // 写法二:
    redirect: 'index/childrenOne', // 重定向,路由地址第一次可以正常访问,
    // 但是地址栏重新输入就不能跳转了,不加/(斜杆)。所以这种写法是有问题的,第二次输入路由地址就相当于找当前路由的子路由的
    children: [
      {
        // 在子集路由中也有两种写法,也是可以正常访问的
        // path: 'childrenOne', // 写法1,可以正常访问,访问的时候加上父路径如/index/childrenOne
        path: '/index/childrenOne', // 写法2,可以正常访问,访问的时候加上父路径如/index/childrenOne

        // 但是注意了,下面这两种写法是不行的,不能正常访问的
        // path: '/childrenOne', // 无法访问写法1,无法正常访问路由,这里就多了一个  /  就不能正常访问路由
        // path: 'index/childrenOne', // 无法访问写法2,无法正常访问路由,这里就少了一个  /  就不能正常访问路由
        name: '路由子组件1', // 路由名称要保证唯一性,不然会有问题,就是无法访问对应的同名的路由路径
        component: () => import('../views/ChildrenOne.vue')
      },
      {
        path: 'childrenTwo',
        name: '路由子组件2',
        component: () => import('../views/ChildrenTow.vue')
      },
      {
        path: 'childrenThree',
        name: '路由子组件3',
        component: () => import('../views/ChildrenThree.vue')
      }
    ]
  },
  {
    path: '/404',
    name: '404',
    component: () => import('../views/404.vue')
  },
  /**
   * 如果路由没有,就跳转到404页面,路由匹配规则
   */
  // {
  //   path: '/:pathMatcher(.*)*',
  //   name: 'remaining',
  //   redirect: '/404'
  // },
]

const router = createRouter({
  history: createWebHashHistory(),
  routes: clientRoutes
})

export default router

代码截图说明
在这里插入图片描述
在这里插入图片描述

注意这个router.push()是在父路由组件idnex.vue中的,可以通过编程时导航展示对应的子路由组件,如上图所是的关系图 ,可以省略写去父组件的地址,点击跳转的时候会自动加上父路由的地址的。也就是父路由router.push(对应的子路由)的这种情况。
在这里插入图片描述
结果如下所示
在这里插入图片描述

同级路由的编程式导航

同级路由之间,也就是同级路由1router.push(同级路由2)这种情况,如下图所示ChildrenOne.vue和ChildrenTow.vue是同级路由,在父路由的index.vue的router-view中展示,它们都有同一个父路由,不写完整路径也可以正常跳转,会自动加上路由的父路径,具体看后面的结果所示

在这里插入图片描述

修改childrenOne.vue的代码
<template>
  <div class="children-one">
    <h1>这是index.vue的路由子组件111111111</h1>
    <div style="border: 2px red solid; height: 50px;  margin: 10px; padding: 10px;" @click="goChildrenTwo_1">
      跳转到同级路由2,childrenTow.vue,使用router.push('/index/childrenTwo')的形式
    </div>
    <div style="border: 2px red solid; height: 50px;  margin: 10px; padding: 10px;" @click="goChildrenTwo_2">
      跳转到同级路由2,childrenTow.vue,使用router.push('childrenTwo')的形式
    </div>
  </div>
</template>

<script setup lang="ts">
// 路由编程式导航
import { useRouter } from 'vue-router';
const router = useRouter()

const goChildrenTwo_1 = () => {
  router.push("/index/childrenTwo")
}

const goChildrenTwo_2 = () => {
 router.push('childrenTwo')
}

</script>

<style scoped>
.children-one {
  background-color: aqua;
}
</style>
修改childrenTwo.vue的代码
<template>
  <div class="children-tow">
    <h1>这是index.vue的路由子组件2222</h1>
    <div style="border: 2px rgb(0, 4, 255) solid; height: 50px; margin: 10px; padding: 10px;" @click="goChildrenOne_1">
      跳转到同级路由1,childrenOne.vue,使用router.push('/index/childrenOne')的形式
    </div>
    <div style="border: 2px rgb(0, 4, 255)solid; height: 50px;  margin: 10px; padding: 10px;" @click="goChildrenOne_2">
      跳转到同级路由1, childrenOne.vue,使用router.push('childrenOne')的形式
    </div>
  </div>
</template>

<script setup lang="ts">
// 路由编程式导航
import { useRouter } from 'vue-router';
const router = useRouter()

const goChildrenOne_1 = () => {
  router.push("/index/childrenOne")
}

const goChildrenOne_2 = () => {
 router.push('childrenOne')
}
</script>

<style scoped>
.children-tow {
  background-color: pink;
}
</style>

在这里插入图片描述

结果如下所示:
在这里插入图片描述
不同级别之间后续再试验一下

子路由到父路由的编程式导航

假设如果是从子路由跳转到父路由,如下图这里从childrenThree.vue这个子路由使用router.push()跳转到父类有idnex.vue,想展示父路由的内容,但是这里没有成功。具体看下面
在这里插入图片描述

修改childrenThree.vue的代码
<template>
  <div class="children-three">
    <h1>这是index.vue的路由子组件3333</h1>
    <div style="border: 2px rgb(136, 255, 0)solid; height: 50px;  margin: 10px; padding: 10px;" @click="goIndex_1">
      子路由3跳转到父路由idnex.vue的内容, 子路由childrenThree.vue,使用router.push('/index')的形式
    </div>
    <div style="border: 2px rgb(136, 255, 0)solid; height: 50px;  margin: 10px; padding: 10px;" @click="goIndex_2">
      子路由3跳转到父路由idnex.vue的内容, 子路由childrenThree.vue,使用router.push('index')的形式
    </div>
  </div>
</template>

<script setup lang="ts">
// 路由编程式导航
import { useRouter } from 'vue-router';
const router = useRouter()

const goIndex_1 = () => {

  // 本来想通过子路由跳转到父路由的,
  // 然后通过父路由的重定向,展示子组件1,
  // childrenOne.vue的内容。这种跳转方式不行
  router.push('/index')
}

const goIndex_2 = () => {
  // 本来想通过子路由跳转到父路由的,
  // 然后通过父路由的重定向,展示子组件1,
  // childrenOne.vue的内容。这种跳转方式也不行
  router.push('index')
}

</script>

<style scoped>
.children-three {
  background-color: orange;
}
</style>

在这里插入图片描述
结果如下所示
在这里插入图片描述
从上面的GIF图我们可以看到,想让子路由childrenThree.vue的跳转到父路由,想展示父路由index.vue的内容,无论是有/(斜杆)还是没有/(斜杆)都不能正常跳转。这里也可以理解,这里在子路由进行router.push()的话,它可以跳转的要么是与子路由的同级路由,要么是子路由的子路由,也可以是父路由。这里就是前面提到的父路由到子路由的编程式导航,同级路由的编程式导航。

如果这里我们按照如下所示注释掉路由根组件的重定向,也就是App.vue中< router-view >展示的内容。这时我们访问npm run dev运行之后,打开url地址,就需要手动输入路由/index才可以访问到index.vue的内容,具体看下面的GIF图
在这里插入图片描述

路由的配置文件不变,只是注释了根组件的重定向而已,代码如下

从路由配置文件我们可以看出,404页面和index页面是在同一级别的路由组件
在这里插入图片描述

import { createRouter, createWebHashHistory } from "vue-router";

// 常规路由
const clientRoutes = [
  {
    path: '/',
    name:'app',
    // 路由重定向
    // redirect: '/index',
  }, 
  {
    path: '/index',
    name: 'index.vue路由组件首页',
    component: () => import('../views/index.vue'),
     // 在这里,之后一种写法,如下所示:写法二第一次可以重定向,但是第二次就有问题了,具体看后面的GIF图
    // 写法一:
    // redirect: '/index/childrenOne', // 重定向,路由地址可以正常访问,在浏览器中重新输入地址也可以,也就是说这里只能写这种
    // 如果,不想无端端报错的话
    // 写法二:
    redirect: 'index/childrenOne', // 重定向,路由地址第一次可以正常访问,
    // 但是地址栏重新输入就不能跳转了,不加/(斜杆)。所以这种写法是有问题的,第二次输入路由地址就相当于找当前路由的子路由的
    children: [
      {
        // 在子集路由中也有两种写法,也是可以正常访问的
        // path: 'childrenOne', // 写法1,可以正常访问,访问的时候加上父路径如/index/childrenOne
        path: '/index/childrenOne', // 写法2,可以正常访问,访问的时候加上父路径如/index/childrenOne

        // 但是注意了,下面这两种写法是不行的,不能正常访问的
        // path: '/childrenOne', // 无法访问写法1,无法正常访问路由,这里就多了一个  /  就不能正常访问路由
        // path: 'index/childrenOne', // 无法访问写法2,无法正常访问路由,这里就少了一个  /  就不能正常访问路由
        name: '路由子组件1', // 路由名称要保证唯一性,不然会有问题,就是无法访问对应的同名的路由路径
        component: () => import('../views/ChildrenOne.vue')
      },
      {
        path: 'childrenTwo',
        name: '路由子组件2',
        component: () => import('../views/ChildrenTow.vue')
      },
      {
        path: 'childrenThree',
        name: '路由子组件3',
        component: () => import('../views/ChildrenThree.vue')
      }
    ]
  },
  {
    path: '/404',
    name: '404',
    component: () => import('../views/404.vue')
  },
  /**
   * 如果路由没有,就跳转到404页面,路由匹配规则
   */
  // {
  //   path: '/:pathMatcher(.*)*',
  //   name: 'remaining',
  //   redirect: '/404'
  // },
]

const router = createRouter({
  history: createWebHashHistory(),
  routes: clientRoutes
})

export default router

结果如下所示,这里就解释了上面为什么子路由想跳转到父路由没有成功的原因了。我们可以看到同级路由的index.vue的内容,和404.vue的内容,可以相互展示。但是如果在浏览器地址输入了/index之后,再输入一次/index的话,就相当于是找/index/index。也就是找这个/index/的index子路由了。从这里就可以得到一个提示,那就是在子路由childrenThree.vue跳转到父路由之前,随便跳转一层不管是否存在的地址,然后再跳转到父路由index.vue的父路由。这样也不行,结果跟子路由到父路由的编程式导航的GIF图是一样的。出现这种现象的原因是因为这个,上面提到过的
在这里插入图片描述

在这里插入图片描述

不同级别的路由编程是导航

文件目录和路由文件的关系如下所示
在这里插入图片描述

在这里插入图片描述

在上面的内容中,我们看到了直接从子路由通过router.push()跳转到父路由是不行的,但是如果是直接跳转到根组件的路由路径/(斜杠),即App.vue的router-view占位的内容,然后通过根组件重定向到路由路径/index,即index.vue组件的router-view占位的内容。这样就通过访问不同级别的路由实现所谓意义上的子路由组件childrenThree.vue,跳转到父路由,展示父路由index.vue的内容。这样也不行,但是跳转到跟index.vue同一级别的404.vue页面就可以,也就是说可以跳转到不同级别的没有关系的路由,但是要把路由不同界别的路由路径写全。也就是下面代码注释中解释的,router.push()什么情况下必须加’/'(斜杠)具体看下面的childrenThree.vue的代码注释。

修改childrenThree.vue组件的代码如下所示

在这里插入图片描述
在这里插入图片描述

<template>
  <div class="children-three">
    <h1>这是index.vue的路由子组件3333</h1>
    <div style="border: 2px rgb(136, 255, 0)solid; height: 50px;  margin: 10px; padding: 10px;" @click="goIndex_1">
      子路由3跳转到父路由idnex.vue的内容, 子路由childrenThree.vue,使用router.push('/')的形式,跳转到跟路由然后利用跟路由重定向到父路由,失败,
      因为上面提到的路由重定向为redirect: 'index/childrenOne',而不是redirect: '/index/childrenOne'
    </div>
    <div style="border: 2px rgb(136, 255, 0)solid; height: 50px;  margin: 10px; padding: 10px;" @click="goIndex_2">
      子路由3跳转到父路由idnex.vue同级的404.vue的内容, 子路由childrenThree.vue,使用router.push('/404')跳转到与index.vue的同级路由404.vue界面,成功
    </div>
    <div style="border: 2px rgb(136, 255, 0)solid; height: 50px;  margin: 10px; padding: 10px;" @click="goHome_3">
      子路由3跳转到父路由idnex.vue同级的Home.vue的内容, 子路由childrenThree.vue,使用router.push('/home')跳转到与index.vue的同级路由Home.vue界面,
      因为/home子路由配置中设置了重定向到Home.vue的子路由组件HomeChildrenOne.vue,成功
    </div>
    <div style="border: 2px rgb(136, 255, 0)solid; height: 50px;  margin: 10px; padding: 10px;" @click="goHomeChldrenTwo_4">
      子路由3跳转到父路由idnex.vue同级的Home.vue的子组件HomeChildrenTwo.vue的内容, 子路由childrenThree.vue,使用router.push('/home/HomeChildrenTWo')直接跳转到与index.vue的同级路
      由Home.vue的子组件,HomeChildrenTWo.vue,成功
    </div>
  </div>
</template>

<script setup lang="ts">
// 路由编程式导航
import { useRouter } from 'vue-router';
const router = useRouter()

const goIndex_1 = () => {

  // 本来想通过子路由跳转到父路由的,
  // 然后通过父路由的重定向,展示子组件1,
  // childrenOne.vue的内容。这种跳转方式不行
  // 因为index的重定向是:'index/childrenOne',而不是redirect: '/index/childrenOne'
  // router.push('/index')
  // 上面那种方式不行,但是下面这种方式也不行
  // 因为index的重定向是:'index/childrenOne',而不是redirect: '/index/childrenOne'
  router.push('/')
}

const goIndex_2 = () => {
  // 本来想通过子路由跳转到父路由的,
  // 然后通过父路由的重定向,展示子组件1,
  // childrenOne.vue的内容。这种跳转方式也不行
  // router.push('index')
  // 与index.vue同一级别的404.vue页面
  // 这里必须是/404,因为这里跳转到与childrenThree.vue组件
  // 的父组件index.vue的同级界面404.vue。
  // 从这篇文章上面的内容我们知道,如果不加/(斜杆)默认访问的
  // 是同级路由,或者子路由界面,
  // 这里的404.vue页面跟childrenThree.vue并不是
  // 同级路由页面和子路由界面,所以必须需要/(斜杆)
  router.push('/404')
}

const goHome_3 = () => {
  // 这里为什么必须加/,
  // 而不是router.push('home')
  // 这个跟上面404的注释解释一样,就必须加/(斜杠)那个
  // 这里可以直接/home可以重定向成功,是因为使用了正确的重定向路径
  //  redirect: '/home/HomeChildrenOne', 有/(斜杠)开头
  router.push('/home')
}

const goHomeChldrenTwo_4 = () => {
  // 这里为什么必须加/,
  // 而不是router.push("home/HomeChildrenTwo")
  // 这个跟上面404的注释解释一样,就必须加/(斜杠)那个
  router.push("/home/HomeChildrenTwo")
}

</script>

<style scoped>
.children-three {
  background-color: orange;
}
</style>
HomeChildrenOne.vue代码如下
<template>
  <div class="home-children-one">
    <h2>这个是路由Home.vue的子组件1111111111111,HomeChildrenOne.vue</h2>
    <hr>
    <div style="border: 2px rgb(72, 23, 247) solid; height: 50px;  margin: 10px; padding: 10px;" @click="goIndex_3">
      子路由组件HomeChildrenOne.vue跳转到父路由Home.vue同级的index.vue的内容, 子路由HomeChildrenOne.vue,使用router.push('/index')跳转到与Home.vue的同级路由idnex.vue界面,
      因为/index子路由配置中设置了重定向到index.vue的子路由组件ChildrenOne.vue,失败
    </div>
    <div style="border: 2px rgb(72, 23, 247) solid; height: 50px;  margin: 10px; padding: 10px;" @click="go404page_3">
      子路由组件HomeChildrenOne.vue跳转到父路由Home.vue同级的404.vue的内容, 子路由HomeChildrenOne.vue,使用router.push('/404')跳转到与Home.vue的同级路由404.vue界面,成功
    </div>
    <div style="border: 2px rgb(72, 23, 247) solid; height: 50px;  margin: 10px; padding: 10px;" @click="goHomeChldrenOne_4">
      子路由组件HomeChildrenOne.vue跳转到父路由Home.vue同级的index.vue的子组件ChildrenOne.vue的内容, 子路由HomeChildrenOne.vue,使用router.push('/index/childrenOne')直接跳转到与Home.vue的同级路
      由idnex.vue的子组件,ChildrenOne.vue,成功
    </div>
    <div style="border: 2px rgb(72, 23, 247) solid; height: 50px;  margin: 10px; padding: 10px;" @click="goHomeChldrenTwo_4">
      子路由组件HomeChildrenOne.vue跳转到父路由Home.vue同级的index.vue的子组件ChildrenTow.vue的内容, 子路由HomeChildrenOne.vue,使用router.push('/index/childrenTwo')直接跳转到与Home.vue的同级路
      由idnex.vue的子组件,ChildrenTow.vue,成功
    </div>
    <div style="border: 2px rgb(72, 23, 247) solid; height: 50px;  margin: 10px; padding: 10px;" @click="goHomeChldrenThree_4">
      子路由组件HomeChildrenOne.vue跳转到父路由Home.vue同级的index.vue的子组件ChildrenThree.vue的内容, 子路由HomeChildrenOne.vue,使用router.push('/index/childrenThree')直接跳转到与Home.vue的同级路
      由idnex.vue的子组件,ChildrenThree.vue,成功
    </div>
    <div>
      总结:(先看GIF图再理解这一句)如果是不同级别的路由跳转,使用router.push()的时候,记得写完整的路径,特别是有子路由路径的情况下,
      记得是/父路由/子路由这样的完整路由路径,具体看上面的几种情况(先看后面的GIF图)就知道了
    </div>
  </div>
</template>

<script setup lang="ts">
// 路由编程式导航
import { useRouter } from 'vue-router';
const router = useRouter()

const goIndex_3 = () => {
  // 这里失败了,原因还在试着找着中,如果有懂的大佬,可不可以跟我说一下。
  router.push("/index")
}

const go404page_3 = () => {
  // 只要威为什么router.push("404")不行,
  // 具体看上面修改的childrenThree.vue关于这里的解释
 router.push("/404")
}

const goHomeChldrenOne_4 = () => {
   // 只要威为什么router.push("index/childrenOne")不行,
  // 具体看上面修改的childrenThree.vue关于这里的解释
  router.push("/index/childrenOne")
}

const goHomeChldrenTwo_4 = () => {
  // 只要威为什么router.push("index/childrenTwo")不行,
  // 具体看上面修改的childrenThree.vue关于这里的解释
  router.push("/index/childrenTwo")
}

const goHomeChldrenThree_4 = () => {
  // 只要威为什么router.push("index/childrenThree")不行,
  // 具体看上面修改的childrenThree.vue关于这里的解释
  router.push("/index/childrenThree")
}
</script>

<style scoped>
.home-children-one {
  background-color: rgb(197, 97, 255);
  margin: 10px;
}
</style>
HomeChldrenTwo.vue的代码如下
<template>
  <div class="home-children-two">
    <h2>这个是路由Home.vue的子组件222222222,HomeChildrenTwo.vue</h2>
  </div>
</template>

<script setup lang="ts">
</script>

<style scoped>
.home-children-two {
  background-color: bisque;
  margin: 10px;
}
</style>
修改路由配置文件如下所示

在这里插入图片描述
在这里插入图片描述

router目录下的路由配置文件,index.ts代码如下

import { createRouter, createWebHashHistory } from "vue-router";

// 常规路由
const clientRoutes = [
  {
    path: '/',
    name:'app',
    // 路由重定向
    redirect: '/index',
  }, 
  {
    path: '/index',
    name: 'index.vue路由组件首页',
    component: () => import('../views/index.vue'),
    // 在这里,之后一种写法,如下所示:写法二第一次可以重定向,但是第二次就有问题了,具体看后面的GIF图
    // 写法一:
    // redirect: '/index/childrenOne', // 重定向,路由地址可以正常访问,在浏览器中重新输入地址也可以,也就是说这里只能写这种
    // 如果,不想无端端报错的话
    // 写法二:
    redirect: 'index/childrenOne', // 重定向,路由地址第一次可以正常访问,
    // 但是地址栏重新输入就不能跳转了,不加/(斜杆)。所以这种写法是有问题的,第二次输入路由地址就相当于找当前路由的子路由的
    children: [
      {
        // 在子集路由中也有两种写法,也是可以正常访问的
        // path: 'childrenOne', // 写法1,可以正常访问,访问的时候加上父路径如/index/childrenOne
        path: '/index/childrenOne', // 写法2,可以正常访问,访问的时候加上父路径如/index/childrenOne

        // 但是注意了,下面这两种写法是不行的,不能正常访问的
        // path: '/childrenOne', // 无法访问写法1,无法正常访问路由,这里就多了一个  /  就不能正常访问路由
        // path: 'index/childrenOne', // 无法访问写法2,无法正常访问路由,这里就少了一个  /  就不能正常访问路由
        name: '路由子组件1', // 路由名称要保证唯一性,不然会有问题,就是无法访问对应的同名的路由路径
        component: () => import('../views/ChildrenOne.vue')
      },
      {
        path: 'childrenTwo',
        name: '路由子组件2',
        component: () => import('../views/ChildrenTow.vue')
      },
      {
        path: 'childrenThree',
        name: '路由子组件3',
        component: () => import('../views/ChildrenThree.vue')
      }
    ]
  },
  {
    path: '/home',
    name: 'Home.vue路由组件',
    component: () => import('../views/Home.vue'),
    redirect: '/home/HomeChildrenOne',
    children: [
      {
        path: 'HomeChildrenOne',
        name: 'Home.vue的路由子组件11111',
        component: () => import('../views/HomeChildrenOne.vue')
      },
      {
        path: 'HomeChildrenTwo',
        name: 'Home.vue的路由子组件22222',
        component: () => import('../views/HomeChildrenTwo.vue')
      }
    ]
  }
  ,
  {
    path: '/404',
    name: '404',
    component: () => import('../views/404.vue')
  },
  /**
   * 如果路由没有,就跳转到404页面,路由匹配规则
   */
  // {
  //   path: '/:pathMatcher(.*)*',
  //   name: 'remaining',
  //   redirect: '/404'
  // },
]

const router = createRouter({
  history: createWebHashHistory(),
  routes: clientRoutes
})

export default router

路由信息表如下所示
在这里插入图片描述

结果如下所示:
在这里插入图片描述
总结如下:如果是使用router.push()不同级别的路由相互跳转,记得把完整路径跳转,这样可以在一定程度上避免问题。
上面的GIF中,在HomeChildrenOne中的router.pusr(‘/index’),没有成功,然后在ChildrenThree.vue中router.push(‘/home’)成功的原因是,一个是正确的路由重定向路径,一个是错误的路由重定向路径。因为这里的路由配置是
在这里插入图片描述
如果在路由配置中改成
在这里插入图片描述
在HomeChildrenOne中的router.pusr(‘/index’),成功,然后在ChildrenThree.vue中router.push(‘/home’)成功,的原因是,两个是正确的路由重定向路径。所以结果如下所示
在这里插入图片描述

路由的router.push()总结

总结如下:在vue-router的编程式导航中,router.push(“/XXX”)以斜杠开头的是,跳转到从/(斜杠)根路径,开始一个层级一个层级路由找下去并展示。router.push(“XXX”),没有从斜杆开始,跳转到的路由是当前路由的子路由,或者是当前路由的同级路由。所以这里有两种写跳转路由是分两种情况。一种是router.push(“/XXX”),另外一种是router.push(“XXX”)。这里从父路由跳转到子路由,后者跳转到同级路由亦可以使用router.push(“/XXX/XXX”)这种形式写完整路径,也可以使用router.push(“XXX”)这种相对路径,如果是使用router.push()不同级别的路由相互跳转,记得把完整路径跳转,这样可以在一定程度上避免问题。这里建议写完整的路径,可以一眼看出路由的关系,方便阅读,至少跟容易知道跳转到的是那个路由的内容。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

路由携带参数

这里有官网管编程式导航 | Vue Router (vuejs.org),的路由参数内容。
在这里插入图片描述
在我做项目的时候,因为业务的需要,需要将某个路由组件中某个数据的ID传入到另外一个页面中去,而这两个路由是同级的路由,所以这里我想到了使用路由传参的形式,将ID放到路由参数中,然后再跳转到那个路由的页面中获取。又因为,这里有路由匹配规则的,官网用法,路由的匹配语法 | Vue Router (vuejs.org)
在这里插入图片描述
像这里的用法,我觉得比较适合的是点击某一个ID,然后跳转到这个ID的详情页面。
注意,这里用到的代码是上面的代码
然而我这里需要的是,路由的路径可以传入ID,也可以不传ID。都可以正常访问对应的路由页面。如下GIF所示
在这里插入图片描述
我这里在项目中,是点击左侧菜单栏的时候,路由路径没有任何参数。但是从另外一个页面点击某一项表格数据的时候,将这个数据的ID传给需要跳转的页面,然后跳转到的那个页面根据拿到的ID通过接口查询数据。总之是,连个页面的数据,在数据库中的表现有一对一的关系,至少两个表格的内容不一样,在一个表中保存了另外一个表的ID。

修改HomeChildrenOne.vue的代码
<template>
  <div class="home-children-one">
    <h2>这个是路由Home.vue的子组件1111111111111,HomeChildrenOne.vue</h2>
    <hr>
    <!-- <div style="border: 2px rgb(72, 23, 247) solid; height: 50px;  margin: 10px; padding: 10px;" @click="goIndex_3">
      子路由组件HomeChildrenOne.vue跳转到父路由Home.vue同级的index.vue的内容, 子路由HomeChildrenOne.vue,使用router.push('/index')跳转到与Home.vue的同级路由idnex.vue界面,
      因为/index子路由配置中设置了重定向到index.vue的子路由组件ChildrenOne.vue,失败
    </div>
    <div style="border: 2px rgb(72, 23, 247) solid; height: 50px;  margin: 10px; padding: 10px;" @click="go404page_3">
      子路由组件HomeChildrenOne.vue跳转到父路由Home.vue同级的404.vue的内容, 子路由HomeChildrenOne.vue,使用router.push('/404')跳转到与Home.vue的同级路由404.vue界面,成功
    </div>
    <div style="border: 2px rgb(72, 23, 247) solid; height: 50px;  margin: 10px; padding: 10px;" @click="goHomeChldrenOne_4">
      子路由组件HomeChildrenOne.vue跳转到父路由Home.vue同级的index.vue的子组件ChildrenOne.vue的内容, 子路由HomeChildrenOne.vue,使用router.push('/index/childrenOne')直接跳转到与Home.vue的同级路
      由idnex.vue的子组件,ChildrenOne.vue,成功
    </div>
    <div style="border: 2px rgb(72, 23, 247) solid; height: 50px;  margin: 10px; padding: 10px;" @click="goHomeChldrenTwo_4">
      子路由组件HomeChildrenOne.vue跳转到父路由Home.vue同级的index.vue的子组件ChildrenTow.vue的内容, 子路由HomeChildrenOne.vue,使用router.push('/index/childrenTwo')直接跳转到与Home.vue的同级路
      由idnex.vue的子组件,ChildrenTow.vue,成功
    </div>
    <div style="border: 2px rgb(72, 23, 247) solid; height: 50px;  margin: 10px; padding: 10px;" @click="goHomeChldrenThree_4">
      子路由组件HomeChildrenOne.vue跳转到父路由Home.vue同级的index.vue的子组件ChildrenThree.vue的内容, 子路由HomeChildrenOne.vue,使用router.push('/index/childrenThree')直接跳转到与Home.vue的同级路
      由idnex.vue的子组件,ChildrenThree.vue,成功
    </div>
    <div>
      总结:(先看GIF图再理解这一句)如果是不同级别的路由跳转,使用router.push()的时候,记得写完整的路径,特别是有子路由路径的情况下,
      记得是/父路由/子路由这样的完整路由路径,具体看上面的几种情况(先看后面的GIF图)就知道了
    </div> -->
    <div style="height: 50px; margin: 8px; line-height: 50px; background-color: pink;" @click="goHomeChildrenTwo_1">
      跳转到路由HomeChildrenTWo页面router.push('/home/HomeChildrenTwo')不携带参数
    </div>
    <div style="height: 50px; margin: 8px; line-height: 50px; background-color: rgb(9, 196, 243);" @click="goHomeChildrenTwo_2">
      跳转到路由HomeChildrenTWo页面router.push('/home/HomeChildrenTwo?projectId=8')携带参数
    </div>
  </div>
</template>

<script setup lang="ts">
import {ref} from 'vue'
// 路由编程式导航
import { useRouter } from 'vue-router';
const router = useRouter()

const goHomeChildrenTwo_1 = () => {
  router.push('/home/HomeChildrenTwo')
}

const id = ref(8)
const goHomeChildrenTwo_2 = () => {
  // router.push('/home/HomeChildrenTwo?projectId=' + id.value)
  router.push(`/home/HomeChildrenTwo?projectId=${id.value}`)
}

/**
const goIndex_3 = () => {
  // 这里失败了,原因还在试着找着中,如果有懂的大佬,可不可以跟我说一下。
  router.push("/index")
}

const go404page_3 = () => {
  // 只要威为什么router.push("404")不行,
  // 具体看上面修改的childrenThree.vue关于这里的解释
 router.push("/404")
}

const goHomeChldrenOne_4 = () => {
   // 只要威为什么router.push("index/childrenOne")不行,
  // 具体看上面修改的childrenThree.vue关于这里的解释
  router.push("/index/childrenOne")
}

const goHomeChldrenTwo_4 = () => {
  // 只要威为什么router.push("index/childrenTwo")不行,
  // 具体看上面修改的childrenThree.vue关于这里的解释
  router.push("/index/childrenTwo")
}

const goHomeChldrenThree_4 = () => {
  // 只要威为什么router.push("index/childrenThree")不行,
  // 具体看上面修改的childrenThree.vue关于这里的解释
  router.push("/index/childrenThree")
}

 */

</script>

<style scoped>
.home-children-one {
  background-color: rgb(197, 97, 255);
  margin: 10px;
}
</style>
修改HomeChildrenTwo.vue的代码
<template>
  <div class="home-children-two">
    <h2>这个是路由Home.vue的子组件222222222,HomeChildrenTwo.vue</h2>
    <div style="height: 50px; background-color: orange; line-height: 50px;" @click="goHomeChildrenOne">
      跳转到HomeChildrenOne组件router.push('/home/HomeChildrenOne')
    </div>
    <div  style="height: 50px; line-height: 50px;" >
      路由路径path是:{{ path }}
    </div>
    <div  style="height: 50px; line-height: 50px;" >
      路由路径fullPath是:{{ fullPath }}
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
// 路由编程式导航
import { useRouter } from 'vue-router';
const router = useRouter()

const path = ref('')
const fullPath = ref('')

const goHomeChildrenOne = () => {
  router.push('/home/HomeChildrenOne')
}

onMounted(() => {
  console.log(router)
})
</script>

<style scoped>
.home-children-two {
  background-color: bisque;
  margin: 10px;
}
</style>

这里有关于官网路由的接口说明,接口:Router | Vue Router (vuejs.org) 可以在这里看一下,也可以直接看我的GIF图,可以从直接打印的路由对象中,看出路由对象包括的内容。具体看截图和GIF图
在这里插入图片描述
在这里插入图片描述
其他代码不变,通过console.log(router)可以看出router的路由对象具有的内容,从上面的截图中可以看出,router是一个vue中使用ref封装的对象

再次修改HomeChildrenTwo.vue的代码

<template>
  <div class="home-children-two">
    <h2>这个是路由Home.vue的子组件222222222,HomeChildrenTwo.vue</h2>
    <div style="height: 50px; background-color: orange; line-height: 50px;" @click="goHomeChildrenOne">
      跳转到HomeChildrenOne组件router.push('/home/HomeChildrenOne')
    </div>
    <div style="height: 50px; line-height: 50px;">
      路由路径path是:{{ path }}
    </div>
    <div style="height: 50px; line-height: 50px;">
      路由路径fullPath是:{{ fullPath }}
    </div>
    <!-- <div v-if="projectId !== ''" style="height: 50px; line-height: 50px;" > -->
    <div v-if="projectId !== ''" style="height: 50px; line-height: 50px;">
      ID是:{{ projectId }}
    </div>
    <div v-else style="height: 50px; line-height: 50px;">
      路由暂时:没有传入参数
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
// 路由编程式导航
import { useRouter } from 'vue-router';
const router = useRouter()

const path = ref('')
const fullPath = ref('')
const projectId = ref('')

const goHomeChildrenOne = () => {
  router.push('/home/HomeChildrenOne')
}

onMounted(() => {
  console.log(router)
  // router是一个ref对象,从console.log(router)可以看出,所以是router.currentRoute.value
  path.value = router.currentRoute.value.path
  fullPath.value = router.currentRoute.value.fullPath
  // debugger
  // if(fullPath.value.lastIndexOf("=") !== -1) {
  if (fullPath.value.lastIndexOf("=") != -1) {
    //  const id = fullPath.value.substring(fullPath.value.lastIndexOf("=")).replace("=",'')
    //  const projectIdNumber = JSON.parse(id)
    projectId.value = fullPath.value.substring(fullPath.value.lastIndexOf("=")).replace("=", '')
  }
})
</script>

<style scoped>
.home-children-two {
  background-color: bisque;
  margin: 10px;
}
</style>

结果如下所示:
在这里插入图片描述

动态路由,后续再写上,这里有动态路由 | Vue Router (vuejs.org)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值