vue3中使用react风格语法

    144
import { ref, UnwrapRef, reactive, watch, WatchOptions } from 'vue';

const isObject = (o): o is object => {
  return typeof o === 'object';
}

const isFunction = (f): f is Function => {
  return typeof f === 'function';
}

export const useState = <T>(defaultValue: T) => {
  if (isObject(defaultValue)) {
    return useStateObj(defaultValue);
  }
  const state = ref(defaultValue);
  const set = (value: T): void => {
    state.value = value as UnwrapRef<T>;
  };
  return [state, set];
};

const useStateObj = <O extends object>(defaultObj: O) => {
  const obj = reactive(defaultObj);
  const set = (valueObj: O): void => {
    Object.entries(valueObj).forEach(([key, val]) => {
      obj[key] = val;
    });
  };
  return [obj, set];
}

export const useEffect = (effectHandler, dependencies) => {
  return watch(dependencies, (changedDependencies, prevDependencies, onCleanUp) => {
    const effectCleaner = effectHandler(changedDependencies, prevDependencies);
    if (isFunction(effectCleaner)) {
      onCleanUp(effectCleaner);
    }
  }, { immediate: true, deep: true } as WatchOptions);
}
import { defineComponent } from 'vue';
import useSWR from './path-to-useSWR';

function fetcher(url: string) {
    return fetch(url).then(res => res.json());
}

export default defineComponent({
    setup() {
        const { data, isLoading, error, mutate } = useSWR('https://api.example.com/data', fetcher);

        return {
            data,
            isLoading,
            error,
            refreshData: mutate,
        };
    },
});
import { ref, watch, reactive } from 'vue';

interface SWRResponse<T> {
    data: T | null;
    error: any;
    isLoading: boolean;
    mutate: () => Promise<void>;
}

function useSWR<T = any>(url: string, fetcher: (url: string) => Promise<T>): SWRResponse<T> {
    const state = reactive({
        data: null as T | null,
        error: null as any,
        isLoading: true,
    });

    const fetchData = async () => {
        state.isLoading = true;

        try {
            const data = await fetcher(url);
            state.data = data;
        } catch (err) {
            state.error = err;
        } finally {
            state.isLoading = false;
        }
    };

    watch(url, fetchData, { immediate: true });

    return {
        get data() {
            return state.data;
        },
        get error() {
            return state.error;
        },
        get isLoading() {
            return state.isLoading;
        },
        mutate: fetchData,
    };
}

export default useSWR;
评论区
共有评论 0
暂无评论