// expose effect so computed can be stopped
effect: runner,
get value() {
+ if (__SSR__) {
+ return getter()
+ }
+
if (dirty) {
value = runner()
dirty = false
-import { isObject, toRawType } from '@vue/shared'
+import { isObject, toRawType, EMPTY_OBJ } from '@vue/shared'
import {
mutableHandlers,
readonlyHandlers,
if (!canObserve(target)) {
return target
}
- const handlers = collectionTypes.has(target.constructor)
- ? collectionHandlers
- : baseHandlers
+ const handlers = __SSR__
+ ? // disable reactivity in SSR.
+ // NOTE: a potential caveat here is isReactive check may return different
+ // values on nested values on client/server. This should be very rare but
+ // we should keep an eye on this.
+ EMPTY_OBJ
+ : collectionTypes.has(target.constructor)
+ ? collectionHandlers
+ : baseHandlers
observed = new Proxy(target, handlers)
toProxy.set(target, observed)
toRaw.set(observed, target)
return raw
}
raw = convert(raw)
+
+ if (__SSR__) {
+ return {
+ _isRef: true,
+ value: raw
+ }
+ }
+
const r = {
_isRef: true,
get value() {
export function toRefs<T extends object>(
object: T
): { [K in keyof T]: Ref<T[K]> } {
- if (__DEV__ && !isReactive(object)) {
+ if (__DEV__ && !__SSR__ && !isReactive(object)) {
console.warn(`toRefs() expects a reactive object but received a plain one.`)
}
const ret: any = {}
export const createHook = <T extends Function = () => any>(
lifecycle: LifecycleHooks
) => (hook: T, target: ComponentInternalInstance | null = currentInstance) =>
- injectHook(lifecycle, hook, target)
+ // post-create lifecycle registrations are noops during SSR
+ !__SSR__ && injectHook(lifecycle, hook, target)
export const onBeforeMount = createHook(LifecycleHooks.BEFORE_MOUNT)
export const onMounted = createHook(LifecycleHooks.MOUNTED)
instance: ComponentPublicInstance | null,
info: string
) => boolean | void
-export const onErrorCaptured = createHook<ErrorCapturedHook>(
- LifecycleHooks.ERROR_CAPTURED
-)
+
+export const onErrorCaptured = (
+ hook: ErrorCapturedHook,
+ target: ComponentInternalInstance | null = currentInstance
+) => {
+ injectHook(LifecycleHooks.ERROR_CAPTURED, hook, target)
+}
) {
const renderContext =
instance.renderContext === EMPTY_OBJ
- ? (instance.renderContext = reactive({}))
+ ? (instance.renderContext = __SSR__ ? {} : reactive({}))
: instance.renderContext
const ctx = instance.proxy!
const {
checkDuplicateProperties!(OptionTypes.DATA, key)
}
}
- instance.data = reactive(data)
+ instance.data = __SSR__ ? data : reactive(data)
} else {
// existing data: this is a mixin or extends.
extend(instance.data, data)
isArray,
isFunction,
isString,
- hasChanged
+ hasChanged,
+ NOOP
} from '@vue/shared'
import { recordEffect } from './apiReactivity'
import {
cbOrOptions?: WatchCallback<T> | WatchOptions,
options?: WatchOptions
): StopHandle {
- if (isFunction(cbOrOptions)) {
+ if (__SSR__ && !(options && options.flush === 'sync')) {
+ // during SSR, non-sync watchers never fire.
+ return NOOP
+ } else if (isFunction(cbOrOptions)) {
// effect callback as 2nd argument - this is a source watcher
return doWatch(effectOrSource, cbOrOptions, options)
} else {
instance: ComponentInternalInstance,
parentSuspense: SuspenseBoundary | null
) {
- let setupResult
const Component = instance.type as ComponentOptions
if (__DEV__) {
// 2. create props proxy
// the propsProxy is a reactive AND readonly proxy to the actual props.
// it will be updated in resolveProps() on updates before render
- const propsProxy = (instance.propsProxy = shallowReadonly(instance.props))
+ const propsProxy = (instance.propsProxy = __SSR__
+ ? instance.props
+ : shallowReadonly(instance.props))
// 3. call setup()
const { setup } = Component
if (setup) {
currentInstance = instance
currentSuspense = parentSuspense
- setupResult = callWithErrorHandling(
+ const setupResult = callWithErrorHandling(
setup,
instance,
ErrorCodes.SETUP_FUNCTION,
currentSuspense = null
if (isPromise(setupResult)) {
- if (__FEATURE_SUSPENSE__) {
+ if (__SSR__) {
+ // return the promise so server-renderer can wait on it
+ return setupResult
+ } else if (__FEATURE_SUSPENSE__) {
// async setup returned Promise.
// bail here and wait for re-entry.
instance.asyncDep = setupResult
} else {
finishComponentSetup(instance, parentSuspense)
}
-
- return setupResult
}
export function handleSetupResult(
}
// setup returned bindings.
// assuming a render function compiled from template is present.
- instance.renderContext = reactive(setupResult)
+ instance.renderContext = __SSR__ ? setupResult : reactive(setupResult)
} else if (__DEV__ && setupResult !== undefined) {
warn(
`setup() should return an object. Received: ${
}
if (instance.renderContext === EMPTY_OBJ) {
- instance.renderContext = reactive({})
+ instance.renderContext = __SSR__ ? {} : reactive({})
}
}