Skip to content

Commit 52cc7e8

Browse files
committed
refactor(directives): remove binding.instance
BREAKING CHANGE: custom directive bindings no longer expose instance This is a rarely used property that creates extra complexity in ensuring it points to the correct instance. From a design perspective, a custom directive should be scoped to the element and data it is bound to and should not have access to the entire instance in the first place.
1 parent 3eab143 commit 52cc7e8

File tree

2 files changed

+2
-27
lines changed

2 files changed

+2
-27
lines changed

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

-16
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import {
99
DirectiveBinding,
1010
nextTick
1111
} from '@vue/runtime-test'
12-
import { currentInstance, ComponentInternalInstance } from '../src/component'
1312

1413
describe('directives', () => {
1514
it('should work', async () => {
@@ -18,7 +17,6 @@ describe('directives', () => {
1817
function assertBindings(binding: DirectiveBinding) {
1918
expect(binding.value).toBe(count.value)
2019
expect(binding.arg).toBe('foo')
21-
expect(binding.instance).toBe(_instance && _instance.proxy)
2220
expect(binding.modifiers && binding.modifiers.ok).toBe(true)
2321
}
2422

@@ -107,13 +105,9 @@ describe('directives', () => {
107105
unmounted
108106
}
109107

110-
let _instance: ComponentInternalInstance | null = null
111108
let _vnode: VNode | null = null
112109
let _prevVnode: VNode | null = null
113110
const Comp = {
114-
setup() {
115-
_instance = currentInstance
116-
},
117111
render() {
118112
_prevVnode = _vnode
119113
_vnode = withDirectives(h('div', count.value), [
@@ -153,7 +147,6 @@ describe('directives', () => {
153147
function assertBindings(binding: DirectiveBinding) {
154148
expect(binding.value).toBe(count.value)
155149
expect(binding.arg).toBe('foo')
156-
expect(binding.instance).toBe(_instance && _instance.proxy)
157150
expect(binding.modifiers && binding.modifiers.ok).toBe(true)
158151
}
159152

@@ -167,13 +160,9 @@ describe('directives', () => {
167160
expect(prevVNode).toBe(_prevVnode)
168161
}) as DirectiveHook)
169162

170-
let _instance: ComponentInternalInstance | null = null
171163
let _vnode: VNode | null = null
172164
let _prevVnode: VNode | null = null
173165
const Comp = {
174-
setup() {
175-
_instance = currentInstance
176-
},
177166
render() {
178167
_prevVnode = _vnode
179168
_vnode = withDirectives(h('div', count.value), [
@@ -207,7 +196,6 @@ describe('directives', () => {
207196
function assertBindings(binding: DirectiveBinding) {
208197
expect(binding.value).toBe(count.value)
209198
expect(binding.arg).toBe('foo')
210-
expect(binding.instance).toBe(_instance && _instance.proxy)
211199
expect(binding.modifiers && binding.modifiers.ok).toBe(true)
212200
}
213201

@@ -296,7 +284,6 @@ describe('directives', () => {
296284
unmounted
297285
}
298286

299-
let _instance: ComponentInternalInstance | null = null
300287
let _vnode: VNode | null = null
301288
let _prevVnode: VNode | null = null
302289

@@ -307,9 +294,6 @@ describe('directives', () => {
307294
}
308295

309296
const Comp = {
310-
setup() {
311-
_instance = currentInstance
312-
},
313297
render() {
314298
return withDirectives(h(Child, { count: count.value }), [
315299
[

packages/runtime-core/src/directives.ts

+2-11
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,9 @@ import { VNode } from './vnode'
1515
import { isFunction, EMPTY_OBJ, makeMap, EMPTY_ARR } from '@vue/shared'
1616
import { warn } from './warning'
1717
import { ComponentInternalInstance } from './component'
18-
import { currentRenderingInstance } from './componentRenderUtils'
1918
import { callWithAsyncErrorHandling, ErrorCodes } from './errorHandling'
20-
import { ComponentPublicInstance } from './componentProxy'
2119

2220
export interface DirectiveBinding {
23-
instance: ComponentPublicInstance | null
2421
value: any
2522
oldValue: any
2623
arg?: string
@@ -108,14 +105,9 @@ export function withDirectives<T extends VNode>(
108105
vnode: T,
109106
directives: DirectiveArguments
110107
): T {
111-
const internalInstance = currentRenderingInstance
112-
if (internalInstance === null) {
113-
__DEV__ && warn(`withDirectives can only be used inside render functions.`)
114-
return vnode
115-
}
116-
const instance = internalInstance.proxy
117108
const props = vnode.props || (vnode.props = {})
118-
const bindings = vnode.dirs || (vnode.dirs = new Array(directives.length))
109+
const bindings: DirectiveBinding[] =
110+
vnode.dirs || (vnode.dirs = new Array(directives.length))
119111
const injected: Record<string, true> = {}
120112
for (let i = 0; i < directives.length; i++) {
121113
let [dir, value, arg, modifiers = EMPTY_OBJ] = directives[i]
@@ -127,7 +119,6 @@ export function withDirectives<T extends VNode>(
127119
}
128120
bindings[i] = {
129121
dir,
130-
instance,
131122
value,
132123
oldValue: void 0,
133124
arg,

0 commit comments

Comments
 (0)