Revert "refactor(directives): remove binding.instance"

This reverts commit 52cc7e8231.
This commit is contained in:
Evan You 2020-03-16 12:47:49 -04:00
parent 19228a469a
commit 23701666cb
2 changed files with 27 additions and 2 deletions

View File

@ -9,6 +9,7 @@ import {
DirectiveBinding, DirectiveBinding,
nextTick nextTick
} from '@vue/runtime-test' } from '@vue/runtime-test'
import { currentInstance, ComponentInternalInstance } from '../src/component'
describe('directives', () => { describe('directives', () => {
it('should work', async () => { it('should work', async () => {
@ -17,6 +18,7 @@ describe('directives', () => {
function assertBindings(binding: DirectiveBinding) { function assertBindings(binding: DirectiveBinding) {
expect(binding.value).toBe(count.value) expect(binding.value).toBe(count.value)
expect(binding.arg).toBe('foo') expect(binding.arg).toBe('foo')
expect(binding.instance).toBe(_instance && _instance.proxy)
expect(binding.modifiers && binding.modifiers.ok).toBe(true) expect(binding.modifiers && binding.modifiers.ok).toBe(true)
} }
@ -105,9 +107,13 @@ describe('directives', () => {
unmounted unmounted
} }
let _instance: ComponentInternalInstance | null = null
let _vnode: VNode | null = null let _vnode: VNode | null = null
let _prevVnode: VNode | null = null let _prevVnode: VNode | null = null
const Comp = { const Comp = {
setup() {
_instance = currentInstance
},
render() { render() {
_prevVnode = _vnode _prevVnode = _vnode
_vnode = withDirectives(h('div', count.value), [ _vnode = withDirectives(h('div', count.value), [
@ -147,6 +153,7 @@ describe('directives', () => {
function assertBindings(binding: DirectiveBinding) { function assertBindings(binding: DirectiveBinding) {
expect(binding.value).toBe(count.value) expect(binding.value).toBe(count.value)
expect(binding.arg).toBe('foo') expect(binding.arg).toBe('foo')
expect(binding.instance).toBe(_instance && _instance.proxy)
expect(binding.modifiers && binding.modifiers.ok).toBe(true) expect(binding.modifiers && binding.modifiers.ok).toBe(true)
} }
@ -160,9 +167,13 @@ describe('directives', () => {
expect(prevVNode).toBe(_prevVnode) expect(prevVNode).toBe(_prevVnode)
}) as DirectiveHook) }) as DirectiveHook)
let _instance: ComponentInternalInstance | null = null
let _vnode: VNode | null = null let _vnode: VNode | null = null
let _prevVnode: VNode | null = null let _prevVnode: VNode | null = null
const Comp = { const Comp = {
setup() {
_instance = currentInstance
},
render() { render() {
_prevVnode = _vnode _prevVnode = _vnode
_vnode = withDirectives(h('div', count.value), [ _vnode = withDirectives(h('div', count.value), [
@ -196,6 +207,7 @@ describe('directives', () => {
function assertBindings(binding: DirectiveBinding) { function assertBindings(binding: DirectiveBinding) {
expect(binding.value).toBe(count.value) expect(binding.value).toBe(count.value)
expect(binding.arg).toBe('foo') expect(binding.arg).toBe('foo')
expect(binding.instance).toBe(_instance && _instance.proxy)
expect(binding.modifiers && binding.modifiers.ok).toBe(true) expect(binding.modifiers && binding.modifiers.ok).toBe(true)
} }
@ -284,6 +296,7 @@ describe('directives', () => {
unmounted unmounted
} }
let _instance: ComponentInternalInstance | null = null
let _vnode: VNode | null = null let _vnode: VNode | null = null
let _prevVnode: VNode | null = null let _prevVnode: VNode | null = null
@ -294,6 +307,9 @@ describe('directives', () => {
} }
const Comp = { const Comp = {
setup() {
_instance = currentInstance
},
render() { render() {
return withDirectives(h(Child, { count: count.value }), [ return withDirectives(h(Child, { count: count.value }), [
[ [

View File

@ -15,9 +15,12 @@ import { VNode } from './vnode'
import { isFunction, EMPTY_OBJ, makeMap, EMPTY_ARR } from '@vue/shared' import { isFunction, EMPTY_OBJ, makeMap, EMPTY_ARR } from '@vue/shared'
import { warn } from './warning' import { warn } from './warning'
import { ComponentInternalInstance } from './component' import { ComponentInternalInstance } from './component'
import { currentRenderingInstance } from './componentRenderUtils'
import { callWithAsyncErrorHandling, ErrorCodes } from './errorHandling' import { callWithAsyncErrorHandling, ErrorCodes } from './errorHandling'
import { ComponentPublicInstance } from './componentProxy'
export interface DirectiveBinding { export interface DirectiveBinding {
instance: ComponentPublicInstance | null
value: any value: any
oldValue: any oldValue: any
arg?: string arg?: string
@ -105,9 +108,14 @@ export function withDirectives<T extends VNode>(
vnode: T, vnode: T,
directives: DirectiveArguments directives: DirectiveArguments
): T { ): T {
const internalInstance = currentRenderingInstance
if (internalInstance === null) {
__DEV__ && warn(`withDirectives can only be used inside render functions.`)
return vnode
}
const instance = internalInstance.proxy
const props = vnode.props || (vnode.props = {}) const props = vnode.props || (vnode.props = {})
const bindings: DirectiveBinding[] = const bindings = vnode.dirs || (vnode.dirs = new Array(directives.length))
vnode.dirs || (vnode.dirs = new Array(directives.length))
const injected: Record<string, true> = {} const injected: Record<string, true> = {}
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]
@ -119,6 +127,7 @@ export function withDirectives<T extends VNode>(
} }
bindings[i] = { bindings[i] = {
dir, dir,
instance,
value, value,
oldValue: void 0, oldValue: void 0,
arg, arg,