这里说明一下,这里我得出了两个结论,关于编程式导航的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)