mirror of
				https://github.com/soybeanjs/soybean-admin.git
				synced 2025-11-04 15:53:43 +08:00 
			
		
		
		
	feat(hooks): add state hooks: useRef, useState, useSignal
This commit is contained in:
		@@ -7,4 +7,5 @@ import useHookTable from './use-table';
 | 
			
		||||
 | 
			
		||||
export { useBoolean, useLoading, useCountDown, useContext, useSvgIconRender, useHookTable };
 | 
			
		||||
 | 
			
		||||
export * from './use-state';
 | 
			
		||||
export * from './use-table';
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										81
									
								
								packages/hooks/src/use-state.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								packages/hooks/src/use-state.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
			
		||||
import { ref } from 'vue';
 | 
			
		||||
import type { Ref } from 'vue';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * useRef
 | 
			
		||||
 *
 | 
			
		||||
 * it is a simple ref management hook wrapped by vue3's ref function.
 | 
			
		||||
 *
 | 
			
		||||
 * to resolve the ref type problem about `UnwrapRef`
 | 
			
		||||
 *
 | 
			
		||||
 * @param initValue
 | 
			
		||||
 */
 | 
			
		||||
export function useRef<T>(initValue: T) {
 | 
			
		||||
  const refValue = ref(initValue) as Ref<T>;
 | 
			
		||||
 | 
			
		||||
  return refValue;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * useState
 | 
			
		||||
 *
 | 
			
		||||
 * define a state and a setState function
 | 
			
		||||
 *
 | 
			
		||||
 * @param initValue
 | 
			
		||||
 */
 | 
			
		||||
export function useState<T>(initValue: T) {
 | 
			
		||||
  const state = useRef(initValue);
 | 
			
		||||
 | 
			
		||||
  function setState(value: T) {
 | 
			
		||||
    state.value = value;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return [state, setState] as const;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface Signal<T> {
 | 
			
		||||
  (): T;
 | 
			
		||||
  /**
 | 
			
		||||
   * the ref object of the signal, but it is readonly
 | 
			
		||||
   *
 | 
			
		||||
   * equal to `const ref = ref(initValue);`
 | 
			
		||||
   */
 | 
			
		||||
  readonly ref: Readonly<Ref<T>>;
 | 
			
		||||
  /**
 | 
			
		||||
   * set the value of the signal
 | 
			
		||||
   *
 | 
			
		||||
   * @param value
 | 
			
		||||
   */
 | 
			
		||||
  set(value: T): void;
 | 
			
		||||
  /**
 | 
			
		||||
   * update the value of the signal
 | 
			
		||||
   *
 | 
			
		||||
   * @param fn update function
 | 
			
		||||
   */
 | 
			
		||||
  update(fn: (value: T) => T): void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * useSignal
 | 
			
		||||
 *
 | 
			
		||||
 * @param initValue
 | 
			
		||||
 */
 | 
			
		||||
export function useSignal<T>(initValue: T) {
 | 
			
		||||
  const [state, setState] = useState(initValue);
 | 
			
		||||
 | 
			
		||||
  function updateState(fn: (value: T) => T) {
 | 
			
		||||
    const updatedValue = fn(state.value);
 | 
			
		||||
    setState(updatedValue);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const signal = function signal() {
 | 
			
		||||
    return state.value;
 | 
			
		||||
  } as Signal<T>;
 | 
			
		||||
 | 
			
		||||
  (signal as any).ref = state;
 | 
			
		||||
 | 
			
		||||
  signal.set = setState;
 | 
			
		||||
  signal.update = updateState;
 | 
			
		||||
 | 
			
		||||
  return signal;
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user