设置组件内钩子
最后,我们还可以使用组件内 Hook 作为组件生命周期 Hook,我们希望将这些 Hook 的范围限制在组件级别,以便更好地维护代码,或者增强工作流程,使同一组件在特定用例中需要有不同的行为。
我们现在可以拥有 About
组件,并定义 beforeRouteEnter()
Hook,如下所示:
<script>
export default {
data() {
return {
user: ''
}
},
beforeRouteEnter(to, from, next) {
if (!to.params || !to.params.user) {
next(comp => {
comp.user = 'Alex'
})
} else {
next();
}
}
}
</script>
可以看到,在 beforeRouteEnter
期间我们无法访问组件的 this
作用域,因为触发时视图组件仍在创建中。幸运的是,我们可以通过传递给 next()
的回调来访问该实例。每当导航被确认时,这意味着组件被创建,回调将被触发,并且组件实例将作为回调的唯一参数(comp)。
对于 |
beforeRouteUpdate 当同一个组件被不同的路由重用时被调用。 这适用于我们使用动态路由的情况,这将在下一节中讨论。
beforeRouteLeave 在组件将被停用或用户离开当前视图之前被触发。 这在新导航的 beforeEach 防护之前调用,通常在编辑器组件中使用,以防止用户在不保存的情况下导航离开。
在这个守卫中,我们可以通过将 false
传递给 next()
函数来取消新的导航。
例如,假设我们将以下 Hook 添加到 About.vue 文件中组件的选项中:
//...
beforeRouteLeave(to, from, next) {
const ans = window.confirm('You are about to leave the About page. Are you sure?');
next(!!ans);
}
当我们离开 About 页面时,将出现一个弹出对话框,要求确认,如下图所示,然后继续相应导航:

在本节中,我们研究了如何设置组件内 Hook,即仅限于特定组件的 Hook。 我们为 About 组件设置了一个组件内 Hook,要求用户在离开页面之前进行确认。 在下一节中,我们将把消息列表移动到外部文件中,仅当 MessageFeed 处于视图中时才加载。
练习 6.04:将消息列表提取到外部文件并仅在查看 MessageFeed 时加载它
回到 Exercise 6.03,将所选消息的内容传递到新消息页面并将其打印出来,现在我们将使用 beforeEnter 和 beforeRouteEnter 路由器挂钩进行一些代码增强。本练习旨在让您更熟悉如何使用路由器挂钩。
要访问本练习的代码文件,请参阅 https://packt.live/3lg1F2R 。
-
让我们从 ./src/views/MessageFeed 中提取消息静态数据。vue 并将其保存在 ./src/assets/messages.js 中:
const messages = [ 'Hello, how are you?', 'The weather is nice', 'This is message feed', 'And I am the fourth message' ]; export default messages;
-
在 ./src/views/MessageFeed.vue 中,我们将本地数据属性替换为
props: { messages: { type: String, default: [] }}
:export default { props: { messages: { type: Array, default: () => [] } } }
-
现在我们需要加载消息列表,并在导航到消息路由时将其分配给消息参数。 我们将通过在路由的配置对象中使用 beforeEnter Hook 来完成此操作。 不要忘记添加 props: true 将参数标准化为相关的渲染 props。 您可以通过修改 src/router/index.js 中定义的 route 来做到这一点,如下所示:
{ path: '/messages', name: 'messageFeed', component: () => import(/* webpackChunkName: "messages" */'../views/MessageFeed.vue'), props: true, async beforeEnter(to, from, next) { next() } },
-
我们将通过导入(import)延迟加载消息列表:
const module = await import (/* webpackChunkName: "messagesFeed" */ '../assets/messages.js');
-
然后,检索所需的信息,如下所示:
const messages = module.default; if (messages && messages.length > 0) { to.params.messages = messages; }
-
src/router/index.js 中路由的完整代码应如下所示:
{ path: '/messages', name: 'messageFeed', component: () => import(/* webpackChunkName: "messages" */ '../views/MessageFeed.vue'), props: true, async beforeEnter(to, from, next) { if (!to.params || !to.params.messages) { const module = await import (/* webpackChunkName: "messagesFeed" */ '../assets/messages.js'); const messages = module.default; if (messages && messages.length > 0) { to.params.messages = messages; } } next() } },
查看网站时,我们应该看到类似于上一个练习的消息源。 这如下面的屏幕截图所示:

至此,我们已经学习并实践了如何使用不同的路由 Hooks 在应用程序中配置路由器、传递参数以及拦截页面之间的导航。在下一节中,我们将讨论一个更高级的主题——动态路由。