diff --git a/packages/client/src/app.ts b/packages/client/src/app.ts index 73f53e01aa..7b071ee338 100644 --- a/packages/client/src/app.ts +++ b/packages/client/src/app.ts @@ -2,6 +2,7 @@ import { clientConfigs } from '@internal/clientConfigs' import { createApp, createSSRApp, h } from 'vue' import { RouterView } from 'vue-router' import { siteData } from './composables/index.js' +import { clientDataMap } from './helpers/index.js' import { createVueRouter } from './router.js' import { setupGlobalComponents } from './setupGlobalComponents.js' import { setupGlobalComputed } from './setupGlobalComputed.js' @@ -50,6 +51,11 @@ export const createVueApp: CreateVueAppFunction = async () => { setupDevtools(app, globalComputed) } + // provide client data + for (const [key, value] of clientDataMap) { + app.provide(key, value) + } + // invoke all client enhance for (const clientConfig of clientConfigs) { await clientConfig.enhance?.({ app, router, siteData }) diff --git a/packages/client/src/composables/clientData.ts b/packages/client/src/composables/clientData.ts new file mode 100644 index 0000000000..cc09150723 --- /dev/null +++ b/packages/client/src/composables/clientData.ts @@ -0,0 +1,15 @@ +import { inject } from 'vue' +import type { InjectionKey } from 'vue' + +export const useClientData = ( + key: InjectionKey, + required?: U, +): U extends true ? T : T | undefined => { + const result = inject(key) + + if (required && !result) { + throw new Error(`Can not found ${key} in clientData()`) + } + + return result as U extends true ? T : T | undefined +} diff --git a/packages/client/src/composables/index.ts b/packages/client/src/composables/index.ts index 838b38b191..4253ac28d4 100644 --- a/packages/client/src/composables/index.ts +++ b/packages/client/src/composables/index.ts @@ -1,3 +1,4 @@ +export * from './clientData.js' export * from './layouts.js' export * from './pageData.js' export * from './pageFrontmatter.js' diff --git a/packages/client/src/helpers/defineClientData.ts b/packages/client/src/helpers/defineClientData.ts new file mode 100644 index 0000000000..6537e528be --- /dev/null +++ b/packages/client/src/helpers/defineClientData.ts @@ -0,0 +1,14 @@ +import type { InjectionKey } from 'vue' + +export const clientDataMap = new Map, unknown>() + +/** + * A helper function to help you define vuepress client data + */ +export const defineClientData = ( + key: InjectionKey, + data: T, + overrideExisting = true, +): void => { + if (overrideExisting || !clientDataMap.has(key)) clientDataMap.set(key, data) +} diff --git a/packages/client/src/helpers/index.ts b/packages/client/src/helpers/index.ts index e5726afa68..223b916e0a 100644 --- a/packages/client/src/helpers/index.ts +++ b/packages/client/src/helpers/index.ts @@ -1,2 +1,3 @@ export * from './defineClientConfig.js' +export * from './defineClientData.js' export * from './withBase.js'