Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
fix(runtime-core): ensure custom directive instance properly exposes …
…properties on closed instances. (#5022)

fix #5018
  • Loading branch information
LinusBorg committed Apr 12, 2022
1 parent 0a301d4 commit f44087e
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 3 deletions.
28 changes: 27 additions & 1 deletion packages/runtime-core/__tests__/directives.spec.ts
Expand Up @@ -7,7 +7,8 @@ import {
DirectiveHook,
VNode,
DirectiveBinding,
nextTick
nextTick,
defineComponent
} from '@vue/runtime-test'
import { currentInstance, ComponentInternalInstance } from '../src/component'

Expand Down Expand Up @@ -395,4 +396,29 @@ describe('directives', () => {
expect(beforeUpdate).toHaveBeenCalledTimes(1)
expect(count.value).toBe(1)
})

test('should receive exposeProxy for closed instances', async () => {
let res: string
const App = defineComponent({
setup(_, { expose }) {
expose({
msg: 'Test'
})

return () =>
withDirectives(h('p', 'Lore Ipsum'), [
[
{
mounted(el, { instance }) {
res = (instance as any).msg as string
}
}
]
])
}
})
const root = nodeOps.createElement('div')
render(h(App), root)
expect(res!).toBe('Test')
})
})
6 changes: 4 additions & 2 deletions packages/runtime-core/src/directives.ts
Expand Up @@ -14,7 +14,7 @@ return withDirectives(h(comp), [
import { VNode } from './vnode'
import { isFunction, EMPTY_OBJ, isBuiltInDirective } from '@vue/shared'
import { warn } from './warning'
import { ComponentInternalInstance, Data } from './component'
import { ComponentInternalInstance, Data, getExposeProxy } from './component'
import { currentRenderingInstance } from './componentRenderContext'
import { callWithAsyncErrorHandling, ErrorCodes } from './errorHandling'
import { ComponentPublicInstance } from './componentPublicInstance'
Expand Down Expand Up @@ -89,7 +89,9 @@ export function withDirectives<T extends VNode>(
__DEV__ && warn(`withDirectives can only be used inside render functions.`)
return vnode
}
const instance = internalInstance.proxy
const instance =
(getExposeProxy(internalInstance) as ComponentPublicInstance) ||
internalInstance.proxy
const bindings: DirectiveBinding[] = vnode.dirs || (vnode.dirs = [])
for (let i = 0; i < directives.length; i++) {
let [dir, value, arg, modifiers = EMPTY_OBJ] = directives[i]
Expand Down

0 comments on commit f44087e

Please sign in to comment.