将参数与 Props 解耦
在 index.js 文件中,让我们使用名为 props 的附加属性来调整 about 路由的配置。 通过将此属性的值设置为 true,路由器将自动理解 $route.params 并将其相应地映射到 props 组件中:
{
path: '/about',
name: 'about',
component: () => import(/* webpackChunkName: "about" */'../views/About.vue'),
props: true
}
在 About.vue 文件中,我们将声明 props 类型,如下所示:
props: {
user: String
}
在 <template> 部分,我们将 $route.params.user 替换为 user:
<template>
<div class="about">
<h1>About {{user}}</h1>
</div>
</template>
输出仍然是相同的,如下面的屏幕截图所示:

除此之外,您还可以在路由配置的 props 属性中定义要传递的数据。现在可以将 props 声明为具有所需数据的对象,而不是布尔值,如下例所示:
{
path: '/about',
name: 'about',
component: () => import(/* webpackChunkName: "about" */'../views/About.vue'),
props: { age: 32 }
}
通过类似的步骤,我们将在 About.vue 中将 age 声明为 props 组件,并将其作为文本打印到屏幕上:
<template>
<div class="about">
<h1>About {{user}}</h1>
<h2>Age: {{age}}</h2>
</div>
</template>
<script>
export default {
props: {
user: String,
age: Number
}
}
</script>
现在,当单击 About 页面时,页面将渲染如下:

我们以前的用户数据不再可见!这是因为,现在 props 在 About 路由的配置中使用静态数据声明,并且不能从外部覆盖。无论我们在目标 router-link 组件中的 to 属性参数中传递什么值,它的值在整个应用程序导航过程中都将保持不变。
我们现在将学习如何将所选消息的内容传递到新消息页面并打印它。
练习 6.03:将所选消息的内容传递到新消息页面并将其打印出来
我们将从 Exercise 6.02 “将导航链接添加到 MessageFeed 路由” 继续,其中我们使用消息的 URL 路径定义了 MessageFeed 路由。该视图将在视图组件选项的 data 属性中渲染预定义消息的列表。
在本练习中,我们将创建一个新的 message 页面,指定用于渲染用户选择的消息内容。 它应该是可重复使用的。
要访问本练习的代码文件,请参阅 https://packt.live/36mTwTY 。
-
在 ./src/views/ 文件夹中,我们创建一个名为 Message.vue 的新单文件组件。 该组件接收 string 类型的 content prop 并将其渲染在 <p> 标签下:
<template> <div> <p>{{content}}</p> </div> </template> <script> export default { props: { content: { default: '', type: String } } } </script>
-
让我们将创建的视图组件注册到 ./src/router/index.js 中的现有路由。我们将新路由定义为一条消息,其路径为 /message。它还将接受 props: true 以便将传递给路由的所有参数相应地映射到相关的 prop。要使用的路由的完整列表如下:
export const routes = [ { path: '/', name: 'home', component: Home }, { path: '/about', name: 'about', component: () => import(/* webpackChunkName: "about" */'../views/About.vue') }, { path: '/messages', name: 'messageFeed', component: () => import(/* webpackChunkName: "messages" */ '../views/MessageFeed.vue') }, { path: '/message', name: 'message', component: () => import(/* webpackChunkName: "message" */ '../views/Message.vue'), props: true } ]
-
由于路由已注册并可供使用,我们需要对 ./src/views/MessageFeed.vue 的 <template> 部分进行更改,以确保每个消息行现在可单击,并且在点击时将用户重定向到新路由。让我们用 router-click 替换 <p> 标签。因为我们已将新路由命名为 message,所以我们将设置 to 绑定到
{ name: 'message' }
:<template> <div> <h2> Message Feed </h2> <div v-for="(m, i) in messages" :key="i" > <router-link :to="{ name: 'message'}"> {{ m }} </router-link> </div> </div> </template>
-
在 template 下,我们将添加一个脚本(script)标记,其中包含消息(messages)的一些示例数据:
<script> export default { data() { return { messages: [ 'Hello, how are you?', 'The weather is nice', 'This is message feed', 'And I am the fourth message' ] } } } </script>
-
当您打开 ./messages 页面时,所有消息现在都可以单击,如以下屏幕截图所示:
Figure 3. Figure 6.20: Message Feed page after changing messages to be clickable -
现在,当用户单击消息时,它将打开一个新页面。但是,页面内容将为空,因为我们没有向 <route-click> 组件传递任何内容参数,如下图所示:
Figure 4. Figure 6.21: Message page with no content generated -
让我们回到 ./src/views/MessageFeed.vue 并添加
params: { content: m }
:<template> <div> <h2> Message Feed </h2> <div v-for="(m, i) in messages" :key="i" > <router-link :to="{ name: 'message', params: { content: m }}"> {{ m }} </router-link> </div> </div> </template>
-
现在,当您单击第一条消息 Hello, how are you? 时,输出将如下所示:
Figure 5. Figure 6.22: Message page with the clicked message’s content rendered
很简单,不是吗? 我们通过 router-link 以及组件的 params 和 props 的组合,动态地完成了从消息提要到单个选定消息的详细页面的流程。然而,这种方法有一个显着的缺点。
当您仍在第一条消息的 ./message
路径上时,让我们刷新页面。输出将与步骤 5 中的相同 - 一个空的内容页面。刷新时,路由会在没有传递任何内容参数的情况下触发,这与用户单击特定链接时不同,并且之前传递的参数不会保存或缓存。因此没有内容。
在下面的部分中,我们将学习如何拦截导航流并使用 Router Hooks 解决这个问题。