前端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>
相关推荐
_r0bin_1 分钟前
前端面试准备-7
开发语言·前端·javascript·fetch·跨域·class
IT瘾君2 分钟前
JavaWeb:前端工程化-Vue
前端·javascript·vue.js
zhang98800002 分钟前
JavaScript 核心原理深度解析-不停留于表面的VUE等的使用!
开发语言·javascript·vue.js
potender4 分钟前
前端框架Vue
前端·vue.js·前端框架
站在风口的猪110839 分钟前
《前端面试题:CSS预处理器(Sass、Less等)》
前端·css·html·less·css3·sass·html5
程序员的世界你不懂1 小时前
(9)-Fiddler抓包-Fiddler如何设置捕获Https会话
前端·https·fiddler
MoFe11 小时前
【.net core】天地图坐标转换为高德地图坐标(WGS84 坐标转 GCJ02 坐标)
java·前端·.netcore
去旅行、在路上2 小时前
chrome使用手机调试触屏web
前端·chrome
Aphasia3112 小时前
模式验证库——zod
前端·react.js
lexiangqicheng3 小时前
es6+和css3新增的特性有哪些
前端·es6·css3