Below component and mixin have been removed, please see new prefetch hook
Hey folks, Vue 2.6 is here with a great new feature for SSR: serverPrefetch() hook
Native approach
You can find this example in official SSR documentation:
<template>
<div v-if="item">{{ item.title }}</div>
<div v-else>...</div>
</template>
<script>
export default {
computed: {
// display the item from store state.
item() {
return this.$store.state.items[this.$route.params.id];
},
},
serverPrefetch() {
return this.fetchItem();
},
// Client-side only
mounted() {
if (!this.item) {
this.fetchItem();
}
},
methods: {
fetchItem() {
// return the Promise from the action
return store.dispatch('fetchItem', this.$route.params.id);
},
},
};
</script>
~~It's very simple to setup prefetching on server side with this, and this hook is
available on all your components (not only views/pages components)!~~
Second advantage is you have access to this and you can call computed, methods and plugins in it!
~~But compared to asyncData() plugin you have one downside with serverPrefetch hook:
you have to duplicate your code in serverPrefetch and in mounted hooks.~~
Prefetch: renderless component
I've made some little experiments with this new serverPrefetch, here is the first one:
<Prefetch :promise="() => $http.get('/api/data')" v-slot="{ pending, result, error }">
<template v-if="pending">
Loading...
</template>
<template v-else-if="result">
Here is your data: {{ result }}
</template>
<template v-else>
Error!
</template>
</Prefetch>
~~As you can see is a renderless component which can resolve any promise and return results
in scoped slot. Of course this component is SSR ready, so on a HTTP request, promise will
be resolved and rendered on server side, then client side will mount it with prefetched data.~~
~~There is a little dirty thing in there: you have to pass a function that return a promise
as prop of this component. This trick avoid to execute promise twice, one time when the component
is created on server side, second time when component is created on client side.~~
To use it:
import { Prefetch } from '@uvue/core';
Vue.component('Prefetch', Prefetch);
~~This is great, but some of you don't want to see Prefetch components everywhere in their
code, so come the second one:~~
Prefetch: mixin
<template>
<div>
Here is your data: {{ result }}
</div>
</template>
<script>
import { PrefetchMixin } from '@uvue/core';
export default {
mixins: [PrefetchMixin],
data: () => ({
result: null,
}),
async prefetch() {
this.result = await this.$http.get('/api/data');
},
};
</script>
~~This mixin will do the same has serverPrefetch hook but here you declare your
code only once!~~
To make this available everywhere:
import { PrefetchMixin } from '@uvue/core';
Vue.mixin(PrefetchMixin)
So, asyncData and fetch will be removed ?
~~Nope! Mainly because these two hooks use beforeResolve router navigation guard.
Main advantage of this method is that page change only occur when data is fully loaded.~~
~~Second reason to keep these plugins is that usage of serverPrefetch can be dangerous: imagine
you have 10 components in one page that does server prefetching: this can bloat your
page load time and can be difficult to debug.~~
I think it's good practice to keep your data loading on a view/page level to avoid this issue.
DEPRECATED
Below component and mixin have been removed, please see new prefetch hook
Hey folks, Vue 2.6 is here with a great new feature for SSR:serverPrefetch()
hookNative approachYou can find this example in official SSR documentation:~~It's very simple to setup prefetching on server side with this, and this hook is available on all your components (not only views/pages components)!~~
Second advantage is you have access tothis
and you can call computed, methods and plugins in it!~~But compared to
asyncData()
plugin you have one downside withserverPrefetch
hook: you have to duplicate your code inserverPrefetch
and inmounted
hooks.~~Prefetch: renderless component
I've made some little experiments with this newserverPrefetch
, here is the first one:~~As you can see is a renderless component which can resolve any promise and return results in scoped slot. Of course this component is SSR ready, so on a HTTP request, promise will be resolved and rendered on server side, then client side will mount it with prefetched data.~~
~~There is a little dirty thing in there: you have to pass a function that return a promise as prop of this component. This trick avoid to execute promise twice, one time when the component is created on server side, second time when component is created on client side.~~
To use it:~~This is great, but some of you don't want to see Prefetch components everywhere in their code, so come the second one:~~
Prefetch: mixin
~~This mixin will do the same has
serverPrefetch
hook but here you declare your code only once!~~To make this available everywhere:So,asyncData
andfetch
will be removed ?~~Nope! Mainly because these two hooks use
beforeResolve
router navigation guard. Main advantage of this method is that page change only occur when data is fully loaded.~~~~Second reason to keep these plugins is that usage of
serverPrefetch
can be dangerous: imagine you have 10 components in one page that does server prefetching: this can bloat your page load time and can be difficult to debug.~~I think it's good practice to keep your data loading on a view/page level to avoid this issue.