在为给定路由渲染页面之前,我想首先同步获取必要的数据。理想情况下,我希望在页面组件中获取数据,但我不反对在路由器文件中执行此操作。我已经阅读并尝试了各种方法,但部分挑战来自于这样一个事实:构建组件的方法也有多种,并且某些功能的使用也各不相同。
就我而言,我使用 Composition API 和
语法构建单文件组件。 Vue Router 文档链接讨论了“导航前获取”,其中我可以访问 beforeRouteEnter
或 beforeRouteUpdate
,但这是使用选项 API 显示的。他们确实有 Composition API 的页面,提到我可以使用 onBeforeRouteUpdate
,但它使用 setup()
函数。我想无论如何我都会尝试使用
:
<script setup> import { onBeforeRouteUpdate } from 'vue-router' onBeforeRouteUpdate(() => { console.log('onBeforeRouteUpdate') }) </script>
但是,这不会执行。我尝试过的最接近的方法是使用 beforeEnter
防护来获取路由器中的数据,并将数据设置到 meta
属性上,然后可以在组件中的路由实例上访问该属性: p>
beforeEnter: (to, from, next) => { fetch('https://pokeapi.co/api/v2/pokemon/ditto') .then(res => res.json()) .then(res => { to.meta.pokemon = res; next(); }); }
但是有了这个,文档中指出, beforeEnter
仅在输入路由时触发。参数更改不会重新触发此问题,这意味着我必须在组件中的路线上设置一个观察程序。我还不如将所有这些逻辑都放在组件本身中。
我似乎找不到一个好的方法来做到这一点,但我可能忽略了一些事情。如果有人有一些指示或建议,我将不胜感激。提前致谢。
P粉5462579132023-11-18 12:39:56
首先,beforeRouteUpdate
仅在更新实际路由时触发,但不会像官方那样转到另一个组件/页面这里告诉。
关于什么可能触发生命周期挂钩的示例是
<button @click="$router.push({ hash: `#${Math.floor(Math.random() * 10)}` })"> random hash </button>
onBeforeRouteLeave
完美地工作,正如你所期望的那样,从一个页面移动到另一个页面时。
对于最初的问题,您可以实现某种路由器中间件 就像 Nuxt 做到了。这样,您就可以等待
HTTP 调用,并且只有在那时才允许实际导航。因此几乎可以创建块导航效果。
我不确定如何使用 Composition API 编写它,但我知道它可以与 Options API 完美配合(有很多可用的博客文章)。 setup
本身以它自己的生命周期方式运行,我想很多事情都相当棘手。
TLDR:在我看来,一个好的路由器中间件+页面包装器(如布局)是您案例中的完美组合。在那里,您可以同时为相当多的页面设置一个观察者。
但是一切都取决于您想要如何组织自己并构建代码。
骨架屏幕给人一种比阻塞更快的感觉,但总的来说,您也可以使用 prefetch< /a> (默认情况下也随 Nuxt 一起提供)以获得一些提示并可能在需要某些资源之前加载它们。 (+同一域中的其他技巧来加速您的网络请求)
P粉5459565972023-11-18 11:49:37
有一个解决方案 - 使用顶级等待 - https ://vuejs.org/api/sfc-script-setup.html#top-level-await
只需将 RouterView 组件包装在 Suspense 组件中,如下所示 - https://vuejs.org/guide/built-ins/suspense.html#combining-with-other-components(不要使用不需要的组件)
唯一需要注意的是,“加载屏幕”将在初始请求时可见。
我为您做了一个小演示,以便您可以尝试一下 - https ://github.com/ileue/vue-top-level-await-demo