Skip to content

Commit

Permalink
refactor(runtime-core): remove need for internal instance sink
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Apr 16, 2020
1 parent 4d014dc commit 24e5ab3
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 38 deletions.
10 changes: 5 additions & 5 deletions packages/runtime-core/__tests__/componentProxy.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ describe('component: proxy', () => {
expect(`Attempting to mutate public property "$data"`).toHaveBeenWarned()
})

test('sink', async () => {
test('user attached properties', async () => {
let instance: ComponentInternalInstance
let instanceProxy: any
const Comp = {
Expand All @@ -116,7 +116,7 @@ describe('component: proxy', () => {
render(h(Comp), nodeOps.createElement('div'))
instanceProxy.foo = 1
expect(instanceProxy.foo).toBe(1)
expect(instance!.sink.foo).toBe(1)
expect(instance!.proxyTarget.foo).toBe(1)
})

test('globalProperties', () => {
Expand All @@ -140,8 +140,8 @@ describe('component: proxy', () => {

// set should overwrite globalProperties with local
instanceProxy.foo = 2
expect(instanceProxy.foo).toBe(2)
expect(instance!.sink.foo).toBe(2)
// expect(instanceProxy.foo).toBe(2)
expect(instance!.proxyTarget.foo).toBe(2)
// should not affect global
expect(app.config.globalProperties.foo).toBe(1)
})
Expand Down Expand Up @@ -188,7 +188,7 @@ describe('component: proxy', () => {
expect('$foobar' in instanceProxy).toBe(false)
expect('baz' in instanceProxy).toBe(false)

// set non-existent (goes into sink)
// set non-existent (goes into proxyTarget sink)
instanceProxy.baz = 1
expect('baz' in instanceProxy).toBe(true)

Expand Down
12 changes: 5 additions & 7 deletions packages/runtime-core/src/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,11 @@ export interface ComponentInternalInstance {
attrs: Data
slots: InternalSlots
proxy: ComponentPublicInstance | null
// The target object for the public instance proxy. In dev mode, we also
// define getters for all known instance properties on it so it can be
// properly inspected in the console. These getters are skipped in prod mode
// for performance. In addition, any user attached properties
// (via `this.x = ...`) are also stored on this object.
proxyTarget: ComponentPublicProxyTarget
// alternative proxy used only for runtime-compiled render functions using
// `with` block
Expand All @@ -156,9 +161,6 @@ export interface ComponentInternalInstance {
asyncDep: Promise<any> | null
asyncResolved: boolean

// storage for any extra properties
sink: { [key: string]: any }

// lifecycle
isMounted: boolean
isUnmounted: boolean
Expand Down Expand Up @@ -230,10 +232,6 @@ export function createComponentInstance(
asyncDep: null,
asyncResolved: false,

// user namespace for storing whatever the user assigns to `this`
// can also be used as a wildcard storage for ad-hoc injections internally
sink: {},

// lifecycle hooks
// not using enums here because it results in computed properties
isMounted: false,
Expand Down
22 changes: 14 additions & 8 deletions packages/runtime-core/src/componentProxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
props,
accessCache,
type,
sink,
proxyTarget,
appContext
} = instance

Expand Down Expand Up @@ -136,16 +136,17 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
}
}

// public $xxx properties & user-attached properties (sink)
// public $xxx properties &
// user-attached properties (falls through to proxyTarget)
const publicGetter = publicPropertiesMap[key]
let cssModule, globalProperties
if (publicGetter) {
if (__DEV__ && key === '$attrs') {
markAttrsAccessed()
}
return publicGetter(instance)
} else if (hasOwn(sink, key)) {
return sink[key]
} else if (hasOwn(proxyTarget, key)) {
return proxyTarget[key]
} else if (
(cssModule = type.__cssModules) &&
(cssModule = cssModule[key])
Expand Down Expand Up @@ -190,8 +191,13 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
)
return false
} else {
instance.sink[key] = value
if (__DEV__) {
if (__DEV__ && key in instance.appContext.config.globalProperties) {
Object.defineProperty(instance.proxyTarget, key, {
configurable: true,
enumerable: true,
value
})
} else {
instance.proxyTarget[key] = value
}
}
Expand All @@ -200,7 +206,7 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {

has(
{
_: { data, accessCache, renderContext, type, sink, appContext }
_: { data, accessCache, renderContext, type, proxyTarget, appContext }
}: ComponentPublicProxyTarget,
key: string
) {
Expand All @@ -210,7 +216,7 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
hasOwn(renderContext, key) ||
(type.props && hasOwn(normalizePropsOptions(type.props)[0]!, key)) ||
hasOwn(publicPropertiesMap, key) ||
hasOwn(sink, key) ||
hasOwn(proxyTarget, key) ||
hasOwn(appContext.config.globalProperties, key)
)
}
Expand Down
23 changes: 11 additions & 12 deletions packages/runtime-core/src/components/KeepAlive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import {
invokeArrayFns
} from '@vue/shared'
import { watch } from '../apiWatch'
import { SuspenseBoundary } from './Suspense'
import {
RendererInternals,
queuePostRenderEffect,
Expand All @@ -27,6 +26,7 @@ import {
RendererNode
} from '../renderer'
import { setTransitionHooks } from './BaseTransition'
import { ComponentPublicProxyTarget } from '../componentProxy'

type MatchPattern = string | RegExp | string[] | RegExp[]

Expand All @@ -40,9 +40,8 @@ type CacheKey = string | number | Component
type Cache = Map<CacheKey, VNode>
type Keys = Set<CacheKey>

export interface KeepAliveSink {
export interface KeepAliveContext extends ComponentPublicProxyTarget {
renderer: RendererInternals
parentSuspense: SuspenseBoundary | null
activate: (
vnode: VNode,
container: RendererElement,
Expand Down Expand Up @@ -76,25 +75,25 @@ const KeepAliveImpl = {
let current: VNode | null = null

const instance = getCurrentInstance()!
const parentSuspense = instance.suspense

// KeepAlive communicates with the instantiated renderer via the "sink"
// where the renderer passes in platform-specific functions, and the
// KeepAlive instance exposes activate/deactivate implementations.
// KeepAlive communicates with the instantiated renderer via the proxyTarget
// as a shared context where the renderer passes in its internals,
// and the KeepAlive instance exposes activate/deactivate implementations.
// The whole point of this is to avoid importing KeepAlive directly in the
// renderer to facilitate tree-shaking.
const sink = instance.sink as KeepAliveSink
const sharedContext = instance.proxyTarget as KeepAliveContext
const {
renderer: {
p: patch,
m: move,
um: _unmount,
o: { createElement }
},
parentSuspense
} = sink
}
} = sharedContext
const storageContainer = createElement('div')

sink.activate = (vnode, container, anchor, isSVG, optimized) => {
sharedContext.activate = (vnode, container, anchor, isSVG, optimized) => {
const child = vnode.component!
move(vnode, container, anchor, MoveType.ENTER, parentSuspense)
// in case props have changed
Expand All @@ -116,7 +115,7 @@ const KeepAliveImpl = {
}, parentSuspense)
}

sink.deactivate = (vnode: VNode) => {
sharedContext.deactivate = (vnode: VNode) => {
move(vnode, storageContainer, null, MoveType.LEAVE, parentSuspense)
queuePostRenderEffect(() => {
const component = vnode.component!
Expand Down
10 changes: 4 additions & 6 deletions packages/runtime-core/src/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ import {
SuspenseImpl
} from './components/Suspense'
import { TeleportImpl } from './components/Teleport'
import { KeepAliveSink, isKeepAlive } from './components/KeepAlive'
import { isKeepAlive, KeepAliveContext } from './components/KeepAlive'
import { registerHMR, unregisterHMR } from './hmr'
import {
ErrorCodes,
Expand Down Expand Up @@ -949,7 +949,7 @@ function baseCreateRenderer(
) => {
if (n1 == null) {
if (n2.shapeFlag & ShapeFlags.COMPONENT_KEPT_ALIVE) {
;(parentComponent!.sink as KeepAliveSink).activate(
;(parentComponent!.proxyTarget as KeepAliveContext).activate(
n2,
container,
anchor,
Expand Down Expand Up @@ -998,9 +998,7 @@ function baseCreateRenderer(

// inject renderer internals for keepAlive
if (isKeepAlive(initialVNode)) {
const sink = instance.sink as KeepAliveSink
sink.renderer = internals
sink.parentSuspense = parentSuspense
;(instance.proxyTarget as KeepAliveContext).renderer = internals
}

// resolve props and slots for setup context
Expand Down Expand Up @@ -1721,7 +1719,7 @@ function baseCreateRenderer(

if (shapeFlag & ShapeFlags.COMPONENT) {
if (shapeFlag & ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE) {
;(parentComponent!.sink as KeepAliveSink).deactivate(vnode)
;(parentComponent!.proxyTarget as KeepAliveContext).deactivate(vnode)
} else {
unmountComponent(vnode.component!, parentSuspense, doRemove)
}
Expand Down

0 comments on commit 24e5ab3

Please sign in to comment.