Fetching all pages and data #72
-
I'm currently in the process of upgrading my personal website from VuePress to this newer VuePress 2, which uses Vue 3. At this point, I managed to eject the theme in the new way and using the local theme with a relative path. I also converted my Home page to VuePress 2, and it also loads the data provided via the frontmatter. So far, so good. ✌️ The problem is... I'm stuck at the part of loading my blog posts, guides and portfolio items. Previously, I used (...) But what is the VuePress 2-equivalent of Kind regards, Ricardo P.S. I already found that I could use the following line for the import type { Page } from '@vuepress/core/lib/types' |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 12 replies
-
TLDR: I checked the following code to confirm that we are still provide However, So, use hook usePagesData exported from client: import { usePagesData } from "@vuepress/client" Also a good idea to inject pages global computed: // composable/usePosts.ts
import { inject } from "vue"
import { usePagesData } from "@vuepress/client"
import type { InjectionKey } from "vue"
import type { PageData } from "../types"
export const pagesSymbol: InjectionKey<Promise<PageData[]>> = Symbol("posts")
/**
* Inject pages global computed
*/
export const usePages = async (): Promise<PageData[]> => {
const pages= inject(pagesSymbol)
if (!pages) {
throw new Error("usePages() is called without provider.")
}
return pages
}
export const resolvePages = async (): Promise<PageData[]> => {
const pagesData = usePagesData()
const pages = await Promise.all(
Object.keys(pagesData.value).map((key) => pagesData.value[key]())
)
return pages as PageData[]
} // clientAppSetup.ts
import { provide } from "vue"
import type { ClientAppSetup } from "@vuepress/client"
import { resolvePosts, postsSymbol } from "./composables"
const clientAppSetup: ClientAppSetup = () => {
const pages = resolvePages()
provide(pagesSymbol, pages)
}
export default clientAppSetup |
Beta Was this translation helpful? Give feedback.
-
Since @nsznsznjsz has provided a possible solution, I would like to share the considerations behind this change. Also provide a TLDR; version (lol): Scalability Here's the original discussion:
In short, putting The pages data is only useful for some features of VuePress v1:
Those features are not required for all sites, so we make page data dynamically imported in v2 to try to avoid the scalability issue. Now if we understand the problem, we might find that @nsznsznjsz 's solution should work well in small sites, but it would also encounter the same scalability issue as v1. A better solution would be collecting data on demand in node side, and forwarding data to client side. For example, generate temp file in // .vuepress/config.ts
export default {
onPrepared: async (app) => {
const myData = app.pages.map((page) => {
// ...
})
await app.writeTemp('my-data.js', `export default ${JSON.stringify(myData)}`)
},
} // some-client-component.vue
import myData from '@temp/my-data' However, this solution is more complicated, and should handle watching and HMR manually to get better dev experience. 🤔 |
Beta Was this translation helpful? Give feedback.
TLDR:
import { usePagesData } from "@vuepress/client"
I checked the following code to confirm that we are still provide
$site
on template:https://github.com/vuepress/vuepress-next/blob/67118e8d9e57088e68076c631b1bfb58a6d0a730/packages/%40vuepress/client/src/app.ts#L129-L170
However,
$site.pages
no longer exists:https://github.com/vuepress/vuepress-next/blob/67118e8d9e57088e68076c631b1bfb58a6d0a730/packages/%40vuepress/shared/src/types/site.ts#L7-L36
So, use hook usePagesData exported from client:
Also a good idea to inject pages global computed: