Access "page data" within vue component used in markdown content #3684
Replies: 2 comments
-
|
I am trying now a shared reactive var that is imported in both components export const referencesStore = reactive({
sources: new Map<string, Source>(),
links: new Map<string, SourceLink>(),
hasLinkForCode(code: string) {
....Good idea or should I replace that? |
Beta Was this translation helpful? Give feedback.
-
|
As I have seen that multiple people run into that problem, I'll reiterate a bit what I did, maybe it helps you as well. Situation: In the markdown I have components that are used and the components need data from the DB. I have a component named "Reference" that has a parameter "code" that is the identifier for the data to fetch. Problem: Multiple queries fail silently when you superseed an unknown number of queries when the site is no longer deployed locally. (In my case it failed with the cloudflare D1 DB) Solution: Add Minimark as explicit dependency if necessary, Add this Snippet: function extractCodes(body: MinimarkTree | undefined): string[] {
if (body === undefined) return []
const result: string[] = []
visit(body, node => node[0] === 'reference', (node) => {
result.push(node[1].code as string)
})
return result
}To fetch the codes from the markdown. The references need to be available for the components within the page, so I used a reactive variable. export const referencesStore = reactive({
sources: new Map<string, Source>(),
links: new Map<string, SourceLink>(),
hasLinkForCode(code: string) {
return this.links.has(code)
},
hasSourceFor(path: string) {
return this.sources.has('/quellen/' + path.split('/')[2] + '/' + path.split('/')[3])
},
linkByCode(code: string): SourceLink {
return this.links.get(code) || {
title: code + ' not found',
date: '', code: '', uri: '', type: '', path: '', tags: [], coSources: [],
}
},
sourceByLinkPath(path: string): Source {
return this.sources.get('/quellen/' + path.split('/')[2] + '/' + path.split('/')[3]) || {
name: path + ' not found',
date: '', description: '', path: '', tags: [], image: '',
}
},
async fetchFor(links: string[] | undefined) {
const sourceLinkCodes = new Set<string>(links || [])
const { data: sourceLinksRaw }
= await
useAsyncData(
`quellenlinks-for-page`,
() => {
return queryCollection('quellenlinks')
.orWhere(
(query) => {
sourceLinkCodes.forEach(s => query = query.where('code', '=', s))
return query
},
).all()
})
const sourceLinks = sourceLinksRaw.value as SourceLink[]
this.links.clear()
this.sources.clear()
for (const link of (sourceLinks || []) as SourceLink[]) {
this.links.set(link.code, link)
}
await this.updateSources()
},
async updateSources() {
const sourcePaths = new Set([...this.links.values()]
.map(l => '/quellen/' + l.path.split('/')[2] + '/' + l.path.split('/')[3]))
const { data: sourcesByLinksRaw }
= (this.links?.size > 0)
? await useAsyncData('sourcelink-sources', () => {
const builder = queryCollection('quellen').orWhere(
(query) => {
sourcePaths.forEach(s => query = query.where('path', '=', s))
return query
},
)
return builder
.all()
})
: { data: { value: [] } }
for (const source of (sourcesByLinksRaw?.value || []) as Source[]) {
this.sources.set(source.path, source)
}
},
})In the page that displays the markdown I do this: referencesStore.fetchFor(extractCodes(page.value?.body))The component fetches the data from there: const props = defineProps<{
code: string
}>()
const link = referencesStore.linkByCode(props.code)Hope it helps |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
I am using nixt to create a knowledge base for fact check, there I have lots of sources and links from sources that are referenced within the markdown files.
I have the problem explained in #3683 and I guess the problem is that nuxt fails when within a single page you have more than a handful of DB queries. To reduce the number of queries, I am thinking to "register" the links in the markdown head and to fetch them in a single call before rendering the markdown, which would then do a lookup in the linkdata that was fetched before.
The problem is that the data is queried within the vue component that displays the page content and the markdown is evaluated later, using the content renderer component.
I don't know how I can easily pass a large array from the outside to the vue components that are used within the markdown. I am thinking of some kind of "global page context". I am a bit uneasy regarding memory usage when I mess up and fill up the browser memory with globals :-D
State management like vuex has a similar problem and I really only need the data within the page rendering, not before and not afterwards.
Any advice? :-)
Beta Was this translation helpful? Give feedback.
All reactions