Skip to content

Commit b2662a6

Browse files
committed
wip: separate setupState
1 parent 0709380 commit b2662a6

File tree

4 files changed

+64
-41
lines changed

4 files changed

+64
-41
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ describe('component: proxy', () => {
3535
expect(instance!.data.foo).toBe(2)
3636
})
3737

38-
test('renderContext', () => {
38+
test('setupState', () => {
3939
let instance: ComponentInternalInstance
4040
let instanceProxy: any
4141
const Comp = {
@@ -55,7 +55,7 @@ describe('component: proxy', () => {
5555
render(h(Comp), nodeOps.createElement('div'))
5656
expect(instanceProxy.foo).toBe(1)
5757
instanceProxy.foo = 2
58-
expect(instance!.renderContext.foo).toBe(2)
58+
expect(instance!.setupState.foo).toBe(2)
5959
})
6060

6161
test('should not expose non-declared props', () => {

packages/runtime-core/src/component.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
RuntimeCompiledPublicInstanceProxyHandlers,
1414
createDevProxyTarget,
1515
exposePropsOnDevProxyTarget,
16-
exposeRenderContextOnDevProxyTarget
16+
exposeSetupStateOnDevProxyTarget
1717
} from './componentProxy'
1818
import { ComponentPropsOptions, initProps } from './componentProps'
1919
import { Slots, initSlots, InternalSlots } from './componentSlots'
@@ -143,6 +143,13 @@ export interface ComponentInternalInstance {
143143
attrs: Data
144144
slots: InternalSlots
145145
proxy: ComponentPublicInstance | null
146+
refs: Data
147+
emit: EmitFn
148+
149+
// setup
150+
setupState: Data
151+
setupContext: SetupContext | null
152+
146153
// The target object for the public instance proxy. In dev mode, we also
147154
// define getters for all known instance properties on it so it can be
148155
// properly inspected in the console. These getters are skipped in prod mode
@@ -152,9 +159,6 @@ export interface ComponentInternalInstance {
152159
// alternative proxy used only for runtime-compiled render functions using
153160
// `with` block
154161
withProxy: ComponentPublicInstance | null
155-
setupContext: SetupContext | null
156-
refs: Data
157-
emit: EmitFn
158162

159163
// suspense related
160164
suspense: SuspenseBoundary | null
@@ -209,19 +213,20 @@ export function createComponentInstance(
209213
proxy: null,
210214
proxyTarget: null!, // to be immediately set
211215
withProxy: null,
212-
setupContext: null,
213216
effects: null,
214217
provides: parent ? parent.provides : Object.create(appContext.provides),
215218
accessCache: null!,
216219
renderCache: [],
217220

218-
// setup context properties
221+
// state
219222
renderContext: EMPTY_OBJ,
220223
data: EMPTY_OBJ,
221224
props: EMPTY_OBJ,
222225
attrs: EMPTY_OBJ,
223226
slots: EMPTY_OBJ,
224227
refs: EMPTY_OBJ,
228+
setupState: EMPTY_OBJ,
229+
setupContext: null,
225230

226231
// per-instance asset storage (mutable during options resolution)
227232
components: Object.create(appContext.components),
@@ -392,9 +397,9 @@ export function handleSetupResult(
392397
}
393398
// setup returned bindings.
394399
// assuming a render function compiled from template is present.
395-
instance.renderContext = reactive(setupResult)
400+
instance.setupState = reactive(setupResult)
396401
if (__DEV__) {
397-
exposeRenderContextOnDevProxyTarget(instance)
402+
exposeSetupStateOnDevProxyTarget(instance)
398403
}
399404
} else if (__DEV__ && setupResult !== undefined) {
400405
warn(

packages/runtime-core/src/componentProxy.ts

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,10 @@ const publicPropertiesMap: Record<
7676
}
7777

7878
const enum AccessTypes {
79+
SETUP,
7980
DATA,
80-
CONTEXT,
8181
PROPS,
82+
CONTEXT,
8283
OTHER
8384
}
8485

@@ -91,6 +92,7 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
9192
get({ _: instance }: ComponentPublicProxyTarget, key: string) {
9293
const {
9394
renderContext,
95+
setupState,
9496
data,
9597
props,
9698
accessCache,
@@ -109,6 +111,8 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
109111
const n = accessCache![key]
110112
if (n !== undefined) {
111113
switch (n) {
114+
case AccessTypes.SETUP:
115+
return setupState[key]
112116
case AccessTypes.DATA:
113117
return data[key]
114118
case AccessTypes.CONTEXT:
@@ -117,22 +121,25 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
117121
return props![key]
118122
// default: just fallthrough
119123
}
124+
} else if (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) {
125+
accessCache![key] = AccessTypes.SETUP
126+
return setupState[key]
120127
} else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
121128
accessCache![key] = AccessTypes.DATA
122129
return data[key]
130+
} else if (
131+
// only cache other properties when instance has declared (thus stable)
132+
// props
133+
type.props &&
134+
hasOwn(normalizePropsOptions(type.props)[0]!, key)
135+
) {
136+
accessCache![key] = AccessTypes.PROPS
137+
return props![key]
123138
} else if (renderContext !== EMPTY_OBJ && hasOwn(renderContext, key)) {
124139
accessCache![key] = AccessTypes.CONTEXT
125140
return renderContext[key]
126-
} else if (type.props) {
127-
// only cache other properties when instance has declared (thus stable)
128-
// props
129-
if (hasOwn(normalizePropsOptions(type.props)[0]!, key)) {
130-
accessCache![key] = AccessTypes.PROPS
131-
// return the value from propsProxy for ref unwrapping and readonly
132-
return props![key]
133-
} else {
134-
accessCache![key] = AccessTypes.OTHER
135-
}
141+
} else {
142+
accessCache![key] = AccessTypes.OTHER
136143
}
137144
}
138145

@@ -170,23 +177,25 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
170177
key: string,
171178
value: any
172179
): boolean {
173-
const { data, renderContext } = instance
174-
if (data !== EMPTY_OBJ && hasOwn(data, key)) {
180+
const { data, setupState, renderContext } = instance
181+
if (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) {
182+
setupState[key] = value
183+
} else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
175184
data[key] = value
176-
} else if (hasOwn(renderContext, key)) {
177-
renderContext[key] = value
178-
} else if (key[0] === '$' && key.slice(1) in instance) {
185+
} else if (key in instance.props) {
179186
__DEV__ &&
180187
warn(
181-
`Attempting to mutate public property "${key}". ` +
182-
`Properties starting with $ are reserved and readonly.`,
188+
`Attempting to mutate prop "${key}". Props are readonly.`,
183189
instance
184190
)
185191
return false
186-
} else if (key in instance.props) {
192+
} else if (hasOwn(renderContext, key)) {
193+
renderContext[key] = value
194+
} else if (key[0] === '$' && key.slice(1) in instance) {
187195
__DEV__ &&
188196
warn(
189-
`Attempting to mutate prop "${key}". Props are readonly.`,
197+
`Attempting to mutate public property "${key}". ` +
198+
`Properties starting with $ are reserved and readonly.`,
190199
instance
191200
)
192201
return false
@@ -206,15 +215,24 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
206215

207216
has(
208217
{
209-
_: { data, accessCache, renderContext, type, proxyTarget, appContext }
218+
_: {
219+
data,
220+
setupState,
221+
accessCache,
222+
renderContext,
223+
type,
224+
proxyTarget,
225+
appContext
226+
}
210227
}: ComponentPublicProxyTarget,
211228
key: string
212229
) {
213230
return (
214231
accessCache![key] !== undefined ||
215232
(data !== EMPTY_OBJ && hasOwn(data, key)) ||
216-
hasOwn(renderContext, key) ||
233+
(setupState !== EMPTY_OBJ && hasOwn(setupState, key)) ||
217234
(type.props && hasOwn(normalizePropsOptions(type.props)[0]!, key)) ||
235+
hasOwn(renderContext, key) ||
218236
hasOwn(publicPropertiesMap, key) ||
219237
hasOwn(proxyTarget, key) ||
220238
hasOwn(appContext.config.globalProperties, key)
@@ -306,15 +324,15 @@ export function exposePropsOnDevProxyTarget(
306324
}
307325
}
308326

309-
export function exposeRenderContextOnDevProxyTarget(
327+
export function exposeSetupStateOnDevProxyTarget(
310328
instance: ComponentInternalInstance
311329
) {
312-
const { proxyTarget, renderContext } = instance
313-
Object.keys(toRaw(renderContext)).forEach(key => {
330+
const { proxyTarget, setupState } = instance
331+
Object.keys(toRaw(setupState)).forEach(key => {
314332
Object.defineProperty(proxyTarget, key, {
315333
enumerable: true,
316334
configurable: true,
317-
get: () => renderContext[key],
335+
get: () => setupState[key],
318336
set: NOOP
319337
})
320338
})

packages/runtime-core/src/renderer.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1899,14 +1899,14 @@ function baseCreateRenderer(
18991899
}
19001900
const oldRef = oldRawRef && oldRawRef[1]
19011901
const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs
1902-
const renderContext = owner.renderContext
1902+
const setupState = owner.setupState
19031903

19041904
// unset old ref
19051905
if (oldRef != null && oldRef !== ref) {
19061906
if (isString(oldRef)) {
19071907
refs[oldRef] = null
1908-
if (hasOwn(renderContext, oldRef)) {
1909-
renderContext[oldRef] = null
1908+
if (hasOwn(setupState, oldRef)) {
1909+
setupState[oldRef] = null
19101910
}
19111911
} else if (isRef(oldRef)) {
19121912
oldRef.value = null
@@ -1915,8 +1915,8 @@ function baseCreateRenderer(
19151915

19161916
if (isString(ref)) {
19171917
refs[ref] = value
1918-
if (hasOwn(renderContext, ref)) {
1919-
renderContext[ref] = value
1918+
if (hasOwn(setupState, ref)) {
1919+
setupState[ref] = value
19201920
}
19211921
} else if (isRef(ref)) {
19221922
ref.value = value

0 commit comments

Comments
 (0)