Skip to content

Commit

Permalink
docs: add docs for core functions
Browse files Browse the repository at this point in the history
  • Loading branch information
hlysine committed May 22, 2023
1 parent e54ab60 commit 79b2035
Showing 1 changed file with 240 additions and 0 deletions.
240 changes: 240 additions & 0 deletions src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,26 @@ import { useRef } from 'react';

export { ref, computed, reactive, readonly } from '@vue/reactivity';

/**
* The hook version of `ref` from `@vue/reactivity`.
* In addition to values accepted by `ref`, you can also pass an initializer function returning the value.
*
* This hook version allows the ref to be created when the component first render, then cached for future re-renders.
* If you pass in an initializer function, it will only be called on first render.
*
* -----------------------------
*
* Takes an inner value and returns a reactive and mutable ref object, which
* has a single property `.value` that points to the inner value.
*
* @example
* ```js
* const count = useReference(1)
* ```
*
* @param value - The object to wrap in the ref, or a function that returns the object.
* @see {@link https://vuejs.org/api/reactivity-core.html#ref}
*/
export const useReference = <T>(value: T | (() => T)): Ref<UnwrapRef<T>> => {
const reactiveRef = useRef<Ref<UnwrapRef<T>> | null>(null);
if (reactiveRef.current === null) {
Expand All @@ -44,6 +64,48 @@ interface UseComputed {
): WritableComputedRef<T>;
}

/**
* The hook version of `computed` from `@vue/reactivity`.
*
* This hook version allows the computed ref to be created when the component first render, then cached for future re-renders.
*
* -----------------------------
*
* 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
* // Inside a function component:
* // Creating a readonly computed ref:
* const count = useReference(1)
* const plusOne = useComputed(() => count.value + 1)
*
* console.log(plusOne.value) // 2
* plusOne.value++ // error
* ```
*
* @example
* ```js
* // Inside a function component:
* // Creating a writable computed ref:
* const count = useReference(1)
* const plusOne = useComputed({
* 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 const useComputed: UseComputed = (<T>(
optionsOrGetter: ComputedGetter<T> | WritableComputedOptions<T>,
debugOptions?: DebuggerOptions
Expand All @@ -60,6 +122,35 @@ export const useComputed: UseComputed = (<T>(
return reactiveRef.current;
}) as UseComputed;

/**
* The hook version of `reactive` from `@vue/reactivity`.
* In addition to values accepted by `reactive`, you can also pass an initializer function returning the value.
*
* This hook version allows the reactive object to be created when the component first render, then cached for future
* re-renders.
* If you pass in an initializer function, it will only be called on first render.
*
* -----------------------------
*
* Returns a reactive proxy of the object.
*
* 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 obj = useReactive({ count: 0 })
* ```
*
* @example
* ```js
* const obj = useReactive(() => ({ count: 0 }))
* ```
*
* @param target - The source object, or a function that returns the object.
* @see {@link https://vuejs.org/api/reactivity-core.html#reactive}
*/
export const useReactive = <T extends object>(
target: T | (() => T)
): UnwrapNestedRefs<T> => {
Expand All @@ -70,6 +161,45 @@ export const useReactive = <T extends object>(
return reactiveRef.current;
};

/**
* The hook version of `readonly` from `@vue/reactivity`.
* In addition to values accepted by `readonly`, you can also pass an initializer function returning the value.
*
* This hook version allows the readonly ref to be created when the component first render, then cached for future
* re-renders.
* If you pass in an initializer function, it will only be called on first render.
*
* -----------------------------
*
* 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
* // Inside a function component:
* const original = useReactive({ count: 0 })
*
* const copy = useReadonly(original)
*
* useWatchEffect(() => {
* // 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, or a function that returns the object.
* @see {@link https://vuejs.org/api/reactivity-core.html#readonly}
*/
export const useReadonly = <T extends object>(
target: T | (() => T)
): DeepReadonly<UnwrapNestedRefs<T>> => {
Expand All @@ -92,6 +222,36 @@ interface UseWatchEffectRef {
cleanup?: CleanupFn | undefined;
}

/**
* The hook version of `effect` from `@vue/reactivity`.
*
* This hook version allows the effect to be set up when the component first render, then automatically stopped
* when the component unmounts.
*
* You may return a cleanup function from the given function to clean up side effects before the given function re-runs.
* Note that this syntax follows that of `useEffect` from React, and is not the same as `watchEffect` from Vue.
*
* -----------------------------
*
* 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.
*
* @example
* ```js
* // Inside a function component:
* const count = useReference(0)
* useWatchEffect(() => {
* console.log(count.value)
* return () => console.log('cleanup')
* })
* count.value++
* ```
*
* @param fn - The function that will track reactive updates. The return value from this function will be used as a cleanup function.
* @param options - Allows to control the effect's behaviour.
*/
export const useWatchEffect = (
fn: () => CleanupFn | void,
options?: UseWatchEffectOptions
Expand All @@ -111,6 +271,30 @@ export const useWatchEffect = (
}
};

/**
* An enhanced version of `effect` from `@vue/reactivity`, adding support for a cleanup function.
*
* ---------------------------
*
* 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.
*
* @example
* ```js
* const count = ref(0)
* effect(() => {
* console.log(count.value)
* return () => console.log('cleanup')
* })
* count.value++
* ```
*
* @param fn - The function that will track reactive updates. The return value from this function will be used as a cleanup function.
* @param options - Allows to control the effect's behaviour.
* @returns A runner that can be used to control the effect after creation.
*/
export const effect = (
fn: () => CleanupFn | void,
options?: ReactiveEffectOptions
Expand Down Expand Up @@ -187,6 +371,29 @@ interface WatchOverloads {
): WatchStopHandle;
}

/**
* Watches one or more reactive data sources and invokes a callback function when the sources change.
*
* @example
* ```js
* const count = ref(0)
* watch(count, (count) => {
* console.log(count)
* return () => console.log('cleanup')
* })
* count.value++
* ```
*
* @param sources - The watcher's source. The source can be one of the following:
* - A getter function that returns a value
* - A ref
* - A reactive object
* - ...or an array of the above.
* @param cb - The callback that will be called when the source changes. It receives the new and old value(s) as arguments.
* @param options - Allows to control the watch's behaviour.
* @returns A function that can be called to stop the watch.
* @see {@link https://vuejs.org/api/reactivity-core.html#watch}
*/
export const watch: WatchOverloads = <
T extends MultiWatchSources,
Immediate extends Readonly<boolean> = false
Expand Down Expand Up @@ -318,6 +525,39 @@ interface UseWatchOverloads {
): void;
}

/**
* The hook version of `watch`.
*
* This hook version allows the watch to be set up when the component first render, then automatically stopped
* when the component unmounts.
*
* You may return a cleanup function from the callback to clean up side effects before the callback re-runs.
* Note that this syntax follows that of `useEffect` from React, and is not the same as `watch` from Vue.
*
* -----------------------------
*
* Watches one or more reactive data sources and invokes a callback function when the sources change.
*
* @example
* ```js
* // Inside a function component:
* const count = useReference(0)
* useWatch(count, (count) => {
* console.log(count)
* return () => console.log('cleanup')
* })
* count.value++
* ```
*
* @param sources - The watcher's source. The source can be one of the following:
* - A getter function that returns a value
* - A ref
* - A reactive object
* - ...or an array of the above.
* @param cb - The callback that will be called when the source changes. It receives the new and old value(s) as arguments.
* @param options - Allows to control the watch's behaviour.
* @see {@link https://vuejs.org/api/reactivity-core.html#watch}
*/
export const useWatch: UseWatchOverloads = <
T extends MultiWatchSources,
Immediate extends Readonly<boolean> = false
Expand Down

0 comments on commit 79b2035

Please sign in to comment.