在跳转页面时,可以透过路由物件里 params 或 query 来传递资料,也可以使用各种不同模式的 Route props 来传递资料。前者需要依赖 URL ,例如 params 需要依靠动态路由,即是/example/:id
来完成。query 则需要在 URL 里写 /example?id=123
这样的格式来传送。
相反,各种模式的 route props 就比较灵活,不用依赖 URL,而且不用透过 route 物件来取得资料像是 this.$route.params
这样的写法就能省下。因为我们可以直接在页面元件设定 props,直接用意 props 来取得经由路由传递过来的资料。
以下会再作详细解说。
但在进入主题之前,先简单重温在 Vue 有什麽方法实现跨页面资料:
注意,目前讨论的情况是跨页面传资料,不是父子元件之间传资料,因此 props/emit
以及 provide/inject
方法就不适用於此情况。
回到重点,此文章会集中说明 route props 的方法。
先说明最简单的 params 和 query 用法。这也是新手刚学 Vue 时最常用到的方法。
先说明 params,做法是在路由设定参数:
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User }
]
})
当输入 /user/111
後,可以在 route object 里取得 params:
console.log(this.$route.params.id)
// 111
第二种是 query,路由直接设定为 /user
即可。但 URL 必须使用这格式:/user?id=111
。
同样地,使用 route object 取得由以上路由传来的 query,结果会回传一个物件:
console.log(this.$route.query)
// {id: '111'}
$router.push
时,只能择一填写 params
或 path
属性另外提醒,当使用 $router.push()
的方法来跳转页面时,要注意:
正确写法:
const id = '123'
this.$router.push({
name: 'user', // 要事先在 router 那边命名你的元件
params: { id }
})
或者
this.$router.push({ path: `/user/${id}` })
错误写法:
this.$router.push({
path: '/user',
params: { id }
})
然而,传 query 的话就没有此限制:
this.$router.push({
path: '/user',
query: { id }
})
query 所传送的参数会显示在 URL 里,但 params 则不一定。像以下写法:
const id = "111";
this.$router.push({
name: 'User', // 即是 /user
params: { id }
});
结果会跳转到 /user
此 URL,在 URL 里不会显示 id 的值。反之,使用 query 的话,参数一定会显示在 URL 里。
很重要一点,重刷页面时,如果使用 query 传参,资料仍然会存在。反之,params 传参的话,资料就会消失。
说到重点了,如果我要跨页面传多笔资料,或者是物件资料。如何使用路由传参的方法来完成?
如果要传送多个值,使用 params
和 query
也可。
前者的话,只要在$router.push()
里的 params
物件里再塞资料就可以:
this.$router.push({
name: 'User',
params: {
id: 111, // 注意,传送後会转为字串
name: 'Alysa'
}
});
query 的做法:
this.$router.push("/user?id=111&name=Alysa")
或
this.$router.push({
path: '/user',
query: {
id: 111, // 注意,传送後会转为字串
name: 'Alysa'
}
})
然而,以上示范可见,params 和 query 所传送的值都会变为字串型别。因此如果值是物件的话,就没法传送。不然会变成 "[object Object]"
。这情况下,如果透过 params 来传资料就会有问题。解决方法会用 JSON.parse
和 JSON.stringify
来转换资料。
以上示范,我们要用 $route.params
这些方法取得 params 和 query。但如果使用 route props 的各种传送 route props 的模式,就可以更灵活,不再使用 $router
来取得资料也行!
布林模式,需要设定动态路由以及 props: true
。
以下例子,假设我要把 id 资料,由某一页传到 A 元件页面里使用。
router/index.js
const routes = [
{
path: "/",
component: Home
},
{
path: "/a/:id",
name: "a",
component: A,
props: true
}
];
A 元件
<template>
<h1>这是 A 页面</h1>
<p>以下是从首页传来的资料:</p>
<p>{{ id }}</p>
</template>
<script>
export default {
props: {
id: {
type: String,
},
},
};
</script>
不用再透过 this.$route.params
来取资料了!直接在元件里的 props 接收 id 资料,并显示出来。但注意,元件所接收的 props,只能是 params。
在路由物件里,建立一个函式来回传 props,给页面元件使用。
跟 Boolean mode 明显不同:
以下先示范传 params 做法。假设我要做以下的事:
router/index.js
{
path: "/b-params",
name: "Bparams",
component: Bparams,
props: (route) => route.params
}
Home.vue(首页)
按按钮後,就跳转到 Bparams页面,并把 API 回传资料用 params 传出去。
<template>
<h2>Function mode(传 params)</h2>
<p>按按钮後打 API,用 function mode,把 API 资料传到 B-params 页面</p>
<a href="#" @click.prevent="passDataToB">去 B-params 页面</a>
</template>
export default {
methods: {
passDataToB() {
fetch("https://randomuser.me/api/")
.then((res) => res.json())
.then((res) => {
this.$router.push({
name: "Bparams",
params: {
...res.results[0],
},
});
})
.catch((err) => console.log(err));
},
},
};
Bparams.vue
<template>
<h1>这是 B 页面</h1>
<p>以下是从首页传来的资料:</p>
<p>{{ user }}</p>
</template>
export default {
props: {
user: {
type: Object,
},
},
};
物件模式适用於传入静态资料。直接在 props 物件里定义要传送的资料即可。
以下示范把资料传入 C 页面元件:
router/index.js
{
path: "/c",
name: "c",
component: C,
// Object mode
props: {
userStatic: {
username: "Tom",
age: 20
}
}
}
C.vue
<template>
<h1>这是 C 页面</h1>
<p>以下是从 router props 传来的静态资料:</p>
<p>{{ userStatic }}</p>
</template>
export default {
props: {
userStatic: {
type: Object,
},
},
};
https://codesandbox.io/s/router-props-function-mode-ktzbr?file=/src/views/Home.vue
this.$router.push()
来跳转页面时,如果是传 params,要注意 path 和 params 属性不能共存,只能择一填写。How to pass Vue Router params as props to components
【Vue.js】Vue Router 之透过路由组件传参数给元件
在去年参加 iT 铁人赛挑战时,选择的题目是需要实作(见:30 天开发 Android App 的流...
登出模式及未登入限制读取页面 navbar.vue调整 登出登入的切换调整 利用v-show来判断是...
前言 昨天讲了 display 当中的 Flex 属性 那今天就要来讲 display 当中的 Ju...
前言 我们在前一天开发完成了套件,那麽就试着来上架ㄅ 。 可以查看 官方文件,肯定讲的比我清楚哈哈(...
数位化时代里,不管我们正在做什麽、想要做什麽,过程中都在产生资料,可以说每个人是巨量资料的发展历程,...