不习惯的 Vue3 起步五 のapiHooks 封装

举报
空城机 发表于 2022/07/13 08:58:45 2022/07/13
【摘要】 在前端开发过程中,对于 Api 接口通常会进行封装,这里 vue3 中因为添加了 typescript,所以也再来写写有 TS 的简单封装方式

使用请求Hooks完善业务

在前端开发过程中,对于Api接口通常会进行封装,这里vue3中因为添加了typescript,所以也再来写写。

本次接口使用的是网上找的公开api:https://tenapi.cn/zhihuresou/,请求出来的数据是知乎热搜榜

返回数据格式:

{
  "data": 200,
  "list": [
    {
      "name": "lpl",
      "query": "FPX 不敌 iG 遭淘汰",
      "url": "https://www.zhihu.com/search?q=lpl&utm_content=search_hot&type=content"
    }
  ]
}

fetch请求封装

  1. 在项目src文件夹下创建一个hooks文件夹,然后创建一个index.ts文件和useApi.ts文件。在useApi.ts文件中主要编写api访问方法

  1. useApi.ts文件,创建一个useApi方法,此方法的输出结果受泛型控制,并且传入两个参数,url和options。

该方法内部的url请求是使用了fetch请求, RequestInfoRequestInit类型不需要额外定义,这是ts里本身就有的

对于抛出方式,可以选择两种都写,这样外部使用时可选性会广一些。

方法中用了泛型,<T>可以帮助捕获用户传入的类型,T可以赋值给之后传入参数value和返回值,来作为它们的类型。

function useApi<T>(url: RequestInfo, options?: RequestInit) {
    const response:Ref<undefined | T> = ref();
    const request = async () => {
        const res = await fetch(url, options);
        const data = await res.json();
        response.value = data;
    }
    return {
        response,
        request
    }
}
// 两种抛出方式
export default useApi;
export {
    useApi
}
  1. 这里可以设置一个接口,作为useApi方法返回的类型接口
export type ApiRequest = ()=>Promise<void>;
export interface UsableAPI<T> {
    response:Ref<undefined | T>,
    request: ApiRequest
}
  1. 在切换到hooks目录下的index.ts,这是此文件夹的入口文件,外部要调用hooks内部的所有方法,都需要通过index.ts获取

在index.ts中添加 export { useApi } from './useApi';




quicktype

从接口获取到数据,在ts往往也需要将其转换为类型模型,这样之前的泛型中才能使用

可以自己依旧数据来写,也可以使用quicktype快速生成

quicktype从JSON、JSON模式、TypeScript和GraphQL查询生成强类型模型和序列化程序,使在许多编程语言中安全地使用JSON类型变得轻而易举。 仓库:https://github.com/quicktype/quicktype

我选择了全局安装: npm install -g quicktype, 如果图方便,可以直接使用网页https://app.quicktype.io/来进行生成

全局安装完成后,在vs code终端中打开要生成ts接口类型文件的对应models文件夹,然后输入命令:quicktype 接口地址 -o 文件名称.ts

在刚刚创建的models文件zhihu.ts中,可以编写一个模型方法,用于调用数据。此方法中通过引用之前写好的useApi方法获取接口数据

import { useApi } from '@/hooks'
import { Ref, ref } from 'vue';
export default async function useZhihu():Promise<Ref<Zhihu>> {
    const { response: result, request } = await useApi<Zhihu>('https://tenapi.cn/zhihuresou/');
    // 发起一次请求
    const loaded = ref(false)
    if (loaded.value === false) {
        await request();
        loaded.value = true;
    }
    return result;
}

vue组件中调用

在子组件中调用起来比较简单,直接引入使用即可,并且可以直接await调用方法。在上面template中渲染时,也和vue2的用法相同。

<template>
    <ul class="zhihu">
        <li v-for="(item) in res.list">{{ item.name }}</li>
    </ul>
</template>

<script setup lang="ts">
    import useZhihu from '@/models/zhihu'

    const res = await useZhihu();
</script>

不过,当运行程序后,会发现界面并不显示,这是因为异步组件,界面需要使用Suspense包裹,这是vue3新出的特性

<Suspense>
    <template #default>
        <apihookTest></apihookTest>
    </template>
    <template #fallback>
    loading...
    </template>
</Suspense>

效果:


至此,基于vue3 + typescript的简单apihooks封装就已经结束了

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。