vue3中使用react风格语法
- 0
#讨论区
00条评论
实时对话
loading...
tsx
ts
ts
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;