前端API层架构设计

技术栈:vue3,typescript,naive-ui组件库,axios请求api库。
API层设计图

feedback.ts

ts 复制代码
import { createDiscreteApi, darkTheme } from 'naive-ui';

const { message, dialog, notification, loadingBar } = createDiscreteApi(
  ['message', 'dialog', 'notification', 'loadingBar'],
  {
    configProviderProps: { theme: darkTheme },
    messageProviderProps: { keepAliveOnHover: true },
  }
);

export { dialog, loadingBar, message, notification };

request.ts

封装http请求模块。axios.create(option)创建axios实例,option.headers.authorization-token用于预防CSRF(跨站请求伪造)攻击。loadingBar组件展示请求接口的进度。http请求拦截响应,如果status为401,表示登录状态过期,需要重新登录。

ts 复制代码
import axios from 'axios';
import { loadingBar, message } from './feedback';
const http = axios.create({
  baseURL: import.meta.env.API_HOST || '',
  withCredentials: true,
  headers: {
    'authorization-token': 'token',
  }
});
http.interceptors.request.use(
  async (config) => {
    loadingBar.start();
    return config;
  },
  (error) => {
    loadingBar.error();
    return Promise.reject(error);
  },
);

http.interceptors.response.use(
  async (response) => {
    loadingBar.finish();
    const { data } = response;
    return data;
  },
  (error) => {
    loadingBar.error();
    const { response, message: msg } = error;

    if (response?.status == 401) {
      message.error('登录状态过期, 请重新登录');
      router.replace({ path: '/login' });
    } else {
      if (response?.data) {
        const { data } = response;
        message.error(data?.msg || data?.message || msg);
      }
    }
    return Promise.reject(error);
  },
);
export default http;

通过封装的http模块请求服务端的接口,获取数据。getDataFromApi函数传入一个参数body,body的数据类型为DataBody,返回的数据是promise对象,promise对象resolve和reject的数据类型是<ApiRes<ReturnItem[]>>。
api.ts

ts 复制代码
import http from './request';

interface DataBody {//自定义数据类型
  startTime: string;
  endTime?: string;
}
interface ApiResWithoutData {
  status: boolean;
  msg: string;
  code?: number
}
interface ApiRes<T> extends ApiResWithoutData {//继承并新加字段
  data: T;
}
interface ReturnItem {
  id: number; 
  name: string;
  age: number;
}

export function getDataFromApi(
  body: DataBody,
): Promise<ApiRes<ReturnItem[]>> {
  const url = `/api/getData`;
  return http.post(url, { ...body });
}

封装组合式函数useTableList。对外提供响应式数据state和设置响应式数据的函数fetchData。 useTableList.ts

ts 复制代码
import { reactive } from 'vue';
import { getDataFromApi } from './api';
export interface ReturnItem {
  id: number; 
  name: string;
  age: number;
}
export function useTableList() {
  const state = reactive({
    tableData: [] as ReturnItem[],
    loading: false,
  });
  async function fetchData() {
    try {
      if (state.loading) {
        message.info('正在加载数据...');
        return;
      }

      const body: DataRBody = {
        startTime: '2024-02-03',
        endTime: '2025-06-08',
      };

      state.loading = true;
      const { data} = await getDataFromApi(body);
      state.loading = false;
      if (!data || !data.length) {
        message.warning('定位数据数量统计无数据');
      } else
        state.tableData = data;
      }
    } catch (error) {
      state.loading = false;
    }
  }
  
   return {
    state,
    fetchData,
  };
}

在业务中使用组合式函数useTableList。
tableList.vue

vue 复制代码
<template>
<n-data-table
    :columns="columns"
    :data="tableData"
    :bordered="false"
  />
</template>

<script lang="ts" setup>
  import { useTableList } from './compositionFn/useTableList';//使用组合式函数
  import { onMounted, ref} from 'vue';
  const colums = [
      { title: 'id', key: 'id' },
      { title: '名字', key: 'name' },
      { title: '年龄', key: 'age' },
  ];
  const tableData = ref(tableData);
  const { state: tableData, fetchData } = useTableList();
  onMounted(() => {
    fetchData();
  });
  
</script>

<style lang="scss" scoped>
</style>
相关推荐
华仔啊8 小时前
Vue3 如何实现图片懒加载?其实一个 Intersection Observer 就搞定了
前端·vue.js
JamesGosling6668 小时前
深入理解内容安全策略(CSP):原理、作用与实践指南
前端·浏览器
不要想太多8 小时前
前端进阶系列之《浏览器渲染原理》
前端
七喜小伙儿8 小时前
第2节:趣谈FreeRTOS--打工人的日常
前端
我叫张小白。8 小时前
Vue3 响应式数据:让数据拥有“生命力“
前端·javascript·vue.js·vue3
laocooon5238578868 小时前
vue3 本文实现了一个Vue3折叠面板组件
开发语言·前端·javascript
IT_陈寒9 小时前
React 18并发渲染实战:5个核心API让你的应用性能飙升50%
前端·人工智能·后端
科普瑞传感仪器9 小时前
从轴孔装配到屏幕贴合:六维力感知的机器人柔性对位应用详解
前端·javascript·数据库·人工智能·机器人·自动化·无人机
n***F8759 小时前
SpringMVC 请求参数接收
前端·javascript·算法
wordbaby9 小时前
搞不懂 px、dpi 和 dp?看这一篇就够了:图解 RN 屏幕适配逻辑
前端