-
-
Notifications
You must be signed in to change notification settings - Fork 5.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provide access to the router instance and component options in "beforeRouteEnter" guard #3166
Comments
Alternatively, access to only
|
@posva I understand that you are actively working on the next version of the router, and this kind of feature can significantly improve usage of the From what I see in the export function guardToPromiseFn(
guard: NavigationGuard,
to: RouteLocationNormalized,
from: RouteLocationNormalizedLoaded,
instance?: ComponentPublicInstance | undefined,
resolvedComponent?: RouteComponent | undefined,
): () => Promise<void> {
...
// wrapping with Promise.resolve allows it to work with both async and sync guards
Promise.resolve(guard.call(instance, to, from, next, resolvedComponent)).catch(err =>
reject(err)
)
}
export function extractComponentsGuards(
matched: RouteRecordNormalized[],
guardType: GuardType,
to: RouteLocationNormalized,
from: RouteLocationNormalizedLoaded
) {
...
if (typeof rawComponent === 'function') {
...
return (
guard && guardToPromiseFn(guard, to, from, record.instances[name], resolvedComponent)()
)
} else {
const guard = rawComponent[guardType]
guard &&
// @ts-ignore: the guards matched the instance type
guards.push(guardToPromiseFn(guard, to, from, record.instances[name], rawComponent))
}
} What do you think? If that works, it looks like it can easily be backported to vue-router v3 |
This is pretty much a duplicate of #2118 Importing the Note accessing the It's important for me to understand what is this solving. Is it accessing to the Most of the time, it is possible to replace I don't think it makes sense to provide the router instance as |
Hi @posva. Thanks for coming back on this one.
I do agree with you on this one. That's why I created different ticket with alternative API proposal, which suppose to solve the same issue. Also because this proposal is limited to
That is complete surprise for me, as
My initial intention was to implement "data fetching before navigation" concept but with the use of Vuex store. To achieve that I need to have access to the
That is an interesting idea and I would investigate it, however I can already see one challenge with it. Looking forward for your thoughts on this. |
That's true. Then it's not a hack... It doesn't work on multiple apps but at the same time you don't do SSR when having multiple apps, so I guess it's fine. It won't be the same on v4 (where it currently doesn't exist) because it could only point to the app returned by My guess is that data fetching might not belong in the routing but even with global |
That is true, and that is something I want to investigate in our app. However, as I mentioned, there is no way to tell which of those |
Yes. They are also ordered from parent to child. You can checkout the source code to see how we do it |
After some experiments, it looks like |
+1, is really needed for components shared with lerna (can't import store instance). Got to same exact issue on our end, what's going on with this? |
In my case there are several apps with their router instances, and the component is unaware which one in use, so it cannot import |
I have just exported the root component and import it as I need into my components: // main.ts
export default createApp(App).use(router).mount("#app"); <script lang="ts">
import { useRouter } from "vue-router";
import main from "../main";
async function load() {
const router = useRouter();
await new Promise((r) => setTimeout(r, 1000));
await router.replace({ name: "index" });
}
</script>
<script setup lang="ts">
defineOptions({
async beforeRouteEnter() {
await main.$root.$.appContext.app.runWithContext(load);
},
});
</script> Extremely not pretty, but seems working. EDIT: |
I think that you might find this Data Loaders RFC interesting: vuejs/rfcs#460 (comment) |
I do find it very interesting, in fact I am trying to implement something inspired by that RFC. Maybe I should have a looksie at how it is implemented in |
I think they were. At least, I do plan on making them available. Be aware that the loaders are subject to change. |
What problem does this feature solve?
There are some use cases, when it is required to have access to the router instance and component options inside
beforeRouteEnter
guard. WhilebeforeRouteUpdate
andbeforeRouteLeave
could get such access throughthis.$router
andthis.$options
, it seems not way to achieve it inbeforeRouteEnter
. Importing router instance (similar to store import suggestion here) is not an option for us because we have shared set of router components, which are re-used in different vue applications, so there is no single place to import vuex store from.Use case
I'm trying to create generic plugin for our applications which will define hook to pre-load data. In some component data pre-load will happen via vuex store, so it should be accessible in this hook.
Here is simplified code for the plugin:
This plugin will make it possible to define custom
preloadData() { ... }
component option for a generic data pre-load as part of routing process. The only missing references to make it work arecomponentOptions
androuter
.Note that it is possible to provide
router
access in this particular example by passing it as plugin argument –export default function install(Vue, router) { ... }
. However, it might be still beneficial to have access to router in thebeforeRouteEnter
guard, as it will be a solution for #3157.What does the proposed API look like?
Proposal is to add additional
guardContext
argument to the guard function:However if it should be implemented in different way – would be great to hear it.
The text was updated successfully, but these errors were encountered: