perf(hooks): perf useSignal

This commit is contained in:
Soybean 2024-04-25 15:00:47 +08:00
parent d460e5cc6d
commit 5d45cef1f0

View File

@ -1,5 +1,12 @@
import { computed, shallowRef, triggerRef } from 'vue'; import { computed, ref, shallowRef, triggerRef } from 'vue';
import type { ComputedGetter, DebuggerOptions, ShallowRef, WritableComputedOptions, WritableComputedRef } from 'vue'; import type {
ComputedGetter,
DebuggerOptions,
Ref,
ShallowRef,
WritableComputedOptions,
WritableComputedRef
} from 'vue';
type Updater<T> = (value: T) => T; type Updater<T> = (value: T) => T;
type Mutator<T> = (value: T) => void; type Mutator<T> = (value: T) => void;
@ -7,6 +14,7 @@ type Mutator<T> = (value: T) => void;
/** /**
* Signal is a reactive value that can be set, updated or mutated * Signal is a reactive value that can be set, updated or mutated
* *
* @example
* ```ts * ```ts
* const count = useSignal(0); * const count = useSignal(0);
* *
@ -56,14 +64,43 @@ export interface Signal<T> {
* @param mutator * @param mutator
*/ */
mutate(mutator: Mutator<T>): void; mutate(mutator: Mutator<T>): void;
/**
* Get the reference of the signal
*
* Sometimes it can be useful to make `v-model` work with the signal
*
* ```vue
* <template>
* <input v-model="model.count" />
* </template>;
*
* <script setup lang="ts">
* const state = useSignal({ count: 0 }, { useRef: true });
*
* const model = state.getRef();
* </script>
* ```
*/
getRef(): Readonly<ShallowRef<Readonly<T>>>;
} }
export interface ReadonlySignal<T> { export interface ReadonlySignal<T> {
(): Readonly<T>; (): Readonly<T>;
} }
export function useSignal<T>(initialValue: T): Signal<T> { export interface SignalOptions {
const state = shallowRef(initialValue); /**
* Whether to use `ref` to store the value
*
* @default false use `sharedRef` to store the value
*/
useRef?: boolean;
}
export function useSignal<T>(initialValue: T, options?: SignalOptions): Signal<T> {
const { useRef } = options || {};
const state = useRef ? (ref(initialValue) as Ref<T>) : shallowRef(initialValue);
return createSignal(state); return createSignal(state);
} }
@ -101,5 +138,7 @@ function createSignal<T>(state: ShallowRef<T> | WritableComputedRef<T>): Signal<
triggerRef(state); triggerRef(state);
}; };
signal.getRef = () => state as Readonly<ShallowRef<Readonly<T>>>;
return signal; return signal;
} }