Skip to content

3.9 前端联调指引 ​

概述

后端接口开发完成后,需要在前端创建对应的 API 模块和页面组件。本节以 example 模块为例,提供简要指引,详细内容参考第 9 章。

联调流程 ​

text
1. 创建 API 模块      → ui/src/api/tool/example.ts
2. 创建页面组件       → ui/src/views/tool/example/index.vue
3. 配置菜单组件路径   → 后端菜单管理中设置 component
4. 测试联调

步骤一:创建 API 模块 ​

在 ui/src/api/tool/ 下创建 example.ts(来自项目实际代码):

typescript
// ui/src/api/tool/example.ts
import { http } from '@/utils/http/axios';

/**
 * 案例演示模块接口
 *
 * 提供案例演示的增删改查及导入导出接口调用。
 */

/**
 * 获取案例演示分页列表
 *
 * @param params 查询参数,包含 pageNo、pageSize 及业务筛选条件
 * @returns 分页结果,含 records、total、size、current、pages
 */
export function getExamplePage(params?: Record<string, any>) {
  return http.request({
    url: '/example/page',
    method: 'GET',
    params,
  });
}

/**
 * 获取全部案例演示列表
 *
 * @param params 查询参数
 * @returns 案例演示列表
 */
export function getExampleList(params?: Record<string, any>) {
  return http.request({
    url: '/example/list',
    method: 'GET',
    params,
  });
}

/**
 * 根据 ID 获取案例演示详情
 *
 * @param id 案例演示ID
 * @returns 案例演示详情数据
 */
export function getExampleDetail(id) {
  return http.request({
    url: '/example/detail/' + id,
    method: 'get',
  });
}

/**
 * 添加案例演示
 *
 * @param data 案例演示数据
 * @returns 新记录的 ID
 */
export function exampleAdd(data: any) {
  return http.request({
    url: '/example/add',
    method: 'POST',
    data,
  });
}

/**
 * 更新案例演示
 *
 * @param data 案例演示数据,需包含主键 id
 * @returns 操作结果
 */
export function exampleUpdate(data: any) {
  return http.request({
    url: '/example/update',
    method: 'PUT',
    data,
  });
}

/**
 * 删除案例演示
 *
 * @param id 案例演示ID
 * @returns 操作结果
 */
export function exampleDelete(id) {
  return http.request({
    url: '/example/delete/' + id,
    method: 'DELETE',
  });
}

/**
 * 批量删除案例演示
 *
 * @param data 含 ids 数组的对象,形如 { ids: [1, 2, 3] }
 * @returns 操作结果
 */
export function exampleBatchDelete(data: any) {
  return http.request({
    url: '/example/batchDelete',
    method: 'DELETE',
    data,
  });
}

/**
 * 导入案例演示
 *
 * @param data 文件数据(FormData)
 * @returns 导入结果,含成功数量与失败明细
 */
export function exampleImport(data) {
  return http.request({
    url: '/example/import',
    method: 'POST',
    data,
  });
}

/**
 * 导出案例演示
 *
 * @param params 查询参数
 * @returns 导出文件的 URL
 */
export function exampleExport(params) {
  return http.request({
    url: '/example/export',
    method: 'GET',
    params,
  });
}

步骤二:创建页面组件 ​

在 ui/src/views/tool/example/ 下创建以下 5 个文件:

文件说明
index.vue列表页(表格 + 搜索 + 分页)
edit.vue新增/编辑弹窗表单
detail.vue详情查看页
columns.ts表格列定义
querySchemas.ts搜索表单字段定义

关于以下示例

以下代码使用原生 el-table / el-form 简化展示核心逻辑。实际项目中应使用封装好的 BasicTable + useForm 等组合式组件,详见第 9 章组件文档。

index.vue(列表页)示例:

vue
<!-- ui/src/views/tool/example/index.vue -->
<template>
  <div>
    <!-- 搜索表单 -->
    <el-form :model="searchForm" inline>
      <el-form-item label="名称">
        <el-input v-model="searchForm.name" placeholder="请输入名称" />
      </el-form-item>
      <el-form-item label="状态">
        <el-select v-model="searchForm.status" placeholder="请选择" clearable>
          <el-option label="启用" :value="1" />
          <el-option label="禁用" :value="0" />
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="handleSearch">搜索</el-button>
        <el-button @click="handleReset">重置</el-button>
      </el-form-item>
    </el-form>

    <!-- 操作按钮 -->
    <el-button type="primary" @click="handleAdd">新增</el-button>
    <el-button type="danger" :disabled="!selectedIds.length" @click="handleBatchDelete">
      批量删除
    </el-button>

    <!-- 数据表格 -->
    <el-table :data="tableData" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" />
      <el-table-column prop="id" label="ID" width="80" />
      <el-table-column prop="name" label="名称" />
      <el-table-column prop="typeText" label="类型" width="100" />
      <el-table-column prop="statusText" label="状态" width="100" />
      <el-table-column prop="sort" label="排序" width="80" />
      <el-table-column prop="createTime" label="创建时间" width="180" />
      <el-table-column label="操作" width="200">
        <template #default="{ row }">
          <el-button size="small" @click="handleEdit(row)">编辑</el-button>
          <el-button size="small" type="danger" @click="handleDelete(row.id)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页 -->
    <el-pagination
      v-model:current-page="pageNo"
      v-model:page-size="pageSize"
      :total="total"
      @current-change="fetchData"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { getExamplePage, exampleDelete, exampleBatchDelete } from '@/api/tool/example';

const searchForm = ref({ name: '', status: '' });
const tableData = ref([]);
const pageNo = ref(1);
const pageSize = ref(20);
const total = ref(0);
const selectedIds = ref([]);

const fetchData = async () => {
  const res = await getExamplePage({
    pageNo: pageNo.value,
    pageSize: pageSize.value,
    ...searchForm.value,
  });
  tableData.value = res.records;
  total.value = res.total;
};

const handleSearch = () => { pageNo.value = 1; fetchData(); };
const handleReset = () => { searchForm.value = { name: '', status: '' }; handleSearch(); };
const handleDelete = async (id: number) => { await exampleDelete(id); fetchData(); };
const handleBatchDelete = async () => { await exampleBatchDelete({ ids: selectedIds.value }); fetchData(); };
const handleSelectionChange = (rows: any[]) => { selectedIds.value = rows.map((r) => r.id); };

onMounted(() => fetchData());
</script>

步骤三:配置菜单 ​

在后端菜单管理中,将组件路径设置为:

text
tool/example/index

前端路由系统会自动将此路径映射到 ui/src/views/tool/example/index.vue。

步骤四:测试联调 ​

  1. 确保后端服务运行:php think run
  2. 确保前端服务运行:pnpm dev
  3. 刷新前端页面,侧边栏应出现"案例演示"菜单
  4. 点击菜单,测试增删改查功能

详细前端开发内容请参考第 9 章。

小蚂蚁云团队 · 提供技术支持