|
|
@@ -39,9 +39,7 @@ import {
|
|
|
import {
|
|
|
reactive,
|
|
|
ComputedGetter,
|
|
|
- WritableComputedOptions,
|
|
|
- ComputedRef,
|
|
|
- toRaw
|
|
|
+ WritableComputedOptions
|
|
|
} from '@vue/reactivity'
|
|
|
import {
|
|
|
ComponentObjectPropsOptions,
|
|
|
@@ -246,8 +244,7 @@ export function applyOptions(
|
|
|
options: ComponentOptions,
|
|
|
asMixin: boolean = false
|
|
|
) {
|
|
|
- const proxyTarget = instance.proxyTarget
|
|
|
- const ctx = instance.proxy!
|
|
|
+ const publicThis = instance.proxy!
|
|
|
const {
|
|
|
// composition
|
|
|
mixins,
|
|
|
@@ -277,19 +274,13 @@ export function applyOptions(
|
|
|
errorCaptured
|
|
|
} = options
|
|
|
|
|
|
- const renderContext = toRaw(
|
|
|
- instance.renderContext === EMPTY_OBJ &&
|
|
|
- (computedOptions || methods || watchOptions || injectOptions)
|
|
|
- ? (instance.renderContext = reactive({}))
|
|
|
- : instance.renderContext
|
|
|
- )
|
|
|
-
|
|
|
+ const ctx = instance.ctx
|
|
|
const globalMixins = instance.appContext.mixins
|
|
|
// call it only during dev
|
|
|
|
|
|
// applyOptions is called non-as-mixin once per instance
|
|
|
if (!asMixin) {
|
|
|
- callSyncHook('beforeCreate', options, ctx, globalMixins)
|
|
|
+ callSyncHook('beforeCreate', options, publicThis, globalMixins)
|
|
|
// global mixins are applied first
|
|
|
applyMixins(instance, globalMixins)
|
|
|
}
|
|
|
@@ -318,7 +309,7 @@ export function applyOptions(
|
|
|
`Plain object usage is no longer supported.`
|
|
|
)
|
|
|
}
|
|
|
- const data = dataOptions.call(ctx, ctx)
|
|
|
+ const data = dataOptions.call(publicThis, publicThis)
|
|
|
if (__DEV__ && isPromise(data)) {
|
|
|
warn(
|
|
|
`data() returned a Promise - note data() cannot be async; If you ` +
|
|
|
@@ -332,7 +323,13 @@ export function applyOptions(
|
|
|
if (__DEV__) {
|
|
|
for (const key in data) {
|
|
|
checkDuplicateProperties!(OptionTypes.DATA, key)
|
|
|
- if (!(key in proxyTarget)) proxyTarget[key] = data[key]
|
|
|
+ // expose data on ctx during dev
|
|
|
+ Object.defineProperty(ctx, key, {
|
|
|
+ configurable: true,
|
|
|
+ enumerable: true,
|
|
|
+ get: () => data[key],
|
|
|
+ set: NOOP
|
|
|
+ })
|
|
|
}
|
|
|
}
|
|
|
instance.data = reactive(data)
|
|
|
@@ -345,37 +342,36 @@ export function applyOptions(
|
|
|
if (computedOptions) {
|
|
|
for (const key in computedOptions) {
|
|
|
const opt = (computedOptions as ComputedOptions)[key]
|
|
|
- if (isFunction(opt)) {
|
|
|
- renderContext[key] = computed(opt.bind(ctx, ctx))
|
|
|
- } else {
|
|
|
- const { get, set } = opt
|
|
|
- if (isFunction(get)) {
|
|
|
- renderContext[key] = computed({
|
|
|
- get: get.bind(ctx, ctx),
|
|
|
- set: isFunction(set)
|
|
|
- ? set.bind(ctx)
|
|
|
- : __DEV__
|
|
|
- ? () => {
|
|
|
- warn(
|
|
|
- `Write operation failed: computed property "${key}" is readonly.`
|
|
|
- )
|
|
|
- }
|
|
|
- : NOOP
|
|
|
- })
|
|
|
- } else if (__DEV__) {
|
|
|
- warn(`Computed property "${key}" has no getter.`)
|
|
|
- }
|
|
|
+ const get = isFunction(opt)
|
|
|
+ ? opt.bind(publicThis, publicThis)
|
|
|
+ : isFunction(opt.get)
|
|
|
+ ? opt.get.bind(publicThis, publicThis)
|
|
|
+ : NOOP
|
|
|
+ if (__DEV__ && get === NOOP) {
|
|
|
+ warn(`Computed property "${key}" has no getter.`)
|
|
|
}
|
|
|
+ const set =
|
|
|
+ !isFunction(opt) && isFunction(opt.set)
|
|
|
+ ? opt.set.bind(publicThis)
|
|
|
+ : __DEV__
|
|
|
+ ? () => {
|
|
|
+ warn(
|
|
|
+ `Write operation failed: computed property "${key}" is readonly.`
|
|
|
+ )
|
|
|
+ }
|
|
|
+ : NOOP
|
|
|
+ const c = computed({
|
|
|
+ get,
|
|
|
+ set
|
|
|
+ })
|
|
|
+ Object.defineProperty(ctx, key, {
|
|
|
+ enumerable: true,
|
|
|
+ configurable: true,
|
|
|
+ get: () => c.value,
|
|
|
+ set: v => (c.value = v)
|
|
|
+ })
|
|
|
if (__DEV__) {
|
|
|
checkDuplicateProperties!(OptionTypes.COMPUTED, key)
|
|
|
- if (renderContext[key] && !(key in proxyTarget)) {
|
|
|
- Object.defineProperty(proxyTarget, key, {
|
|
|
- enumerable: true,
|
|
|
- configurable: true,
|
|
|
- get: () => (renderContext[key] as ComputedRef).value,
|
|
|
- set: NOOP
|
|
|
- })
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -384,12 +380,9 @@ export function applyOptions(
|
|
|
for (const key in methods) {
|
|
|
const methodHandler = (methods as MethodOptions)[key]
|
|
|
if (isFunction(methodHandler)) {
|
|
|
- renderContext[key] = methodHandler.bind(ctx)
|
|
|
+ ctx[key] = methodHandler.bind(publicThis)
|
|
|
if (__DEV__) {
|
|
|
checkDuplicateProperties!(OptionTypes.METHODS, key)
|
|
|
- if (!(key in proxyTarget)) {
|
|
|
- proxyTarget[key] = renderContext[key]
|
|
|
- }
|
|
|
}
|
|
|
} else if (__DEV__) {
|
|
|
warn(
|
|
|
@@ -402,13 +395,13 @@ export function applyOptions(
|
|
|
|
|
|
if (watchOptions) {
|
|
|
for (const key in watchOptions) {
|
|
|
- createWatcher(watchOptions[key], renderContext, ctx, key)
|
|
|
+ createWatcher(watchOptions[key], ctx, publicThis, key)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (provideOptions) {
|
|
|
const provides = isFunction(provideOptions)
|
|
|
- ? provideOptions.call(ctx)
|
|
|
+ ? provideOptions.call(publicThis)
|
|
|
: provideOptions
|
|
|
for (const key in provides) {
|
|
|
provide(key, provides[key])
|
|
|
@@ -419,23 +412,21 @@ export function applyOptions(
|
|
|
if (isArray(injectOptions)) {
|
|
|
for (let i = 0; i < injectOptions.length; i++) {
|
|
|
const key = injectOptions[i]
|
|
|
- renderContext[key] = inject(key)
|
|
|
+ ctx[key] = inject(key)
|
|
|
if (__DEV__) {
|
|
|
checkDuplicateProperties!(OptionTypes.INJECT, key)
|
|
|
- proxyTarget[key] = renderContext[key]
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
|
for (const key in injectOptions) {
|
|
|
const opt = injectOptions[key]
|
|
|
if (isObject(opt)) {
|
|
|
- renderContext[key] = inject(opt.from, opt.default)
|
|
|
+ ctx[key] = inject(opt.from, opt.default)
|
|
|
} else {
|
|
|
- renderContext[key] = inject(opt)
|
|
|
+ ctx[key] = inject(opt)
|
|
|
}
|
|
|
if (__DEV__) {
|
|
|
checkDuplicateProperties!(OptionTypes.INJECT, key)
|
|
|
- proxyTarget[key] = renderContext[key]
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -451,40 +442,40 @@ export function applyOptions(
|
|
|
|
|
|
// lifecycle options
|
|
|
if (!asMixin) {
|
|
|
- callSyncHook('created', options, ctx, globalMixins)
|
|
|
+ callSyncHook('created', options, publicThis, globalMixins)
|
|
|
}
|
|
|
if (beforeMount) {
|
|
|
- onBeforeMount(beforeMount.bind(ctx))
|
|
|
+ onBeforeMount(beforeMount.bind(publicThis))
|
|
|
}
|
|
|
if (mounted) {
|
|
|
- onMounted(mounted.bind(ctx))
|
|
|
+ onMounted(mounted.bind(publicThis))
|
|
|
}
|
|
|
if (beforeUpdate) {
|
|
|
- onBeforeUpdate(beforeUpdate.bind(ctx))
|
|
|
+ onBeforeUpdate(beforeUpdate.bind(publicThis))
|
|
|
}
|
|
|
if (updated) {
|
|
|
- onUpdated(updated.bind(ctx))
|
|
|
+ onUpdated(updated.bind(publicThis))
|
|
|
}
|
|
|
if (activated) {
|
|
|
- onActivated(activated.bind(ctx))
|
|
|
+ onActivated(activated.bind(publicThis))
|
|
|
}
|
|
|
if (deactivated) {
|
|
|
- onDeactivated(deactivated.bind(ctx))
|
|
|
+ onDeactivated(deactivated.bind(publicThis))
|
|
|
}
|
|
|
if (errorCaptured) {
|
|
|
- onErrorCaptured(errorCaptured.bind(ctx))
|
|
|
+ onErrorCaptured(errorCaptured.bind(publicThis))
|
|
|
}
|
|
|
if (renderTracked) {
|
|
|
- onRenderTracked(renderTracked.bind(ctx))
|
|
|
+ onRenderTracked(renderTracked.bind(publicThis))
|
|
|
}
|
|
|
if (renderTriggered) {
|
|
|
- onRenderTriggered(renderTriggered.bind(ctx))
|
|
|
+ onRenderTriggered(renderTriggered.bind(publicThis))
|
|
|
}
|
|
|
if (beforeUnmount) {
|
|
|
- onBeforeUnmount(beforeUnmount.bind(ctx))
|
|
|
+ onBeforeUnmount(beforeUnmount.bind(publicThis))
|
|
|
}
|
|
|
if (unmounted) {
|
|
|
- onUnmounted(unmounted.bind(ctx))
|
|
|
+ onUnmounted(unmounted.bind(publicThis))
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -533,25 +524,25 @@ function applyMixins(
|
|
|
|
|
|
function createWatcher(
|
|
|
raw: ComponentWatchOptionItem,
|
|
|
- renderContext: Data,
|
|
|
- ctx: ComponentPublicInstance,
|
|
|
+ ctx: Data,
|
|
|
+ publicThis: ComponentPublicInstance,
|
|
|
key: string
|
|
|
) {
|
|
|
- const getter = () => (ctx as Data)[key]
|
|
|
+ const getter = () => (publicThis as Data)[key]
|
|
|
if (isString(raw)) {
|
|
|
- const handler = renderContext[raw]
|
|
|
+ const handler = ctx[raw]
|
|
|
if (isFunction(handler)) {
|
|
|
watch(getter, handler as WatchCallback)
|
|
|
} else if (__DEV__) {
|
|
|
warn(`Invalid watch handler specified by key "${raw}"`, handler)
|
|
|
}
|
|
|
} else if (isFunction(raw)) {
|
|
|
- watch(getter, raw.bind(ctx))
|
|
|
+ watch(getter, raw.bind(publicThis))
|
|
|
} else if (isObject(raw)) {
|
|
|
if (isArray(raw)) {
|
|
|
- raw.forEach(r => createWatcher(r, renderContext, ctx, key))
|
|
|
+ raw.forEach(r => createWatcher(r, ctx, publicThis, key))
|
|
|
} else {
|
|
|
- watch(getter, raw.handler.bind(ctx), raw)
|
|
|
+ watch(getter, raw.handler.bind(publicThis), raw)
|
|
|
}
|
|
|
} else if (__DEV__) {
|
|
|
warn(`Invalid watch option: "${key}"`)
|