diff --git a/packages/runtime-core/src/apiOptions.ts b/packages/runtime-core/src/apiOptions.ts index 11f5df98..fb61b96a 100644 --- a/packages/runtime-core/src/apiOptions.ts +++ b/packages/runtime-core/src/apiOptions.ts @@ -112,8 +112,10 @@ export function applyOptions( options: ComponentOptions, asMixin: boolean = false ) { - const data = - instance.data === EMPTY_OBJ ? (instance.data = reactive({})) : instance.data + const renderContext = + instance.renderContext === EMPTY_OBJ + ? (instance.renderContext = reactive({})) + : instance.renderContext const ctx = instance.renderProxy as any const { // composition @@ -166,12 +168,16 @@ export function applyOptions( // state options if (dataOptions) { + const data = + instance.data === EMPTY_OBJ + ? (instance.data = reactive({})) + : instance.data extend(data, isFunction(dataOptions) ? dataOptions.call(ctx) : dataOptions) } if (computedOptions) { for (const key in computedOptions) { const opt = (computedOptions as ComputedOptions)[key] - data[key] = isFunction(opt) + renderContext[key] = isFunction(opt) ? computed(opt.bind(ctx)) : computed({ get: opt.get.bind(ctx), @@ -181,7 +187,7 @@ export function applyOptions( } if (methods) { for (const key in methods) { - data[key] = (methods as MethodOptions)[key].bind(ctx) + renderContext[key] = (methods as MethodOptions)[key].bind(ctx) } } if (watchOptions) { @@ -189,7 +195,7 @@ export function applyOptions( const raw = watchOptions[key] const getter = () => ctx[key] if (isString(raw)) { - const handler = data[raw] + const handler = renderContext[raw] if (isFunction(handler)) { watch(getter, handler as any) } else if (__DEV__) { @@ -217,15 +223,15 @@ export function applyOptions( if (isArray(injectOptions)) { for (let i = 0; i < injectOptions.length; i++) { const key = injectOptions[i] - data[key] = inject(key) + renderContext[key] = inject(key) } } else { for (const key in injectOptions) { const opt = injectOptions[key] if (isObject(opt)) { - data[key] = inject(opt.from, opt.default) + renderContext[key] = inject(opt.from, opt.default) } else { - data[key] = inject(opt) + renderContext[key] = inject(opt) } } } diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts index 2c242692..3583d70f 100644 --- a/packages/runtime-core/src/component.ts +++ b/packages/runtime-core/src/component.ts @@ -144,15 +144,17 @@ export const enum LifecycleHooks { ERROR_CAPTURED = 'ec' } +type Emit = ((event: string, ...args: unknown[]) => void) + interface SetupContext { attrs: Data slots: Slots - emit: ((event: string, ...args: unknown[]) => void) + emit: Emit } type RenderFunction = () => VNodeChild -export type ComponentInstance
= { +export interface ComponentInstance { type: FunctionalComponent | ComponentOptions parent: ComponentInstance | null appContext: AppContext @@ -169,12 +171,16 @@ export type ComponentInstance
= {
directives: Record = {
[LifecycleHooks.ACTIVATED]: LifecycleHook
[LifecycleHooks.DEACTIVATED]: LifecycleHook
[LifecycleHooks.ERROR_CAPTURED]: LifecycleHook
-} & SetupContext
+}
// createComponent
// overload 1: direct setup function
@@ -287,6 +293,7 @@ export function createComponentInstance(
provides: parent ? parent.provides : Object.create(appContext.provides),
// setup context properties
+ renderContext: EMPTY_OBJ,
data: EMPTY_OBJ,
props: EMPTY_OBJ,
attrs: EMPTY_OBJ,
@@ -397,7 +404,7 @@ export function setupStatefulComponent(instance: ComponentInstance) {
// setup returned bindings.
// assuming a render function compiled from template is present.
if (isObject(setupResult)) {
- instance.data = reactive(setupResult)
+ instance.renderContext = reactive(setupResult)
} else if (__DEV__ && setupResult !== undefined) {
warn(
`setup() should return an object. Received: ${
@@ -420,8 +427,8 @@ export function setupStatefulComponent(instance: ComponentInstance) {
if (__FEATURE_OPTIONS__) {
applyOptions(instance, Component)
}
- if (instance.data === EMPTY_OBJ) {
- instance.data = reactive({})
+ if (instance.renderContext === EMPTY_OBJ) {
+ instance.renderContext = reactive({})
}
currentInstance = null
}
diff --git a/packages/runtime-core/src/componentProxy.ts b/packages/runtime-core/src/componentProxy.ts
index 891490d6..019e4204 100644
--- a/packages/runtime-core/src/componentProxy.ts
+++ b/packages/runtime-core/src/componentProxy.ts
@@ -1,12 +1,15 @@
import { ComponentInstance } from './component'
import { nextTick } from './scheduler'
import { instanceWatch } from './apiWatch'
+import { EMPTY_OBJ } from '@vue/shared'
export const RenderProxyHandlers = {
get(target: ComponentInstance, key: string) {
- const { data, props, propsProxy } = target
- if (data.hasOwnProperty(key)) {
+ const { renderContext, data, props, propsProxy } = target
+ if (data !== EMPTY_OBJ && data.hasOwnProperty(key)) {
return data[key]
+ } else if (renderContext.hasOwnProperty(key)) {
+ return renderContext[key]
} else if (props.hasOwnProperty(key)) {
// return the value from propsProxy for ref unwrapping and readonly
return (propsProxy as any)[key]
@@ -31,7 +34,6 @@ export const RenderProxyHandlers = {
case '$el':
return target.vnode.el
case '$options':
- // TODO handle merging
return target.type
default:
// methods are only exposed when options are supported
@@ -50,10 +52,11 @@ export const RenderProxyHandlers = {
}
},
set(target: ComponentInstance, key: string, value: any): boolean {
- const { data } = target
- if (data.hasOwnProperty(key)) {
+ const { data, renderContext } = target
+ if (data !== EMPTY_OBJ && data.hasOwnProperty(key)) {
data[key] = value
- return true
+ } else if (renderContext.hasOwnProperty(key)) {
+ renderContext[key] = value
} else if (key[0] === '$' && key.slice(1) in target) {
// TODO warn attempt of mutating public property
return false
@@ -62,7 +65,7 @@ export const RenderProxyHandlers = {
return false
} else {
target.user[key] = value
- return true
}
+ return true
}
}
diff --git a/packages/runtime-core/src/createRenderer.ts b/packages/runtime-core/src/createRenderer.ts
index 15980b6b..fd0d6aa2 100644
--- a/packages/runtime-core/src/createRenderer.ts
+++ b/packages/runtime-core/src/createRenderer.ts
@@ -1127,13 +1127,13 @@ export function createRenderer(options: RendererOptions): RootRenderFunction {
value: HostNode | ComponentInstance | null
) {
const refs = parent.refs === EMPTY_OBJ ? (parent.refs = {}) : parent.refs
- const rawData = toRaw(parent.data)
+ const renderContext = toRaw(parent.renderContext)
// unset old ref
if (oldRef !== null && oldRef !== ref) {
if (isString(oldRef)) {
refs[oldRef] = null
- const oldSetupRef = rawData[oldRef]
+ const oldSetupRef = renderContext[oldRef]
if (isRef(oldSetupRef)) {
oldSetupRef.value = null
}
@@ -1143,7 +1143,7 @@ export function createRenderer(options: RendererOptions): RootRenderFunction {
}
if (isString(ref)) {
- const setupRef = rawData[ref]
+ const setupRef = renderContext[ref]
if (isRef(setupRef)) {
setupRef.value = value
}