感谢阅读本文 · 欢迎在下方留言交流你的想法
探索更多文章 →共 0 条
tsximport { 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); }
tsimport { 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, }; }, });
ts
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;