前端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>
相关推荐
子非鱼a2 小时前
【WEB】[NewStarCTF 公开赛赛道]UnserializeOne
前端·javascript·html
南雨北斗2 小时前
Vue3 v-model中的自动事件绑定
前端
雪芽蓝域zzs4 小时前
第八节:Element Plus 基础、封装通用组件 + 路由守卫
前端·vue.js
码视野4 小时前
基于 Spring Boot + Vue3 的【智慧公厕微负压排风除臭与客流人感空间占用导引中台】设计与实现(含PRD/三端高保真源码/大屏)
前端·vue.js·人工智能·spring boot·后端
计算机魔术师4 小时前
刚赔了15亿又来被告?索尼华纳联手把Anthropic告上法庭
前端
笑霸final4 小时前
不用上传服务器!用 Vue3 + ONNX Runtime Web 在浏览器本地实现智能抠图
运维·前端·图像处理·ai·onnx·canva可画·web性能优化
月月大王的3D日记4 小时前
Three.js 入门系列(9):从零搭一座“闹鬼小屋”
前端·javascript
TingTing4 小时前
Vue3动态组件库建设
前端
码上暴富5 小时前
Cursor / VS Code 自定义文件颜色
前端·vscode
开开心心就好5 小时前
电子教鞭工具支持画框写字插图片功能齐全
android·开发语言·前端·javascript·人工智能·pdf·html