Skip to content

Commit 373decb

Browse files
committed
feat: remove component proxy
1 parent 36acc2b commit 373decb

File tree

6 files changed

+53
-53
lines changed

6 files changed

+53
-53
lines changed

packages/compiler-core/src/runtimeHelpers.ts

+4
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,15 @@ export const PUSH_SCOPE_ID = Symbol(__DEV__ ? `pushScopeId` : ``)
2727
export const POP_SCOPE_ID = Symbol(__DEV__ ? `popScopeId` : ``)
2828
export const WITH_SCOPE_ID = Symbol(__DEV__ ? `withScopeId` : ``)
2929
export const WITH_CTX = Symbol(__DEV__ ? `withCtx` : ``)
30+
export const PUBLIC_INSTANCE_HANDLERS = Symbol(
31+
__DEV__ ? `PublicInstanceHandlers` : ``
32+
)
3033

3134
// Name mapping for runtime helpers that need to be imported from 'vue' in
3235
// generated code. Make sure these are correctly exported in the runtime!
3336
// Using `any` here because TS doesn't allow symbols as index type.
3437
export const helperNameMap: any = {
38+
[PUBLIC_INSTANCE_HANDLERS]: `PublicInstanceHandlers`,
3539
[FRAGMENT]: `Fragment`,
3640
[TELEPORT]: `Teleport`,
3741
[SUSPENSE]: `Suspense`,

packages/compiler-core/src/transforms/transformExpression.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import {
3131
import { createCompilerError, ErrorCodes } from '../errors'
3232
import { Node, Function, Identifier, ObjectProperty } from '@babel/types'
3333
import { validateBrowserExpression } from '../validateExpression'
34+
import { PUBLIC_INSTANCE_HANDLERS } from '@vue/compiler-core'
3435

3536
const isLiteralWhitelisted = /*#__PURE__*/ makeMap('true,false,null,this')
3637

@@ -102,10 +103,9 @@ export function processExpression(
102103

103104
const { bindingMetadata } = context
104105
const prefix = (raw: string) => {
105-
const source = hasOwn(bindingMetadata, raw)
106-
? `$` + bindingMetadata[raw]
107-
: `_ctx`
108-
return `${source}.${raw}`
106+
return hasOwn(bindingMetadata, raw)
107+
? `${bindingMetadata[raw]}.${raw}`
108+
: `_PublicInstanceHandlers.get(_ctx, "${raw}")`
109109
}
110110

111111
// fast path if expression is a simple identifier.
@@ -119,6 +119,7 @@ export function processExpression(
119119
!isGloballyWhitelisted(rawExp) &&
120120
!isLiteralWhitelisted(rawExp)
121121
) {
122+
context.helper(PUBLIC_INSTANCE_HANDLERS)
122123
node.content = prefix(rawExp)
123124
} else if (!context.identifiers[rawExp] && !bailConstant) {
124125
// mark node constant for hoisting unless it's referring a scope variable
@@ -169,6 +170,7 @@ export function processExpression(
169170
// rewrite the value
170171
node.prefix = `${node.name}: `
171172
}
173+
context.helper(PUBLIC_INSTANCE_HANDLERS)
172174
node.name = prefix(node.name)
173175
ids.push(node)
174176
} else if (!isStaticPropertyKey(node, parent)) {

packages/runtime-core/src/component.ts

+3-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { VNode, VNodeChild, isVNode } from './vnode'
22
import {
3-
reactive,
43
ReactiveEffect,
54
pauseTracking,
65
resetTracking,
@@ -9,8 +8,6 @@ import {
98
import {
109
CreateComponentPublicInstance,
1110
ComponentPublicInstance,
12-
PublicInstanceProxyHandlers,
13-
RuntimeCompiledPublicInstanceProxyHandlers,
1411
createRenderContext,
1512
exposePropsOnRenderContext,
1613
exposeSetupStateOnRenderContext
@@ -473,7 +470,7 @@ function setupStatefulComponent(
473470
instance.accessCache = {}
474471
// 1. create public instance / render proxy
475472
// also mark it raw so it's never observed
476-
instance.proxy = new Proxy(instance.ctx, PublicInstanceProxyHandlers)
473+
instance.proxy = instance.ctx as any
477474
if (__DEV__) {
478475
exposePropsOnRenderContext(instance)
479476
}
@@ -535,7 +532,7 @@ export function handleSetupResult(
535532
}
536533
// setup returned bindings.
537534
// assuming a render function compiled from template is present.
538-
instance.setupState = reactive(setupResult)
535+
instance.setupState = setupResult
539536
if (__DEV__) {
540537
exposeSetupStateOnRenderContext(instance)
541538
}
@@ -615,10 +612,7 @@ function finishComponentSetup(
615612
// proxy used needs a different `has` handler which is more performant and
616613
// also only allows a whitelist of globals to fallthrough.
617614
if (instance.render._rc) {
618-
instance.withProxy = new Proxy(
619-
instance.ctx,
620-
RuntimeCompiledPublicInstanceProxyHandlers
621-
)
615+
instance.withProxy = instance.ctx as any
622616
}
623617
}
624618

packages/runtime-core/src/componentProxy.ts

+35-39
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ import {
1515
shallowReadonly,
1616
ReactiveFlags,
1717
track,
18-
TrackOpTypes
18+
TrackOpTypes,
19+
unref
1920
} from '@vue/reactivity'
2021
import {
2122
ExtractComputedReturns,
@@ -198,8 +199,8 @@ export interface ComponentRenderContext {
198199
_: ComponentInternalInstance
199200
}
200201

201-
export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
202-
get({ _: instance }: ComponentRenderContext, key: string) {
202+
export class PublicInstanceHandlers {
203+
static get({ _: instance }: ComponentRenderContext, key: string) {
203204
const {
204205
ctx,
205206
setupState,
@@ -227,7 +228,7 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
227228
if (n !== undefined) {
228229
switch (n) {
229230
case AccessTypes.SETUP:
230-
return setupState[key]
231+
return unref(setupState[key])
231232
case AccessTypes.DATA:
232233
return data[key]
233234
case AccessTypes.CONTEXT:
@@ -238,7 +239,7 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
238239
}
239240
} else if (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) {
240241
accessCache![key] = AccessTypes.SETUP
241-
return setupState[key]
242+
return unref(setupState[key])
242243
} else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
243244
accessCache![key] = AccessTypes.DATA
244245
return data[key]
@@ -304,9 +305,9 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
304305
)
305306
}
306307
}
307-
},
308+
}
308309

309-
set(
310+
static set(
310311
{ _: instance }: ComponentRenderContext,
311312
key: string,
312313
value: any
@@ -344,9 +345,9 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
344345
}
345346
}
346347
return true
347-
},
348+
}
348349

349-
has(
350+
static has(
350351
{
351352
_: { data, setupState, accessCache, ctx, type, appContext }
352353
}: ComponentRenderContext,
@@ -366,40 +367,35 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
366367
}
367368
}
368369

369-
if (__DEV__ && !__TEST__) {
370-
PublicInstanceProxyHandlers.ownKeys = (target: ComponentRenderContext) => {
371-
warn(
372-
`Avoid app logic that relies on enumerating keys on a component instance. ` +
373-
`The keys will be empty in production mode to avoid performance overhead.`
374-
)
375-
return Reflect.ownKeys(target)
370+
export class RuntimeCompiledPublicInstanceHandlers {
371+
static set(
372+
instance: ComponentRenderContext,
373+
key: string,
374+
value: any
375+
): boolean {
376+
return PublicInstanceHandlers.set(instance, key, value)
376377
}
377-
}
378378

379-
export const RuntimeCompiledPublicInstanceProxyHandlers = extend(
380-
{},
381-
PublicInstanceProxyHandlers,
382-
{
383-
get(target: ComponentRenderContext, key: string) {
384-
// fast path for unscopables when using `with` block
385-
if ((key as any) === Symbol.unscopables) {
386-
return
387-
}
388-
return PublicInstanceProxyHandlers.get!(target, key, target)
389-
},
390-
has(_: ComponentRenderContext, key: string) {
391-
const has = key[0] !== '_' && !isGloballyWhitelisted(key)
392-
if (__DEV__ && !has && PublicInstanceProxyHandlers.has!(_, key)) {
393-
warn(
394-
`Property ${JSON.stringify(
395-
key
396-
)} should not start with _ which is a reserved prefix for Vue internals.`
397-
)
398-
}
399-
return has
379+
static get(target: ComponentRenderContext, key: string) {
380+
// fast path for unscopables when using `with` block
381+
if ((key as any) === Symbol.unscopables) {
382+
return
400383
}
384+
return PublicInstanceHandlers.get(target, key)
401385
}
402-
)
386+
387+
static has(_: ComponentRenderContext, key: string) {
388+
const has = key[0] !== '_' && !isGloballyWhitelisted(key)
389+
if (__DEV__ && !has && PublicInstanceHandlers.has(_, key)) {
390+
warn(
391+
`Property ${JSON.stringify(
392+
key
393+
)} should not start with _ which is a reserved prefix for Vue internals.`
394+
)
395+
}
396+
return has
397+
}
398+
}
403399

404400
// In dev mode, the proxy target exposes the same properties as seen on `this`
405401
// for easier console inspection. In prod mode it will be an empty object so

packages/runtime-core/src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ export {
168168
RenderFunction
169169
} from './componentOptions'
170170
export {
171+
PublicInstanceHandlers,
171172
ComponentPublicInstance,
172173
ComponentCustomProperties
173174
} from './componentProxy'

packages/runtime-core/src/renderer.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,10 @@ export const setRef = (
320320
refs[ref] = value
321321
if (hasOwn(setupState, ref)) {
322322
queuePostRenderEffect(() => {
323-
setupState[ref] = value
323+
const setupStateRef = setupState[ref]
324+
if (isRef(setupStateRef)) {
325+
setupStateRef.value = value
326+
}
324327
}, parentSuspense)
325328
}
326329
} else if (isRef(ref)) {

0 commit comments

Comments
 (0)