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 传参方式(特别是函数写法)。
相关推荐
用户2136610035727 小时前
VueRouter进阶-动态路由与嵌套路由
前端·vue.js
暴走的小呆1 天前
Vue 2 中 Object 的变化侦测:从 getter/setter 到 Dep、Watcher、Observer
vue.js
英勇无比的消炎药1 天前
TinyVue v-auto-tip: 文本超长自动提示的优雅方案
vue.js
时光足迹1 天前
腾讯云 TRTC UniApp SDK 从入门到上线
前端·vue.js·uni-app
时光足迹1 天前
uni-app 里把加密视频嵌入页面播放?我分析了 4 种方案,只有 1 种接近完美
前端·vue.js·uni-app
时光足迹1 天前
JPush UniApp UTS 插件完全参考手册:API、事件与厂商通道一网打尽
vue.js·ios·uni-app
时光足迹1 天前
极光推送全攻略(下):uni-app 代码实现与 iOS 排查实战
vue.js·ios·uni-app
疯狂的魔鬼1 天前
一个"懂分寸"的文本省略组件是怎样炼成的
前端·vue.js·设计
裕波1 天前
AI 正在重写应用开发。Vue 与 Vite,给出新的答案。
javascript·vue.js
妙码生花1 天前
现代前端的极致性能 icon 加载方案(死磕成功版)
前端·vue.js·typescript