]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
feat(runtime-core): allow inject() in custom directives linusborg/feat-set-currenInstance-for-dirs-5002 5036/head
authorThorsten Luenborg <t.luenborg@googlemail.com>
Sat, 4 Dec 2021 11:45:37 +0000 (12:45 +0100)
committerThorsten Luenborg <t.luenborg@googlemail.com>
Sat, 4 Dec 2021 11:45:37 +0000 (12:45 +0100)
Set currentInstance before hook calls

close: #5002

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

index 02d24711804773df53c3386024706cfaa7029bfe..ae0ed54d95678c3eba97e96b030b3bf0c9068c84 100644 (file)
@@ -7,7 +7,10 @@ import {
   DirectiveHook,
   VNode,
   DirectiveBinding,
-  nextTick
+  nextTick,
+  Directive,
+  ComponentPublicInstance,
+  getCurrentInstance
 } from '@vue/runtime-test'
 import { currentInstance, ComponentInternalInstance } from '../src/component'
 
@@ -395,4 +398,29 @@ describe('directives', () => {
     expect(beforeUpdate).toHaveBeenCalledTimes(1)
     expect(count.value).toBe(1)
   })
+
+  test('should have currentInstance available', async () => {
+    let instance: ComponentInternalInstance | null
+    let bindingInstance: ComponentPublicInstance | null
+    const beforeMount: Directive = (_, binding) => {
+      instance = getCurrentInstance()
+      bindingInstance = binding.instance
+    }
+    const App = {
+      render() {
+        return withDirectives(h('p', 'Test'), [
+          [
+            {
+              beforeMount
+            }
+          ]
+        ])
+      }
+    }
+
+    const root = nodeOps.createElement('div')
+    render(h(App), root)
+    expect(instance!).not.toBe(null)
+    expect(instance!.proxy).toBe(bindingInstance!)
+  })
 })
index ec13e951bccb8ba1f7ab1fa95ebea29bb4a1b71b..538dcd3612220e7e10c0b0748c27811c9b12f3ab 100644 (file)
@@ -14,7 +14,12 @@ return withDirectives(h(comp), [
 import { VNode } from './vnode'
 import { isFunction, EMPTY_OBJ, makeMap } from '@vue/shared'
 import { warn } from './warning'
-import { ComponentInternalInstance, Data } from './component'
+import {
+  ComponentInternalInstance,
+  Data,
+  setCurrentInstance,
+  unsetCurrentInstance
+} from './component'
 import { currentRenderingInstance } from './componentRenderContext'
 import { callWithAsyncErrorHandling, ErrorCodes } from './errorHandling'
 import { ComponentPublicInstance } from './componentPublicInstance'
@@ -139,12 +144,14 @@ export function invokeDirectiveHook(
       // disable tracking inside all lifecycle hooks
       // since they can potentially be called inside effects.
       pauseTracking()
+      instance && setCurrentInstance(instance)
       callWithAsyncErrorHandling(hook, instance, ErrorCodes.DIRECTIVE_HOOK, [
         vnode.el,
         binding,
         vnode,
         prevVNode
       ])
+      unsetCurrentInstance()
       resetTracking()
     }
   }