Skip to content

Commit 12e6d2d

Browse files
committed
fix(runtime-core): ensure that binding.instance in custom directive hooks properly exposes properties on closed instances.
1 parent 2d4f455 commit 12e6d2d

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

packages/runtime-core/__tests__/directives.spec.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import {
77
DirectiveHook,
88
VNode,
99
DirectiveBinding,
10-
nextTick
10+
nextTick,
11+
defineComponent
1112
} from '@vue/runtime-test'
1213
import { currentInstance, ComponentInternalInstance } from '../src/component'
1314

@@ -395,4 +396,29 @@ describe('directives', () => {
395396
expect(beforeUpdate).toHaveBeenCalledTimes(1)
396397
expect(count.value).toBe(1)
397398
})
399+
400+
test('should receive exposeProxy for closed instances', async () => {
401+
let res: string
402+
const App = defineComponent({
403+
setup(_, { expose }) {
404+
expose({
405+
msg: 'Test'
406+
})
407+
408+
return () =>
409+
withDirectives(h('p', 'Lore Ipsum'), [
410+
[
411+
{
412+
mounted(el, { instance }) {
413+
res = (instance as any).msg as string
414+
}
415+
}
416+
]
417+
])
418+
}
419+
})
420+
const root = nodeOps.createElement('div')
421+
render(h(App), root)
422+
expect(res!).toBe('Test')
423+
})
398424
})

packages/runtime-core/src/directives.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ return withDirectives(h(comp), [
1414
import { VNode } from './vnode'
1515
import { isFunction, EMPTY_OBJ, makeMap } from '@vue/shared'
1616
import { warn } from './warning'
17-
import { ComponentInternalInstance, Data } from './component'
17+
import { ComponentInternalInstance, Data, getExposeProxy } from './component'
1818
import { currentRenderingInstance } from './componentRenderContext'
1919
import { callWithAsyncErrorHandling, ErrorCodes } from './errorHandling'
2020
import { ComponentPublicInstance } from './componentPublicInstance'
@@ -93,7 +93,9 @@ export function withDirectives<T extends VNode>(
9393
__DEV__ && warn(`withDirectives can only be used inside render functions.`)
9494
return vnode
9595
}
96-
const instance = internalInstance.proxy
96+
const instance =
97+
(getExposeProxy(internalInstance) as ComponentPublicInstance) ||
98+
internalInstance.proxy
9799
const bindings: DirectiveBinding[] = vnode.dirs || (vnode.dirs = [])
98100
for (let i = 0; i < directives.length; i++) {
99101
let [dir, value, arg, modifiers = EMPTY_OBJ] = directives[i]

0 commit comments

Comments
 (0)