vue3 中的 hooks 就是函数的一种写法,就是将文件的一些单独功能的 js 代码进行抽离出来进行封装使用。
其实 hooks 和 vue2 中的 mixin 有点类似,但是相对 mixins 而言, hooks 更清楚复用功能代码的来源, 更清晰易懂。
利用 TS 泛型强化类型检查
需求 2: 封装发 ajax 请求的 hook 函数
hooks/useRequest.ts
import { ref } from "vue";
import axios from "axios";
/*
使用axios发送异步ajax请求
*/
export default function useUrlLoader<T>(url: string) {
const result = (ref < T) | (null > null);
const loading = ref(true);
const errorMsg = ref(null);
axios
.get(url)
.then((response) => {
loading.value = false;
result.value = response.data;
})
.catch((e) => {
loading.value = false;
errorMsg.value = e.message || "未知错误";
});
return {
loading,
result,
errorMsg,
};
}
<template>
<div class="about">
<h2 v-if="loading">LOADING...</h2>
<h2 v-else-if="errorMsg">{{ errorMsg }}</h2>
<!-- <ul v-else>
<li>id: {{result.id}}</li>
<li>name: {{result.name}}</li>
<li>distance: {{result.distance}}</li>
</ul> -->
<ul v-for="p in result" :key="p.id">
<li>id: {{ p.id }}</li>
<li>title: {{ p.title }}</li>
<li>price: {{ p.price }}</li>
</ul>
<!-- <img v-if="result" :src="result[0].url" alt=""> -->
</div>
</template>
<script lang="ts">
import { watch } from "vue";
import useRequest from "./hooks/useRequest";
// 地址数据接口
interface AddressResult {
id: number;
name: string;
distance: string;
}
// 产品数据接口
interface ProductResult {
id: string;
title: string;
price: number;
}
export default {
setup() {
// const {loading, result, errorMsg} = useRequest<AddressResult>('/data/address.json')
const { loading, result, errorMsg } = useRequest<ProductResult[]>(
"/data/products.json"
);
watch(result, () => {
if (result.value) {
console.log(result.value.length); // 有提示
}
});
return {
loading,
result,
errorMsg,
};
},
};
</script>