最新版vue3+TypeScript开发入门到实战教程之路由详解二

上节讲解到路由的基础用法,路由的内容还有很多,这节开始路由嵌套与传参。

1、路由的嵌套

路由嵌套,简单言之,由主页点击进入一个模块,在模块中又可点击进入子模块。如在主页进入Fish组件,在Fish组件中,进入FishDetail详细内容。路由的四个基本要素

  • 路由管理器,统一管理路由
  • 路由信息,记录组件与路由的对应关系
  • 跳转标签与跳转方法,用于跳转指定路由
  • 路由跳转后,指定组件显示位置

创建一个简单实例实现嵌套路由

  • 创建主页,主页含有标题、导航、路由跳转子页面显示位置
  • 创建三个子页面,Fish、Cat、Bird
  • 创建FishDetail组件
  • 创建路由及路由信息
  • 创建Fish子路由

路由源码

复制代码
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组件源码

复制代码
<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组件源码

复制代码
<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组件源码

复制代码
<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组件源码

    <template>
    • <router-link :to="{path:'/fish/detail',query:{id:item.id,name:item.name,price:item.price}}">{{ item.name }}</router-link>
    <RouterView/>
    </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组件源码

复制代码
<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,将失去响应式。

复制代码
<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函数,转换为响应式。如下

复制代码
let { query } = toRefs(useRoute());

3、路由的params传参

params是通过url接收参数,格式类似:fish/detail/02/草鱼/150,可通过useRoute函数获取params参数。与query不同,params必须在路由中设置对应的参数。还是以Fish与FishDetail为例,重新修改代码:

路由代码

复制代码
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组件代码

复制代码
<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组件代码

复制代码
<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,可以通过下面代码跳转:

    <template>
    • <router-link :to="`/fish/detail/${item.id}/${item.name}`">{{item.name }}</router-link>
    <RouterView/>
    </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后面就是字符串拼接。

相关推荐
嵌入式小能手2 小时前
飞凌嵌入式ElfBoard-环境变量之添加修改环境变量setenv
服务器·前端·javascript
polarisya2 小时前
vue组件二次封装
前端·javascript·vue.js
郭泽斌之心2 小时前
Live2D工程对接Fay数字人框架
前端·经验分享·fay数字人
前端搬砖人沐兮2 小时前
被忽视的宝藏:深入解读 createRangeFromPoint 的前世今生与实战技巧
前端
kyriewen2 小时前
手写 Promise:从“我会用”到“我会造”
前端·javascript·面试
Synmbrf2 小时前
基于micro-app的微前端落地实践
javascript·vue.js
wuhen_n2 小时前
案例分析:大屏可视化项目的卡顿排查与解决
前端·javascript·vue.js
比尔盖茨的大脑2 小时前
为了学习 AI Agent,我做了一个 AI 阅读器(已开源)
前端·人工智能
始持2 小时前
第十九讲 深度布局原理与优化
前端·flutter