通过封装一个请求hook,在我们使用axios发送请求时,直接使用useRequest即可。不用再每发送一次请求写一遍axios请求。
request.ts
import { reactive, toRefs, onMounted, ComputedRef } from "vue";
import axios from "axios";
const defaultConfig = { immediate: true };
function useRequest(args: any) {
const { url, params = undefined, config = {} } = args;
const _params = params;
const combineConfig = { ...defaultConfig, ...config };
const {
initData,
immediate,
onSuccess,
onError,
...axiosConfig
} = combineConfig;
// 初始化请求返回值
const state = reactive({
loading: false,
error: false,
data: initData,
});
// 请求方法
const fetchFun = () => {
state.loading = true;
const method = "get";
return axios({
url: url.value ? url.value : url,
method,
params: _params?.value,
...axiosConfig,
})
.then((response) => {
const { data } = response;
if (data.code === 200) {
state.data = data.data;
state.loading = false;
if (typeof onSuccess === "function") {
onSuccess(data);
}
} else {
if (typeof onError === "function") {
onError(data);
}
}
})
.catch((err) => {
state.error = true;
state.loading = false;
});
};
//生命周期 mounted 发送请求
onMounted(() => {
if (immediate) {
fetchFun();
}
});
return { ...toRefs(state), fetch: fetchFun };
}
export default useRequest;
demo.vue
<script lang="ts">
import { computed, defineComponent, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import useRequest from '@/assets/ts/request'
import { MovieType } from '@/assets/interfaces'
interface InitDataType {
movie: Partial<MovieType>
relativeMovies: MovieType[]
}
export default defineComponent({
setup() {
const router = useRouter()
const route = useRoute()
// 初始化数据
const initData: InitDataType = { movie: {}, relativeMovies: [] }
// 请求成功的回调
const onSuccess = (res: any) => {
const { movie } = res.data
// do something
}
// 请求url
const reqUrl = computed(() => `/api/movie/${route.params.id}`)
// 使用useRequest 发送请求
const { data, loading, fetch } = useRequest({
url: reqUrl,
params: route.params.id,
config: {
initData,
onSuccess
}
})
// 监听路径上的id,变化则发送请求
watch(
() => route.params.id,
() => {
fetch()
}
)
return {
//.....
}
}
})
</script>