Comments (15)
@Xowap Can you provide an example how implement it? thanks π
from nuxt.js.
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.js.
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.js.
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.js.
An example would really help.
from nuxt.js.
@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.js.
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.js.
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.js.
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.js.
@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.js.
@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.js.
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.js.
@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.js.
And, I'm no idea of how to use the async data in the component of /layouts
. Does anyone have some ideas?
from nuxt.js.
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.js.
Related Issues (20)
- Can't serve app under subfolder HOT 2
- definePageMeta not working while extendPages from *.js files HOT 2
- Netlify infinite 302 loop with query params & trailing slashes HOT 1
- Layers: Server middlewares are no longer ordered by filename HOT 2
- 'chokidar-granular' doesn't roload Nuxt while using NuxtKit/addLayout HOT 2
- app.cdnURL not applied to URLs in global CSS files HOT 1
- The document occurs error HOT 1
- `defineVitestConfig` from `@nuxt/test-utils` is not a drop-in replacement for `defineConfig` from `vite` (`No test suite found in file`) HOT 1
- During the localization process of Nuxt3, there was an issue of absolute referencing HOT 1
- ERROR input.replace is not a function HOT 2
- Wrong route handler used/RouteParams lost HOT 8
- Warning: "[Violation] Avoid using document.write()." HOT 1
- this is a bug report HOT 1
- Use html-minifier-terser instead of html-minifier for @nuxt/generator HOT 2
- Response status code is returned as 200 on a 404 page HOT 3
- Thereβs a bug HOT 1
- auto custom mode for ssr or csr HOT 1
- Can't auto import component as Pascal Case when use script lang="tsx" in SFC HOT 5
- Typescript not picking up extended NuxtConfig interface when installing with pnpm HOT 3
- Router params 'undefined' in server middleware HOT 2
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.js.