Comments (15)
@Xowap Can you provide an example how implement it? thanks 😄
from nuxt.
Actually it is not possible because it's not linked to a route, Nuxt.js surcharges the component data() associated to a route to allow async data.
For sub components, there are 2 ways of achieving it:
- Making the API call in the mounted() hook and setting the data afterwards, downside: no server rendering
- Making the API call in the data() of the page component and giving the data as a prop to the subComponent: server rendering OK. But the data() of the page might be less readable because it's loading the async data of the sub components
It all depends if you want the sub components to be server-rendered or not.
I hope it solves your issue :)
from nuxt.
This is kind of what I feared.
I've been reading Vue 2's documentation, it looks like Vuex becomes basically mandatory. Which also solves this problem. I guess the real clean solution is to use Vuex, right?
from nuxt.
Yes of course I forgot about vuex, you can integrate the store easily with Nuxt.js, just add a store/index.js (look at examples/vuex-store)
from nuxt.
An example would really help.
from nuxt.
@Atinux Could you elaborate why this is not possible? All the components should be known beforehand statically and it should be possible to make the appropriate calls with the given context. I'm looking into how to solve the issue myself, too, as it would tremendously improve modularization.
from nuxt.
Hi @Etheryte
Sadly, there is no way to know the component three inside lib/app/server.js
, I can only get the routes components and update them by calling the asyncData
& fetch
methods. I tried to find a way for it but it seems impossible right now.
But it's also a good thing to not call asyncData for "normal" components since it let's everyone create Vue component compatible with the same behaviour under nuxt.js and a basic vue app.
from nuxt.
Use this function. That will test all child component .fetch
and call it.
function fetchDeep(component){
var originFn =component.asyncData;
component.asyncData =async function (ctx) {
if(component.components){
let childComponents =Object.values(component.components);
console.log(childComponents);
while(childComponents.length){
let comp =childComponents.shift();
if(comp.options.fetch) await comp.options.fetch(ctx);
if(comp.components) childComponents.push(...Object.values(comp.components));
}
};
return originFn(ctx);
};
return component;
};
There is an example:
A nav component.
import Vue from "vue"
import {mapGetters} from "vuex"
import Component from 'nuxt-class-component';
@Component({
name :'blog-nav',
async fetch({store}){
await store.dispatch('fetchCategory');
},
computed :{
...mapGetters(['categoryMap']),
},
})
export default class extends Vue {
showCategory =['technology','works','think'];
}
A page component which import nav component.
import Vue from "vue"
import Component from 'nuxt-class-component';
import {ArticleInfo} from "@foxzilla/fireblog";
import Marked from 'marked';
import Nav from '~/components/blog-nav.vue';
import {fetchDeep} from '~/modules/jslib';
@Component(fetchDeep({ // ❗️❗️❗️
async asyncData(ctx){
var articleInfo:ArticleInfo =await ctx.app.$axios.$get(`/article/detail/${ctx.params.id}`);
await (<any>Nav).options.fetch(ctx);
return {articleInfo}
},
head(val:ArticleInfo){
return {
title: this.articleInfo.title,
};
},
components :{
'blog-nav' :Nav,
},
}))
export default class extends Vue {
articleInfo:ArticleInfo;
md:(mdContent:string)=>string =Marked;
}
from nuxt.
Use this function. That will test all child component .fetch
and call it.
export function fetchDeep(component){
var originFn =component.asyncData;
var fetchedComp =[];
component.asyncData =async function (ctx) {
if(component.components){
let childComponents =Object.values(component.components);
while(childComponents.length){
let comp =childComponents.shift();
if(fetchedComp.includes(comp))continue;
else fetchedComp.push(comp);
if(comp.options && comp.options.fetch) await comp.options.fetch(ctx);
if(comp.fetch) await comp.fetch(ctx);
if(comp.components) childComponents.push(...Object.values(comp.components));
if(comp.options && comp.options.components) childComponents.push(...Object.values(comp.options.components));
}
};
return originFn && originFn(ctx);
};
return component;
};
There is an example:
A nav component.
import Vue from "vue"
import {mapGetters} from "vuex"
import Component from 'nuxt-class-component';
@Component({
name :'blog-nav',
async fetch({store}){ // will be called
await store.dispatch('fetchCategory');// use vuex
},
computed :{
...mapGetters(['categoryMap']),
},
})
export default class extends Vue {
showCategory =['technology','works','think'];
}
A page component which import nav component.
import Vue from "vue"
import Component from 'nuxt-class-component';
import {ArticleInfo} from "@foxzilla/fireblog";
import Nav from '~/components/blog-nav.vue';
import {fetchDeep} from '~/modules/jslib';
@Component(fetchDeep({ // ❗️❗️❗️
async asyncData(ctx){
var articleInfo:ArticleInfo =await ctx.app.$axios.$get(`/article/detail/${ctx.params.id}`);
await (<any>Nav).options.fetch(ctx);
return {articleInfo}
},
components :{
'blog-nav' :Nav,
},
}))
export default class extends Vue {
}
from nuxt.
@pea3nut Does this work with SSR as well? I tried a similar approach a few releases ago and had a ton of problems getting it to work on the server side.
from nuxt.
@Etheryte It doesn't have a strong test, but now it works on npm run dev
very well, not only enter a URL but also passing in by <router-link></router-link>
, and, I have tested npm run generate
just now, it works too.
Of course, my app is not complex enough now, maybe some bug hidden is there.
`
from nuxt.
I've updated your function with possibility to leave empty fetch or asyncData component property and also use both fetch or asyncData on chold components:
export const fetchDeep = function (component) {
const originFn = component.asyncData;
component.asyncData = async function (ctx) {
if (component.components) {
const promisesToResolve = [];
let childComponents = Object.values(component.components);
while (childComponents.length) {
let comp = childComponents.pop();
if (comp.asyncData) {
promisesToResolve.push(comp.asyncData(ctx));
}
if (comp.fetch) {
promisesToResolve.push(comp.fetch(ctx));
}
if (comp.components) {
childComponents.push(...Object.values(comp.components));
}
}
await Promise.all(promisesToResolve);
};
return (originFn && originFn(ctx)) || Promise.resolve();
};
return component;
};
Is it correct that collecting all promises to resolve in array and then call Promise.all theoretically would work faster that couple of await? On it doesn't matter on server side render? And is it correct assumption that component promise resolve order is unimportant in such case?
from nuxt.
@Romick2005 I found some bugs in my fetchDeep
, and I guess you fetchDeep
has there bugs too.
export function fetchDeep(component){
var originFn =component.asyncData;
var fetchedComp =[];
component.asyncData =async function (ctx) {
if(component.components){
let childComponents =Object.values(component.components);
while(childComponents.length){
let comp =childComponents.shift();
if(fetchedComp.includes(comp))continue;
else fetchedComp.push(comp);
if(comp.options && comp.options.fetch) await comp.options.fetch(ctx);
if(comp.fetch) await comp.fetch(ctx);
if(comp.components) childComponents.push(...Object.values(comp.components));
if(comp.options && comp.options.components) childComponents.push(...Object.values(comp.options.components));
}
};
return originFn && originFn(ctx);
};
return component;
};
It's a little ugly... and too hackly.
from nuxt.
And, I'm no idea of how to use the async data in the component of /layouts
. Does anyone have some ideas?
from nuxt.
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
from nuxt.
Related Issues (20)
- static generating is removing invalid html, but not reporting when linting HOT 4
- Nuxt module dependencies are not inherited from layers HOT 16
- When opened in some browsers, it displays: undefined is not an object (evaluating'uc.matchAll' HOT 2
- support configure `omitLineBreaks` of `@unhead`
- All pages styles are being bundled and delivered HOT 3
- server-page styles are not being built
- Further Customization Options on Teleport and Root Tags HOT 3
- nuxt3 开发环境实现分片上传会 [unhandledRejection] write ECONNABORTED
- RouterView slot HOT 3
- Vue draggable lib not working inside module during dev mode while it works on production build HOT 2
- more granular control of link prefetching
- Remove inline scripts from the build HOT 5
- Nuxt Build Error (RegExp.prototype.exec) HOT 3
- Netlify nitro deployment adds _redirects file with non-existing server functions directory HOT 2
- Final tasks before v4 release
- HMR doesn't work on pages that are added to .nuxtignore file HOT 6
- updating of experimental options HOT 3
- Option to install layer dependencies with --ignore-scripts HOT 2
- `$fetch` interceptor not modifying the retried request when a body is present HOT 5
- How can we integrate AMP ( Accelerated Mobile pages) In nuxt 3.8 ?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from nuxt.