前端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>
相关推荐
IT_陈寒10 分钟前
Java性能优化:从这8个关键指标开始,让你的应用提速50%
前端·人工智能·后端
天生我材必有用_吴用12 分钟前
Vue3+Node.js 实现大文件上传:断点续传、秒传、分片上传完整教程(含源码)
前端
摸鱼的春哥28 分钟前
前端程序员最讨厌的10件事
前端·javascript·后端
牧羊狼的狼4 小时前
React 中的 HOC 和 Hooks
前端·javascript·react.js·hooks·高阶组件·hoc
知识分享小能手6 小时前
React学习教程,从入门到精通, React 属性(Props)语法知识点与案例详解(14)
前端·javascript·vue.js·学习·react.js·vue·react
魔云连洲6 小时前
深入解析:Vue与React的异步批处理更新机制
前端·vue.js·react.js
mCell6 小时前
JavaScript 的多线程能力:Worker
前端·javascript·浏览器
超级无敌攻城狮8 小时前
3 分钟学会!波浪文字动画超详细教程,从 0 到 1 实现「思考中 / 加载中」高级效果
前端
excel9 小时前
用 TensorFlow.js Node 实现猫图像识别(教学版逐步分解)
前端
前端工作日常9 小时前
我学习到的Vue2.6的prop修饰符
vue.js