fix(runtime-core): ensure custom directive instance properly exposes properties on closed instances. (#5022)

fix #5018
This commit is contained in:
Thorsten Lünborg 2022-04-12 09:54:03 +02:00 committed by GitHub
parent 0a301d4dab
commit f44087e171
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 3 deletions

View File

@ -7,7 +7,8 @@ import {
DirectiveHook, DirectiveHook,
VNode, VNode,
DirectiveBinding, DirectiveBinding,
nextTick nextTick,
defineComponent
} from '@vue/runtime-test' } from '@vue/runtime-test'
import { currentInstance, ComponentInternalInstance } from '../src/component' import { currentInstance, ComponentInternalInstance } from '../src/component'
@ -395,4 +396,29 @@ describe('directives', () => {
expect(beforeUpdate).toHaveBeenCalledTimes(1) expect(beforeUpdate).toHaveBeenCalledTimes(1)
expect(count.value).toBe(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')
})
}) })

View File

@ -14,7 +14,7 @@ return withDirectives(h(comp), [
import { VNode } from './vnode' import { VNode } from './vnode'
import { isFunction, EMPTY_OBJ, isBuiltInDirective } from '@vue/shared' import { isFunction, EMPTY_OBJ, isBuiltInDirective } from '@vue/shared'
import { warn } from './warning' import { warn } from './warning'
import { ComponentInternalInstance, Data } from './component' import { ComponentInternalInstance, Data, getExposeProxy } from './component'
import { currentRenderingInstance } from './componentRenderContext' import { currentRenderingInstance } from './componentRenderContext'
import { callWithAsyncErrorHandling, ErrorCodes } from './errorHandling' import { callWithAsyncErrorHandling, ErrorCodes } from './errorHandling'
import { ComponentPublicInstance } from './componentPublicInstance' import { ComponentPublicInstance } from './componentPublicInstance'
@ -89,7 +89,9 @@ export function withDirectives<T extends VNode>(
__DEV__ && warn(`withDirectives can only be used inside render functions.`) __DEV__ && warn(`withDirectives can only be used inside render functions.`)
return vnode return vnode
} }
const instance = internalInstance.proxy const instance =
(getExposeProxy(internalInstance) as ComponentPublicInstance) ||
internalInstance.proxy
const bindings: DirectiveBinding[] = vnode.dirs || (vnode.dirs = []) const bindings: DirectiveBinding[] = vnode.dirs || (vnode.dirs = [])
for (let i = 0; i < directives.length; i++) { for (let i = 0; i < directives.length; i++) {
let [dir, value, arg, modifiers = EMPTY_OBJ] = directives[i] let [dir, value, arg, modifiers = EMPTY_OBJ] = directives[i]