第四章-路由传参

168 阅读3分钟

路由传参

有些时候我们希望在跳转到另一个页面的时候,携带一些参数过去,比如商品介绍页跳转到商品详情页,希望将商品的id携带过去到商品详情页用来查询对应商品id的详情信息。

路由携带参数通常被称作路由传参,路由传参常用的方式有如下3种:路由查询参数(query)、路由路径参数(params)、动态路由参数(params)

路由传参一般在编程式导航中用的比较频繁,单单是进行路由跳转,不携带参数的话我们知道直接通过router.push(path)/router.replace(path)就可以实现。

携带参数进行路由跳转的话,就需要给router.push(object)/router.replace(object)传入一个对象参数。

  • 如果是通过query传参,那么这个对象参数是这样的:{ path: '/detail', query: {...} }

  • 获取query参数通过route.query进行获取。

  • 如果是通过params传参,那么这个对象参数是这样的:{ path: '/detail', params: {...} }

  • 获取params参数通过route.params进行获取。

我们可以看到,不管是query传参还是params传参,它们两个的值都是一个对象,而这个对象中的属性,就是你需要携带到另一个也页面的参数。

前期准备

data.json:

{
    "data": [
        {
            "id": 1,
            "name": "丝袜奶茶",
            "price": 28
        },
        {
            "id": 2,
            "name": "芋泥波波",
            "price": 30
        },
        {
            "id": 3,
            "name": "秋茶",
            "price": 50
        }
    ]
}

router/index.ts:

import { createRouter, createWebHistory } from 'vue-router'

const routes = [
  {
    path: '/', // router-link组件默认展示path为'/'对应的组件
    component: () => import('@/views/list.vue'),
  },
  {
    path: '/detail', // router-link组件默认展示path为'/'对应的组件
    name: 'detail',
    component: () => import('@/views/detail.vue'),
  },
]

/** 创建vue-router实例对象 */
const router = createRouter({
  history: createWebHistory(),
  routes,
})

export default router

App.vue:

<template>
  <router-view></router-view>
</template>

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

<style lang="scss" scoped>
a {
  margin: 0 10px;
}
</style>

query传参

示例:

商品列表页-list.vue:

<template>
  <div>
    <table border cellspacing="0">
      <thead>
        <tr>
          <th>商品id</th>
          <th>商品名称</th>
          <th>商品价格</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="product in data" :key="product.id">
          <td>{{ product.id }}</td>
          <td>{{ product.name }}</td>
          <td>{{ product.price }}</td>
          <td><button @click="toDetail(product)">详情</button></td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script setup lang="ts">
import { useRouter } from 'vue-router'
import { data } from '@/assets/data.json'

const router = useRouter()

interface Product extends Record<string, any> {
  id: number
  name: string
  price: number
}

const toDetail = (product: Product) => {
  router.push({
    path: '/detail',
    query: product,
  })
}
</script>

<style scoped>
table {
  border-collapse: collapse;
}
</style>

商品详情页-detail:

<template>
  <div>
    <div>
      <span>商品名称:</span>
      <span>{{ name }}</span>
    </div>
    <div>
      <span>商品价格:</span>
      <span>{{ price }}</span>
    </div>
    <div>
      <span>商品id:</span>
      <span>{{ id }}</span>
    </div>
  </div>
</template>

<script setup lang="ts">
import { useRoute } from 'vue-router'
const route = useRoute()

const { id, name, price } = route.query
</script>

<style lang="scss" scoped></style>

router4.gif

可以发现,使用query进行传参,参数会暴露在url地址栏中。

params动态路由传参

使用params传参需要注意一点的是,不能通过path跳转,必须使用name进行跳转,否则获取不到参数。

router/index.ts:

{
    path: '/detail/:id/:name/:price', // router-link组件默认展示path为'/'对应的组件
    name: 'detail',
    component: () => import('@/views/detail.vue'),
},

在路径中添加携带的参数: path: '/detail/:id/:name/:price'

list.vue

const toDetail = (product: Product) => {
  router.push({
    name: 'detail',
    params: product,
  })
}

path改为使用name

detail.vue

const { id, name, price } = route.params

route.query改为使用route.params获取传入的参数。

  • 通过上面的例子我们发现,使用params动态路由传参的方式,我们需要提前向目标跳转路由的path中声明添加需要携带的参数,声明的方式为: path: '路径/:携带的参数名'

  • 这样声明的params参数是必传的。也就是说跳转到目标路由的时候没有传入该参数,那么就会报错。

  • 如果需要非必传的路径参数,可以在参数名称的后面加一个 ? 表示该路径参数为非必传参数,类似这样:path: '路径/:携带的参数名?'

  • 注意:我们在传参的时候,切记传入的参数名称一定要与路径中提前声明的参数名称保持一致。

  • 可以发现,使用params进行传参,参数同样会暴露在url地址栏中,只不过query参数是跟在 ?, 而params路径参数不是跟在 ? 后面的。