Vue 路由传参的三种方式(三)

Vue 路由传参的三种方式

在 Vue Router 中,路由组件之间传递参数主要有三种方式:query 参数、params 参数和 props 传参。下面分别介绍。

一、query 传参

query 参数会在 URL 中以 ?key=value 的形式出现,例如 /news/rolonews?id=1&skill=后仰跳投。它类似于 GET 请求的查询字符串。

1.1 基本路由配置(index.ts)

typescript 复制代码
{
  path: '/news',
  name: 'News',
  component: News,
  children: [
    {
      path: 'rolonews',        // 注意:这里没有占位符,参数通过 query 传递
      name: 'Rolonews',
      component: Rolonews,
    },
  ],
},

1.2 传递 query 参数的方式

方式一:字符串拼接(直接写在路径中)
复制代码
<RouterLink to="/news/rolonews?a=666&b=777">{{ rolo.skill }}</RouterLink>

Rolenews.vue 组件中接收参数:

复制代码
<template>
  <p>牛逼666</p>
</template>
<script setup lang="ts">
import { useRoute } from 'vue-router';
const route = useRoute();
console.log(route);   // 打印 route 对象,可以看到 query 属性
</script>

得到:

方式二:模板字符串拼接
复制代码
<RouterLink :to="`/news/rolonews?id=${rolo.id}&skill=${rolo.skill}`">
  {{ rolo.rolo }}
</RouterLink>

更好的理解:使用动态数据构造路径。

完整的父组件 News.vue(使用 query 传参)
复制代码
<template>
  <div class="news">
    <ul>
      <li v-for="rolo in roloList" :key="rolo.id">
        <RouterLink :to="`/news/rolonews?id=${rolo.id}&skill=${rolo.skill}`">
          {{ rolo.rolo }}
        </RouterLink>
      </li>
    </ul>
    <div class="news-content">
      <RouterView></RouterView>
    </div>
  </div>
</template>

<script setup lang="ts" name="News">
import { reactive } from 'vue'
import { RouterView } from 'vue-router'
const roloList = reactive([
  { id: 1, rolo: '老大', skill: '后仰跳投' },
  { id: 2, rolo: '库里', skill: 'logo三分' },
  { id: 3, rolo: '詹姆斯', skill: '罚球线暴扣' },
])
</script>

<style scoped>
/* 样式略 */
</style>
子组件 Rolenews.vue 接收 query 参数
复制代码
<template>
  <p>
    编号:{{ route.query.id }}<br />
    技能:{{ route.query.skill }}
  </p>
</template>
<script setup lang="ts">
import { useRoute } from 'vue-router'
const route = useRoute()
console.log(route)
</script>

就可以拿到数据了

方式三:对象写法(推荐,更清晰)
复制代码
<RouterLink 
  :to="{ path: '/news/rolenews', query: { id: role.id, skill: role.skill } }">
  {{ role.role }}
</RouterLink>

接收时可以使用 toRefs 解构:

复制代码
<template>
  <p>
    编号:{{ query.id }}<br />
    技能:{{ query.skill }}
  </p>
</template>
<script setup lang="ts">
import { useRoute } from 'vue-router'
import { toRefs } from 'vue'
const route = useRoute()
const { query } = toRefs(route)
</script>

注意query 参数刷新页面后依然存在(因为它保存在 URL 中),且不需要在路由配置中预先定义。

二、params 传参

params 参数是 URL 路径的一部分,例如 /news/rolenews/1/后仰跳投。需要在路由配置中预定义占位符。

2.1 传递 params 参数

方式一:模板字符串拼接(路径带占位符)
复制代码
<RouterLink :to="`/news/rolenews/${role.id}/${role.skill}`">
  {{ role.role }}
</RouterLink>
第二步:修改路由配置,添加占位符
复制代码
{
  path: '/news',
  name: 'News',
  component: News,
  children: [
    {
      path: 'rolenews/:id/:skill',    // 冒号表示参数占位符
      name: 'Rolenews',
      component: Rolenews,
    },
  ],
},
第三步:在子组件中通过 route.params 接收
复制代码
<template>
  <p>
    编号:{{ route.params.id }}<br />
    技能:{{ route.params.skill }}
  </p>
</template>
<script setup lang="ts">
import { useRoute } from 'vue-router'
const route = useRoute()
console.log(route.params)
</script>

拿到数据:

方式二:对象写法(必须使用 name,不能使用 path
复制代码
<RouterLink :to="{ name: 'Rolenews', params: { id: role.id, skill: role.skill } }">
  {{ role.role }}
</RouterLink>

2.2 可选参数

如果想要某个参数可传可不传,在占位符后加问号 ?

复制代码
{
  path: 'rolenews/:id?/:skill',   // id 可选
  name: 'Rolenews',
  component: Rolenews,
}

此时可以只传 skill

复制代码
<RouterLink :to="{ name: 'Rolenews', params: { skill: role.skill } }">
  {{ role.role }}
</RouterLink>

重要备注

  1. 传递 params 参数时,若使用 to 的对象写法,必须使用 name ,不能用 path
  2. 传递 params 参数时,需要提前在路由规则的 path 中用 :paramName 占位。

三、props 传参

props 传参可以让路由组件直接通过 props 接收参数,而不必在组件内部使用 route.paramsroute.query,代码更简洁。

3.1 props 的布尔值写法

作用:将路由收到的所有 params 参数作为 props 传递给路由组件。

第一步 :在路由配置中设置 props: true

复制代码
{
  path: '/news',
  name: 'News',
  component: News,
  children: [
    {
      path: 'rolenews/:id?/:skill',
      name: 'Rolenews',
      component: Rolenews,
      props: true,      // 布尔值写法
    },
  ],
},

此时,Rolenews 组件会自动接收 idskill 作为 props。

第二步 :在组件中通过 defineProps 声明接收

复制代码
<template>
  <p>
    编号:{{ id }}<br />
    技能:{{ skill }}
  </p>
</template>
<script setup lang="ts">
defineProps(['id', 'skill'])
</script>

注意props: true 只对 params 参数有效,不能处理 query 参数。

3.2 props 的函数写法

作用:可以自定义返回的 props 对象,灵活性更高。通常用于处理 query 或混合参数。

复制代码
{
  path: '/news',
  name: 'News',
  component: News,
  children: [
    {
      path: 'rolenews/:id?/:skill',
      name: 'Rolenews',
      component: Rolenews,
      props(route) {
        console.log(route)   // 打印路由信息
        return route.params  // 返回 params 参数
      }
    },
  ],
},

控制台打印:出路由的信息

也可以写成箭头函数:

复制代码
props: (route) => route.params

如果需要处理 query 参数:

复制代码
props: (route) => ({ id: route.query.id, skill: route.query.skill })

这样在组件中依然可以通过 defineProps 接收。

3.3 props 的对象写法

作用:直接写死一组键值对作为 props 传递给组件。很少使用,因为值是静态写死的,无法动态传递。

复制代码
{
  path: 'rolenews/:id?/:skill',
  name: 'Rolenews',
  component: Rolenews,
  props: {
    id: '固定id',
    skill: '固定技能',
  },
},

总结对比

传参方式 URL 表现 路由配置要求 接收方式 刷新后参数是否保留
query /path?key=value 不需要占位符 route.query.key 是(在URL中)
params /path/value 需要 :key 占位符 route.params.key 是(在URL中)
props 无特殊表现 配置 props: true 或函数 defineProps 直接接收 取决于底层参数

建议

  • 普通查询参数(如搜索条件、分页)使用 query
  • 资源标识(如 ID、用户名)使用 params
  • 为了组件解耦和可读性,推荐使用 props 传参方式(特别是函数写法)。
相关推荐
如果超人不会飞1 小时前
TinyVue Checkbox复选框组件使用指南
前端·vue.js
如果超人不会飞2 小时前
TinyVue Radio单选框组件使用指南
vue.js
鲁班小子2 小时前
Vite resolve.dedupe 使用教程
vue.js·vite
如果超人不会飞2 小时前
TinyVue Input输入框组件使用指南
vue.js
如果超人不会飞2 小时前
TinyVue Pager分页组件使用指南
前端·vue.js
大刚测试开发实战2 小时前
TestHub重磅更新!AI用例生成增加流式输出、Markdown文档上传、模型配置检测、AI评审开关控制...
vue.js·后端·github
可别3903 小时前
Vue 极简实现语音实时转写(录音转文字,低网络依赖、开箱即用)
前端·javascript·vue.js
阿猫的故乡3 小时前
Vue插槽从入门到项目实战:默认插槽、具名插槽、作用域插槽,一次讲明白
前端·javascript·vue.js
向日的葵0063 小时前
vue3路由的replace属性(四)
前端·javascript·vue.js·vue路由