-
Notifications
You must be signed in to change notification settings - Fork 2
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
Nuxt 3: Introducing fetch() hook #27
Comments
I haven't built a Nuxt app before, but I'm in the middle of teaching these topics at Vue Mastery. Here are my feelings:
This makes me wonder if you planning on keeping asyncData with the same functionality? This might be nice for those who want to upgrade to Nuxt 3 who are using it.
If your goal is to optimize for beginners, not having to deal with a loading state on the client side was quite nice. However, I read above that this is not possible? Also, it might be nice to keep asyncData with the same functionality (of waiting for a return). Again, this might be nice for those who want to upgrade to Nuxt 3 who are using it. |
Thanks @Gregg for your feedback. We plan to have a Nuxt module to keep the current I wanted to get closer to Vue core by keeping only one
I tried many ways to keep the same behaviour when navigating on client-side (ie: wait for all fetch calls before switching to the new route):
But these two were breaking other stuffs inside Vue internals (page transitions, keep-alive, etc) 😢 |
Hi @atinux , i working on quasar-framework and i see have a same thing in quasar framework.
so, how about it? |
Hi @ttquoccuong Actually, the |
First of all, I love this and it will definitely be a huge improvement for most of my projects. But there are some projects which are simpler and that kind of client-side UX might be too much overhead. Maybe the data being fetched is really small that there wouldn't be significant perceived speed improvement and it would cause an annoying flickering of the placeholder as the data is fetched really fast. It's also a huge breaking change, as the whole Nuxt data fetching logic revolves mainly around The So, my suggestion is to add a Defaulting |
That was how I wanted to implement it @henriqemalheiros, exactly like this to have no breaking changes and a smooth upgrade to all users...But sadly Vue.js does not have any I tried to hack |
I was trying to find a way to achieve this and, from what I've found, it seems that the only way this could be done tidily would be through asynchronous lifecycle hooks. In the past, Evan said that there's hasn't been enough substantial benefits that justified implementing this feature. Maybe, with Nuxt on the scene, they could implement it in Vue 3? One possible alternative solution would be tackling this question (small repro here). |
Hello. I've just seen issue this referenced in this issue I commented on...
...so perhaps I'll add my thoughts (though they may not be particularly relevant). In brief, that issue relates to what might be loosely termed a "race condition" regarding fetched data and rendered component:
The issue is that because the data has not been made available in mount, both template and computed properties require I'm not so familiar with nuxt (just a couple of practice projects) but it seems that this proposal does not look to solve that, as the component is rendered first? It seems to me that some way to merge the data before mounting would be the key to cleaner templates and no I made some suggestions in my comment on how this might be achieved, but as @henriqemalheiros noted, the code in Vue Router seems very complex / abstracted so it's something that would certainly need attention from @posva. I forked the repo and had a good dig about – to no avail! |
@davestewart your solution is good, but it achieves the same UX as the current Nuxt version. The problem we're discussing is accessing the component's instance before the route changes. Currently,
If we could move the |
Yes, we're looking to solve the same problem. My proposal looks to similar to
https://jsfiddle.net/tsyav1up/2/ You mention:
The bits I don't understand:
Perhaps this is Nuxt internals I don't understand... And ignore this if it's hijacking the RFC. |
@davestewart you're using That's exactly what we currently have in Nuxt and that is not what this RFC is about. This RFC is introducing a new way to handle data fetching that is closer to what major SPAs do, like Facebook or YouTube. It also supports access to As @atinux said:
So we want to use |
This is the topmost feature I wait for in Nuxt 3 😉 |
I need this feature :-) |
New PR is up -> nuxt/nuxt#6880 |
Maybe my opinion will change at some point, but for sites that are pretty quick I think showing users a loaded page is better than showing them a quasi-broken page where they have to wait longer and watch items load. This is very similar to sites who lazy load images when they enter the viewport (very annoying) vs just BEFORE they enter the viewport. I'm glad to see there is a way to do it the 'classic' way in v3 (though it also seems there is a fetch polyfill for some reason, it would be nice to NOT have that if we aren't using this new feature.) |
@hecktarzuli I would disagree with this statement. One of the important parts of UX is loading speed and speaking from the personal experience, perceptive speed of loading process increases significantly when done in a new way so I would rather go the new way than the old one |
@AndrewBogdanovTSS It's similar to pages like this. On a Desktop, go to https://realtruck.com/, click on a category, then go directly to another category (via top menu or whatever), then hit back/forward/back/forward. You see the content change, then load when you are already 'in' the page. It's probably a little picky, but it annoys me. Yes we could put in the classic placeholder chunks everywhere, but it would actually be a worse experience. If we could just wait ~ 50-100ms and have everything perfect when you hit the page, that's where the sweet spot is. I do understand having a loading state for slow mobile is also ideal, but looking at RUM, that's < 1% of our users. |
Surely it's a no-brainer — implement the new behaviour and polyfill the old behaviour. It's got to be relatively trivial versus doing it the other way around. Some kind of observer/listener on |
If I had a magic wand we'd have 1 fetch method and a way to tell Nuxt to wait XXms for fetches to resolve before starting to render the route. If all fetches resolve before the wait, great! Wait no longer and the page is rendered as intended. It's the font-display:fallback of routing - the best of all worlds :) |
Well that was my wish too, but not possible since we have to create the instance of the page (so showing it) to call fetch 😢 On SSR there is not placeholder since we can wait before rendering the HTML. |
One good news, in full static mode, placeholders should be hidden since the data will be available for the rendered components 😄 |
Yep, hence the word 'magic'. 😄 You'd pretty much have to re-think this whole feature, and maybe even have to hack Vue/Vue-Router. A guy can DREAM! |
Already, gradually in many projects there is a migration to composition api. Is it supposed that the major version of Nuxt 3 will be for Vue 2? |
Composition API is optional @negezor We will support it as soon as it actually better support SSR :) |
@hecktarzuli, you described the perfect end-user experience:
The only means I could find to accomplish this today was with the <template>
<div>…</div>
</template>
<script>
export default {
transition: { name: "page", mode: "" },
// …
};
</script> This makes use of the following global CSS: .page-leave-active {
/* delay gives extra time for data fetching */
transition-delay: 0.4s;
transition-duration: 0;
} This gets the job done, but I'd really like more programmatic control, such as:
|
@pi0 @atinux
So I try the above code and it works fine on client-side, but if error happens during SSR I get the following warning:
So how this most common error handling pattern should be implemented via new Fetch hook ? Thanks |
Closing since it is available in Nuxt 2.12: https://nuxtjs.org/api/pages-fetch |
Summary
Vue 2.6 introduced the serverPrefetch hook on SSR. Allowing to have an asynchronous hook for components to be awaited before rendering the HTML.
The idea is to introduce a new hook called
fetch()
that will allow any component to handle asynchronous operation on both server-side and client-side.Basic example
This is how a page component can look like:
pages/index.vue
You can see a more detailed example and documentation here: https://github.com/nuxt/nuxt.js/tree/feat/async-data/examples/v3/fetch
Motivation
The main motivation here is to remove the correlation between pages & asynchronous data. Each component could have its own async data logic.
This could also introduce a way for Nuxt modules author to create components to fetch data on particular endpoints.
Example:
Where
~/components/Post.vue
is something like:Detailed design
A schema is worth a thousand words 😄
Drawbacks
Context
fetch
hook does not receive anycontext
as 1st argument anymore since it has access tothis
.The context will be updated to be available through
this.$ctx
,this.$config
andthis.$nuxt
, learn more on #25Server-side
No drawbacks since Nuxt will wait for all
fetch
hooks to be finished before rendering the page.Client-side
The main drawback of this current implementation if the UX between Nuxt 2 & Nuxt 3 when navigating from page to page.
Let's take an example of having two pages (
A
andB
) withfetch
used in both of these pages.A -> middleware -> fetch/asyncData -> B
A -> middleware -> B -> fetch
This implies to create placeholders to display something while
fetch
is being called. This is why$isFetching
is introduced.We could support the "old" behaviour by providing a Nuxt module (using Nuxt middleware + plugin), a POC has been made on https://github.com/nuxt/nuxt.js/tree/feat/async-data/examples/v3/async-data
Advantages
People coming from Vue applications should find the new usage of
fetch
easier.this
, no need to learn some mystery Nuxt contextbeforeMount
ormounted
hook to call asynchronous data, renaming it tofetch
should just workfetch
is called duringbeforeMount
hookUnresolved questions
placeholder
property to overwriterender
and show this component until$isFetching
becomesfalse
?unexpected
error in thefetch
hook?Things left:
$progress
bar to handle multiplefetch
calls, see https://github.com/f/vue-waitThe text was updated successfully, but these errors were encountered: