前端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>
相关推荐
灿灿1213812 分钟前
CSS 文字浮雕效果:巧用 text-shadow 实现 3D 立体文字
前端·css
烛阴29 分钟前
Babel 完全上手指南:从零开始解锁现代 JavaScript 开发的超能力!
前端·javascript
AntBlack1 小时前
拖了五个月 ,不当韭菜体验版算是正式发布了
前端·后端·python
31535669131 小时前
一个简单的脚本,让pdf开启夜间模式
前端·后端
尘心cx1 小时前
前端-CSS-day1
前端·css
知否技术1 小时前
前端常说的 SCSS是个啥玩意?一篇文章给你讲的明明白白!
前端·scss
盛夏绽放1 小时前
Vue3 中 Excel 导出的性能优化与实战指南
vue.js·excel
幼儿园技术家1 小时前
Uniapp简易使用canvas绘制分享海报
前端
开开心心就好2 小时前
免费PDF处理软件,支持多种操作
运维·服务器·前端·spring boot·智能手机·pdf·电脑
全宝2 小时前
🎨前端实现文字渐变的三种方式
前端·javascript·css