上节讲解到路由的基础用法,路由的内容还有很多,这节开始路由嵌套与传参。
1、路由的嵌套
路由嵌套,简单言之,由主页点击进入一个模块,在模块中又可点击进入子模块。如在主页进入Fish组件,在Fish组件中,进入FishDetail详细内容。路由的四个基本要素
- 路由管理器,统一管理路由
- 路由信息,记录组件与路由的对应关系
- 跳转标签与跳转方法,用于跳转指定路由
- 路由跳转后,指定组件显示位置
创建一个简单实例实现嵌套路由
- 创建主页,主页含有标题、导航、路由跳转子页面显示位置
- 创建三个子页面,Fish、Cat、Bird
- 创建FishDetail组件
- 创建路由及路由信息
- 创建Fish子路由
路由源码
javascript
import { createRouter, createWebHistory } from 'vue-router'
import Fish from '@/view/Fish.vue'
import Cat from '@/view/Cat.vue'
import Bird from '@/view/Bird.vue'
import FishDetial from '@/view/FishDetial.vue'
console.log(createRouter)
const routes = [
{
name: 'fish',
path: '/fish',
component: Fish,
children: [
{
name: 'fishdetail',
path: 'detail',
component:FishDetial
}
]
},
{ path: '/cat', component: Cat },
{ path: '/bird', component: Bird }, // 动态路由
]
const router = createRouter({
history: createWebHistory(),
routes: routes,
})
export default router
App组件源码
xml
<template>
<div class="app">
<router-link :to="{name:'fish'}">跳转到鱼</router-link>
<router-link to="/cat">跳转到猫</router-link>
<router-link to="/bird">跳转到鸟</router-link>
<div class="content">
<router-view></router-view>
</div>
</div>
</template>
<script setup lang="ts">
</script>
Fish组件源码
xml
<template>
<div>
<ul>
<li v-for="item in fishs" :key="item.id">
<router-link :to="{path:'/fish/detail'}">{{ item.name }}</router-link>
</li>
</ul>
<RouterView/>
</div>
</template>
<script setup lang="ts">
import { reactive } from 'vue';
let fishs = reactive([
{id:'01',name:'鲫鱼',price:100},
{id:'02',name:'草鱼',price:150},
{id:'03',name:'鲈鱼',price:200},
])
</script>
FishDetal组件源码
xml
<template>
<div>
<h3>鱼类:鲫鱼</h3>
<h3>id:01</h3>
<h3>价格:100</h3>
</div>
</template>
<script setup lang="ts">
</script>
运行查看效果: 
2、路由的query传参
当我们点击路由进入子页面时,希望把数据传给子页面。路由的传参,有两种方式。
- query传参,url格式类似/fish/detail?id=01&name=鲫鱼&price=100
- parmas传参,url格式类似/fish/detail/02/草鱼 query传参通过url地址传递给子组件,子组件通过useRoute函数接收query参数。传参实例详见Fish和FishDetail组件. Fish组件源码
xml
<template>
<div>
<ul>
<li v-for="item in fishs" :key="item.id">
<router-link
:to="{path:'/fish/detail',query:{id:item.id,name:item.name,price:item.price}}">{{ item.name }}</router-link>
</li>
</ul>
<RouterView/>
</div>
</template>
<script setup lang="ts">
import { reactive } from 'vue';
let fishs = reactive([
{id:'01',name:'鲫鱼',price:100},
{id:'02',name:'草鱼',price:150},
{id:'03',name:'鲈鱼',price:200},
])
</script>
FishDetail组件源码
xml
<template>
<div>
<h3>鱼类:{{ route.query.name }}</h3>
<h3>id:{{ route.query.id }}</h3>
<h3>价格:{{ route.query.price }}</h3>
</div>
</template>
<script setup lang="ts">
import { useRoute } from 'vue-router';
let route=useRoute();
</script>
运行实例查看效果
注意在FishDetail,获取到的route,是响应式。若我们从route解析获取query,将失去响应式。
xml
<template>
<div>
<h3>鱼类:{{ query.name }}</h3>
<h3>id:{{ query.id }}</h3>
<h3>价格:{{ query.price }}</h3>
</div>
</template>
<script setup lang="ts">
import { useRoute } from 'vue-router';
let { query } = useRoute();
</script>
如图:
注意url地址的变化,若要query具有相应式,可通过toRefs函数,转换为响应式。如下
scss
let { query } = toRefs(useRoute());
3、路由的params传参
params是通过url接收参数,格式类似:fish/detail/02/草鱼/150,可通过useRoute函数获取params参数。与query不同,params必须在路由中设置对应的参数。还是以Fish与FishDetail为例,重新修改代码: 路由代码
javascript
import { createRouter, createWebHistory } from 'vue-router'
import Fish from '@/view/Fish.vue'
import Cat from '@/view/Cat.vue'
import Bird from '@/view/Bird.vue'
import FishDetial from '@/view/FishDetial.vue'
console.log(createRouter)
const routes = [
{
name: 'fish',
path: '/fish',
component: Fish,
children: [
{
name: 'fishdetail',
path: 'detail/:id/:name/:price?',
component:FishDetial
}
]
},
{ path: '/cat', component: Cat },
{ path: '/bird', component: Bird }, // 动态路由
]
const router = createRouter({
history: createWebHistory(),
routes: routes,
})
export default router
Fish组件代码
xml
<template>
<div>
<ul>
<li v-for="item in fishs" :key="item.id">
<router-link
:to="{name:'fishdetail',params:{id:item.id,name:item.name,price:item.price}}">{{ item.name }}</router-link>
</li>
</ul>
<RouterView/>
</div>
</template>
<script setup lang="ts">
import { reactive } from 'vue';
let fishs = reactive([
{id:'01',name:'鲫鱼',price:100},
{id:'02',name:'草鱼',price:150},
{id:'03',name:'鲈鱼',price:200},
])
</script>
FishDetail组件代码
xml
<template>
<div>
<h3>鱼类:{{ route.params.name }}</h3>
<h3>id:{{ route.params.id }}</h3>
<h3>价格:{{ route.params.price }}</h3>
</div>
</template>
<script setup lang="ts">
import { useRoute } from 'vue-router';
let route = useRoute();
</script>
运行实例查看params
注意两点:
- router-link使用跳转路由时,用的是name,而不能用path
- router-link传递参数不能数组
- 在路由配置中price后有问号,代表这个参数可不用传递 若不使用name,可以通过下面代码跳转:
xml
<template>
<div>
<ul>
<li v-for="item in fishs" :key="item.id">
<router-link :to="`/fish/detail/${item.id}/${item.name}`">{{item.name }}</router-link>
</li>
</ul>
<RouterView/>
</div>
</template>
<script setup lang="ts">
import { reactive } from 'vue';
let fishs = reactive([
{id:'01',name:'鲫鱼',price:100},
{id:'02',name:'草鱼',price:150},
{id:'03',name:'鲈鱼',price:200},
])
</script>
其实to后面就是字符串拼接。