Heim > Fragen und Antworten > Hauptteil
Bevor ich die Seite für eine bestimmte Route rendere, möchte ich zunächst die notwendigen Daten synchron abrufen. Idealerweise möchte ich die Daten in der Seitenkomponente abrufen, habe aber nichts dagegen, dies in der Router-Datei zu tun. Ich habe verschiedene Ansätze gelesen und ausprobiert, aber ein Teil der Herausforderung ergibt sich aus der Tatsache, dass es mehrere Möglichkeiten zum Erstellen von Komponenten gibt und die Verwendung bestimmter Funktionen unterschiedlich ist.
In meinem Fall verwende ich die Composition API und
语法构建单文件组件。 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