fix(ssr): directive binding.instance should respect exposed during ssr

close #7499
close #7502
This commit is contained in:
Evan You 2024-06-10 17:46:59 +08:00
parent 9daf90e29f
commit df686abb4f
No known key found for this signature in database
GPG Key ID: B9D421896CA450FB
3 changed files with 55 additions and 3 deletions

View File

@ -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,
}
/**

View File

@ -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(`<div id="foo-arg-true"></div>`)
})
// #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(
`<div${ssrRenderAttrs(
mergeProps(_attrs!, ssrGetDirectiveProps(_ctx, unref(vTest))),
)}></div>`,
)
},
}),
)
expect(renderString).toBe(`<div id="foo"></div>`)
expect(exposeVars).toBe('foo')
})
})

View File

@ -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,