diff --git a/packages/runtime-core/src/index.ts b/packages/runtime-core/src/index.ts index d49872882..8adbe91ee 100644 --- a/packages/runtime-core/src/index.ts +++ b/packages/runtime-core/src/index.ts @@ -363,7 +363,11 @@ export { transformVNodeArgs } from './vnode' // **IMPORTANT** These APIs are exposed solely for @vue/server-renderer and may // change without notice between versions. User code should never rely on them. -import { createComponentInstance, setupComponent } from './component' +import { + createComponentInstance, + getComponentPublicInstance, + setupComponent, +} from './component' import { renderComponentRoot } from './componentRenderUtils' import { setCurrentRenderingInstance } from './componentRenderContext' import { isVNode, normalizeVNode } from './vnode' @@ -375,6 +379,7 @@ const _ssrUtils = { setCurrentRenderingInstance, isVNode, normalizeVNode, + getComponentPublicInstance, } /** diff --git a/packages/server-renderer/__tests__/ssrDirectives.spec.ts b/packages/server-renderer/__tests__/ssrDirectives.spec.ts index d3ced89b3..dfdebe971 100644 --- a/packages/server-renderer/__tests__/ssrDirectives.spec.ts +++ b/packages/server-renderer/__tests__/ssrDirectives.spec.ts @@ -2,7 +2,10 @@ import { renderToString } from '../src/renderToString' import { createApp, h, + mergeProps, + ref, resolveDirective, + unref, vModelCheckbox, vModelDynamic, vModelRadio, @@ -542,4 +545,44 @@ describe('ssr: directives', () => { ), ).toBe(`
`) }) + + // #7499 + test('custom directive w/ getSSRProps (expose)', async () => { + let exposeVars: null | string | undefined = null + const useTestDirective = () => ({ + vTest: { + getSSRProps({ instance }: any) { + if (instance) { + exposeVars = instance.x + } + return { id: exposeVars } + }, + }, + }) + const { vTest } = useTestDirective() + + const renderString = await renderToString( + createApp({ + setup(props, { expose }) { + const x = ref('foo') + expose({ x }) + const __returned__ = { useTestDirective, vTest, ref, x } + Object.defineProperty(__returned__, '__isScriptSetup', { + enumerable: false, + value: true, + }) + return __returned__ + }, + ssrRender(_ctx, _push, _parent, _attrs) { + _push( + ``, + ) + }, + }), + ) + expect(renderString).toBe(``) + expect(exposeVars).toBe('foo') + }) }) diff --git a/packages/server-renderer/src/helpers/ssrGetDirectiveProps.ts b/packages/server-renderer/src/helpers/ssrGetDirectiveProps.ts index 094d8564f..877c01d36 100644 --- a/packages/server-renderer/src/helpers/ssrGetDirectiveProps.ts +++ b/packages/server-renderer/src/helpers/ssrGetDirectiveProps.ts @@ -1,4 +1,8 @@ -import type { ComponentPublicInstance, Directive } from '@vue/runtime-core' +import { + type ComponentPublicInstance, + type Directive, + ssrUtils, +} from '@vue/runtime-core' export function ssrGetDirectiveProps( instance: ComponentPublicInstance, @@ -12,7 +16,7 @@ export function ssrGetDirectiveProps( dir.getSSRProps( { dir, - instance, + instance: ssrUtils.getComponentPublicInstance(instance.$), value, oldValue: undefined, arg,