/**
* vuejs/component-compiler-utils#22 Support uri fragment in transformed require
- * @param urlString an url as a string
+ * @param urlString - an url as a string
*/
function parseUriParts(urlString: string): UrlWithStringQuery {
// A TypeError is thrown if urlString is not a string
}
}
+/**
+ * Takes a getter function and returns a readonly reactive ref object for the
+ * returned value from the getter. It can also take an object with get and set
+ * functions to create a writable ref object.
+ *
+ * @example
+ * ```js
+ * // Creating a readonly computed ref:
+ * const count = ref(1)
+ * const plusOne = computed(() => count.value + 1)
+ *
+ * console.log(plusOne.value) // 2
+ * plusOne.value++ // error
+ * ```
+ *
+ * ```js
+ * // Creating a writable computed ref:
+ * const count = ref(1)
+ * const plusOne = computed({
+ * get: () => count.value + 1,
+ * set: (val) => {
+ * count.value = val - 1
+ * }
+ * })
+ *
+ * plusOne.value = 1
+ * console.log(count.value) // 0
+ * ```
+ *
+ * @param getter - Function that produces the next value.
+ * @param debugOptions - For debugging. See {@link https://vuejs.org/guide/extras/reactivity-in-depth.html#computed-debugging}.
+ * @see {@link https://vuejs.org/api/reactivity-core.html#computed}
+ */
export function computed<T>(
getter: ComputedGetter<T>,
debugOptions?: DebuggerOptions
effect: ReactiveEffect
}
+/**
+ * Registers the given function to track reactive updates.
+ *
+ * The given function will be run once immediately. Every time any reactive
+ * property that's accessed within it gets updated, the function will run again.
+ *
+ * @param fn - The function that will track reactive updates.
+ * @param options - Allows to control the effect's behaviour.
+ * @returns A runner that can be used to control the effect after creation.
+ */
export function effect<T = any>(
fn: () => T,
options?: ReactiveEffectOptions
return runner
}
+/**
+ * Stops the effect associated with the given runner.
+ *
+ * @param runner - Association with the effect to stop tracking.
+ */
export function stop(runner: ReactiveEffectRunner) {
runner.effect.stop()
}
export let shouldTrack = true
const trackStack: boolean[] = []
+/**
+ * Temporarily pauses tracking.
+ */
export function pauseTracking() {
trackStack.push(shouldTrack)
shouldTrack = false
}
+/**
+ * Re-enables effect tracking (if it was paused).
+ */
export function enableTracking() {
trackStack.push(shouldTrack)
shouldTrack = true
}
+/**
+ * Resets the previous global effect tracking state.
+ */
export function resetTracking() {
const last = trackStack.pop()
shouldTrack = last === undefined ? true : last
}
+/**
+ * Tracks access to a reactive property.
+ *
+ * This will check which effect is running at the moment and record it as dep
+ * which records all effects that depend on the reactive property.
+ *
+ * @param target - Object holding the reactive property.
+ * @param type - Defines the type of access to the reactive property.
+ * @param key - Identifier of the reactive property to track.
+ */
export function track(target: object, type: TrackOpTypes, key: unknown) {
if (shouldTrack && activeEffect) {
let depsMap = targetMap.get(target)
}
}
+/**
+ * Finds all deps associated with the target (or a specific property) and
+ * triggers the effects stored within.
+ *
+ * @param target - The reactive object.
+ * @param type - Defines the type of the operation that needs to trigger effects.
+ * @param key - Can be used to target a specific reactive property in the target object.
+ */
export function trigger(
target: object,
type: TriggerOpTypes,
}
}
+/**
+ * Creates an effect scope object which can capture the reactive effects (i.e.
+ * computed and watchers) created within it so that these effects can be
+ * disposed together. For detailed use cases of this API, please consult its
+ * corresponding {@link https://github.com/vuejs/rfcs/blob/master/active-rfcs/0041-reactivity-effect-scope.md | RFC}.
+ *
+ * @param detached - Can be used to create a "detached" effect scope.
+ * @see {@link https://vuejs.org/api/reactivity-advanced.html#effectscope}
+ */
export function effectScope(detached?: boolean) {
return new EffectScope(detached)
}
}
}
+/**
+ * Returns the current active effect scope if there is one.
+ *
+ * @see {@link https://vuejs.org/api/reactivity-advanced.html#getcurrentscope}
+ */
export function getCurrentScope() {
return activeEffectScope
}
+/**
+ * Registers a dispose callback on the current active effect scope. The
+ * callback will be invoked when the associated effect scope is stopped.
+ *
+ * @param fn - The callback function to attach to the scope's cleanup.
+ * @see {@link https://vuejs.org/api/reactivity-advanced.html#onscopedispose}
+ */
export function onScopeDispose(fn: () => void) {
if (activeEffectScope) {
activeEffectScope.cleanups.push(fn)
export type UnwrapNestedRefs<T> = T extends Ref ? T : UnwrapRefSimple<T>
/**
- * Creates a reactive copy of the original object.
+ * Returns a reactive proxy of the object.
*
- * The reactive conversion is "deep"—it affects all nested properties. In the
- * ES2015 Proxy based implementation, the returned proxy is **not** equal to the
- * original object. It is recommended to work exclusively with the reactive
- * proxy and avoid relying on the original object.
- *
- * A reactive object also automatically unwraps refs contained in it, so you
- * don't need to use `.value` when accessing and mutating their value:
+ * The reactive conversion is "deep": it affects all nested properties. A
+ * reactive object also deeply unwraps any properties that are refs while
+ * maintaining reactivity.
*
+ * @example
* ```js
- * const count = ref(0)
- * const obj = reactive({
- * count
- * })
- *
- * obj.count++
- * obj.count // -> 1
- * count.value // -> 1
+ * const obj = reactive({ count: 0 })
* ```
+ *
+ * @param target - The source object.
+ * @see {@link https://vuejs.org/api/reactivity-core.html#reactive}
*/
export function reactive<T extends object>(target: T): UnwrapNestedRefs<T>
export function reactive(target: object) {
export type ShallowReactive<T> = T & { [ShallowReactiveMarker]?: true }
/**
- * Return a shallowly-reactive copy of the original object, where only the root
- * level properties are reactive. It also does not auto-unwrap refs (even at the
- * root level).
+ * Shallow version of {@link reactive()}.
+ *
+ * Unlike {@link reactive()}, there is no deep conversion: only root-level
+ * properties are reactive for a shallow reactive object. Property values are
+ * stored and exposed as-is - this also means properties with ref values will
+ * not be automatically unwrapped.
+ *
+ * @example
+ * ```js
+ * const state = shallowReactive({
+ * foo: 1,
+ * nested: {
+ * bar: 2
+ * }
+ * })
+ *
+ * // mutating state's own properties is reactive
+ * state.foo++
+ *
+ * // ...but does not convert nested objects
+ * isReactive(state.nested) // false
+ *
+ * // NOT reactive
+ * state.nested.bar++
+ * ```
+ *
+ * @param target - The source object.
+ * @see {@link https://vuejs.org/api/reactivity-advanced.html#shallowreactive}
*/
export function shallowReactive<T extends object>(
target: T
: Readonly<T>
/**
- * Creates a readonly copy of the original object. Note the returned copy is not
- * made reactive, but `readonly` can be called on an already reactive object.
+ * Takes an object (reactive or plain) or a ref and returns a readonly proxy to
+ * the original.
+ *
+ * A readonly proxy is deep: any nested property accessed will be readonly as
+ * well. It also has the same ref-unwrapping behavior as {@link reactive()},
+ * except the unwrapped values will also be made readonly.
+ *
+ * @example
+ * ```js
+ * const original = reactive({ count: 0 })
+ *
+ * const copy = readonly(original)
+ *
+ * watchEffect(() => {
+ * // works for reactivity tracking
+ * console.log(copy.count)
+ * })
+ *
+ * // mutating original will trigger watchers relying on the copy
+ * original.count++
+ *
+ * // mutating the copy will fail and result in a warning
+ * copy.count++ // warning!
+ * ```
+ *
+ * @param target - The source object.
+ * @see {@link https://vuejs.org/api/reactivity-core.html#readonly}
*/
export function readonly<T extends object>(
target: T
}
/**
- * Returns a reactive-copy of the original object, where only the root level
- * properties are readonly, and does NOT unwrap refs nor recursively convert
- * returned properties.
- * This is used for creating the props proxy object for stateful components.
+ * Shallow version of {@link readonly()}.
+ *
+ * Unlike {@link readonly()}, there is no deep conversion: only root-level
+ * properties are made readonly. Property values are stored and exposed as-is -
+ * this also means properties with ref values will not be automatically
+ * unwrapped.
+ *
+ * @example
+ * ```js
+ * const state = shallowReadonly({
+ * foo: 1,
+ * nested: {
+ * bar: 2
+ * }
+ * })
+ *
+ * // mutating state's own properties will fail
+ * state.foo++
+ *
+ * // ...but works on nested objects
+ * isReadonly(state.nested) // false
+ *
+ * // works
+ * state.nested.bar++
+ * ```
+ *
+ * @param target - The source object.
+ * @see {@link https://vuejs.org/api/reactivity-advanced.html#shallowreadonly}
*/
export function shallowReadonly<T extends object>(target: T): Readonly<T> {
return createReactiveObject(
return proxy
}
+/**
+ * Checks if an object is a proxy created by {@link reactive()} or
+ * {@link shallowReactive()} (or {@link ref()} in some cases).
+ *
+ * @example
+ * ```js
+ * isReactive(reactive({})) // => true
+ * isReactive(readonly(reactive({}))) // => true
+ * isReactive(ref({}).value) // => true
+ * isReactive(readonly(ref({})).value) // => true
+ * isReactive(ref(true)) // => false
+ * isReactive(shallowRef({}).value) // => false
+ * isReactive(shallowReactive({})) // => true
+ * ```
+ *
+ * @param value - The value to check.
+ * @see {@link https://vuejs.org/api/reactivity-utilities.html#isreactive}
+ */
export function isReactive(value: unknown): boolean {
if (isReadonly(value)) {
return isReactive((value as Target)[ReactiveFlags.RAW])
return !!(value && (value as Target)[ReactiveFlags.IS_REACTIVE])
}
+/**
+ * Checks whether the passed value is a readonly object. The properties of a
+ * readonly object can change, but they can't be assigned directly via the
+ * passed object.
+ *
+ * The proxies created by {@link readonly()} and {@link shallowReadonly()} are
+ * both considered readonly, as is a computed ref without a set function.
+ *
+ * @param value - The value to check.
+ * @see {@link https://vuejs.org/api/reactivity-utilities.html#isreadonly}
+ */
export function isReadonly(value: unknown): boolean {
return !!(value && (value as Target)[ReactiveFlags.IS_READONLY])
}
return !!(value && (value as Target)[ReactiveFlags.IS_SHALLOW])
}
+/**
+ * Checks if an object is a proxy created by {@link reactive},
+ * {@link readonly}, {@link shallowReactive} or {@link shallowReadonly()}.
+ *
+ * @param value - The value to check.
+ * @see {@link https://vuejs.org/api/reactivity-utilities.html#isproxy}
+ */
export function isProxy(value: unknown): boolean {
return isReactive(value) || isReadonly(value)
}
+/**
+ * Returns the raw, original object of a Vue-created proxy.
+ *
+ * `toRaw()` can return the original object from proxies created by
+ * {@link reactive()}, {@link readonly()}, {@link shallowReactive()} or
+ * {@link shallowReadonly()}.
+ *
+ * This is an escape hatch that can be used to temporarily read without
+ * incurring proxy access / tracking overhead or write without triggering
+ * changes. It is **not** recommended to hold a persistent reference to the
+ * original object. Use with caution.
+ *
+ * @example
+ * ```js
+ * const foo = {}
+ * const reactiveFoo = reactive(foo)
+ *
+ * console.log(toRaw(reactiveFoo) === foo) // true
+ * ```
+ *
+ * @param observed - The object for which the "raw" value is requested.
+ * @see {@link https://vuejs.org/api/reactivity-advanced.html#toraw}
+ */
export function toRaw<T>(observed: T): T {
const raw = observed && (observed as Target)[ReactiveFlags.RAW]
return raw ? toRaw(raw) : observed
export type Raw<T> = T & { [RawSymbol]?: true }
+/**
+ * Marks an object so that it will never be converted to a proxy. Returns the
+ * object itself.
+ *
+ * @example
+ * ```js
+ * const foo = markRaw({})
+ * console.log(isReactive(reactive(foo))) // false
+ *
+ * // also works when nested inside other reactive objects
+ * const bar = reactive({ foo })
+ * console.log(isReactive(bar.foo)) // false
+ * ```
+ *
+ * **Warning:** `markRaw()` together with the shallow APIs such as
+ * {@link shallowReactive()} allow you to selectively opt-out of the default
+ * deep reactive/readonly conversion and embed raw, non-proxied objects in your
+ * state graph.
+ *
+ * @param value - The object to be marked as "raw".
+ * @see {@link https://vuejs.org/api/reactivity-advanced.html#markraw}
+ */
export function markRaw<T extends object>(value: T): Raw<T> {
def(value, ReactiveFlags.SKIP, true)
return value
}
+/**
+ * Returns a reactive proxy of the given value (if possible).
+ *
+ * If the given value is not an object, the original value itself is returned.
+ *
+ * @param value - The value for which a reactive proxy shall be created.
+ */
export const toReactive = <T extends unknown>(value: T): T =>
isObject(value) ? reactive(value) : value
+/**
+ * Returns a readonly proxy of the given value (if possible).
+ *
+ * If the given value is not an object, the original value itself is returned.
+ *
+ * @param value - The value for which a readonly proxy shall be created.
+ */
export const toReadonly = <T extends unknown>(value: T): T =>
isObject(value) ? readonly(value as Record<any, any>) : value
}
}
+/**
+ * Checks if a value is a ref object.
+ *
+ * @param r - The value to inspect.
+ * @see {@link https://vuejs.org/api/reactivity-utilities.html#isref}
+ */
export function isRef<T>(r: Ref<T> | unknown): r is Ref<T>
export function isRef(r: any): r is Ref {
return !!(r && r.__v_isRef === true)
}
+/**
+ * Takes an inner value and returns a reactive and mutable ref object, which
+ * has a single property `.value` that points to the inner value.
+ *
+ * @param value - The object to wrap in the ref.
+ * @see {@link https://vuejs.org/api/reactivity-core.html#ref}
+ */
export function ref<T extends object>(
value: T
): [T] extends [Ref] ? T : Ref<UnwrapRef<T>>
export type ShallowRef<T = any> = Ref<T> & { [ShallowRefMarker]?: true }
+/**
+ * Shallow version of {@link ref()}.
+ *
+ * @example
+ * ```js
+ * const state = shallowRef({ count: 1 })
+ *
+ * // does NOT trigger change
+ * state.value.count = 2
+ *
+ * // does trigger change
+ * state.value = { count: 2 }
+ * ```
+ *
+ * @param value - The "inner value" for the shallow ref.
+ * @see {@link https://vuejs.org/api/reactivity-advanced.html#shallowref}
+ */
export function shallowRef<T extends object>(
value: T
): T extends Ref ? T : ShallowRef<T>
}
}
+/**
+ * Force trigger effects that depends on a shallow ref. This is typically used
+ * after making deep mutations to the inner value of a shallow ref.
+ *
+ * @example
+ * ```js
+ * const shallow = shallowRef({
+ * greet: 'Hello, world'
+ * })
+ *
+ * // Logs "Hello, world" once for the first run-through
+ * watchEffect(() => {
+ * console.log(shallow.value.greet)
+ * })
+ *
+ * // This won't trigger the effect because the ref is shallow
+ * shallow.value.greet = 'Hello, universe'
+ *
+ * // Logs "Hello, universe"
+ * triggerRef(shallow)
+ * ```
+ *
+ * @param ref - The ref whose tied effects shall be executed.
+ * @see {@link https://vuejs.org/api/reactivity-advanced.html#triggerref}
+ */
export function triggerRef(ref: Ref) {
triggerRefValue(ref, __DEV__ ? ref.value : void 0)
}
+/**
+ * Returns the inner value if the argument is a ref, otherwise return the
+ * argument itself. This is a sugar function for
+ * `val = isRef(val) ? val.value : val`.
+ *
+ * @example
+ * ```js
+ * function useFoo(x: number | Ref<number>) {
+ * const unwrapped = unref(x)
+ * // unwrapped is guaranteed to be number now
+ * }
+ * ```
+ *
+ * @param ref - Ref or plain value to be converted into the plain value.
+ * @see {@link https://vuejs.org/api/reactivity-utilities.html#unref}
+ */
export function unref<T>(ref: T | Ref<T>): T {
return isRef(ref) ? (ref.value as any) : ref
}
}
}
+/**
+ * Returns a reactive proxy for the given object.
+ *
+ * If the object already is reactive, it's returned as-is. If not, a new
+ * reactive proxy is created. Direct child properties that are refs are properly
+ * handled, as well.
+ *
+ * @param objectWithRefs - Either an already-reactive object or a simple object
+ * that contains refs.
+ */
export function proxyRefs<T extends object>(
objectWithRefs: T
): ShallowUnwrapRef<T> {
}
}
+/**
+ * Creates a customized ref with explicit control over its dependency tracking
+ * and updates triggering.
+ *
+ * @param factory - The function that receives the `track` and `trigger` callbacks.
+ * @see {@link https://vuejs.org/api/reactivity-advanced.html#customref}
+ */
export function customRef<T>(factory: CustomRefFactory<T>): Ref<T> {
return new CustomRefImpl(factory) as any
}
export type ToRefs<T = any> = {
[K in keyof T]: ToRef<T[K]>
}
+
+/**
+ * Converts a reactive object to a plain object where each property of the
+ * resulting object is a ref pointing to the corresponding property of the
+ * original object. Each individual ref is created using {@link toRef()}.
+ *
+ * @param object - Reactive object to be made into an object of linked refs.
+ * @see {@link https://vuejs.org/api/reactivity-utilities.html#torefs}
+ */
export function toRefs<T extends object>(object: T): ToRefs<T> {
if (__DEV__ && !isProxy(object)) {
console.warn(`toRefs() expects a reactive object but received a plain one.`)
export type ToRef<T> = IfAny<T, Ref<T>, [T] extends [Ref] ? T : Ref<T>>
+/**
+ * Can be used to create a ref for a property on a source reactive object. The
+ * created ref is synced with its source property: mutating the source property
+ * will update the ref, and vice-versa.
+ *
+ * @example
+ * ```js
+ * const state = reactive({
+ * foo: 1,
+ * bar: 2
+ * })
+ *
+ * const fooRef = toRef(state, 'foo')
+ *
+ * // mutating the ref updates the original
+ * fooRef.value++
+ * console.log(state.foo) // 2
+ *
+ * // mutating the original also updates the ref
+ * state.foo++
+ * console.log(fooRef.value) // 3
+ * ```
+ *
+ * @param object - The reactive object containing the desired property.
+ * @param key - Name of the property in the reactive object.
+ * @see {@link https://vuejs.org/api/reactivity-utilities.html#toref}
+ */
export function toRef<T extends object, K extends keyof T>(
object: T,
key: K
): ToRef<T[K]>
-
export function toRef<T extends object, K extends keyof T>(
object: T,
key: K,
defaultValue: T[K]
): ToRef<Exclude<T[K], undefined>>
-
export function toRef<T extends object, K extends keyof T>(
object: T,
key: K,