基于后端项目的前端开发实践记录

📋 项目概述

项目名称: 比特奥定制报表系统
技术栈: Vue 3 + Element Plus + Vite (前端) + Spring Boot (后端)
开发模式: 前后端分离
项目结构: 单体仓库包含前后端代码

🏗️ 项目架构分析

目录结构设计

bitao-defined_report_ui/
├── src/                    # 前端源码
│   ├── api/               # API接口层
│   ├── components/        # 组件库
│   │   ├── dict/         # 字典管理组件
│   │   ├── report/       # 报表管理组件
│   │   └── layout/       # 布局组件
│   ├── router/           # 路由配置
│   └── utils/            # 工具函数
├── backend/               # 后端源码
│   └── bitao-defined-report/
└── public/               # 静态资源

技术选型理由

  1. Vue 3: 组合式API,更好的TypeScript支持
  2. Element Plus: 成熟的UI组件库,快速开发
  3. Vite: 快速的构建工具,热更新体验好
  4. Axios: HTTP客户端,支持拦截器和请求/响应处理

🔄 前后端协作流程

1. API设计先行

后端API规范
// 统一响应格式
public class ApiResponse<T> {private String traceId;     // 追踪IDprivate boolean result;     // 操作结果private int code;          // 状态码private String msg;        // 消息private T data;           // 数据private boolean success;   // 成功标识
}// 分页参数基类
public class PageObject {private Integer pageNum = 1;private Integer pageSize = 10;private String isAsc = "desc";
}
前端API封装
// api/reportApi.js
import request from '@/utils/request'/*** 获取报表列表* @param {Object} params 查询参数* @returns {Promise} API响应*/
export function getReportList(params) {return request({url: '/defined-report/report/selectByPage',method: 'post',data: params})
}

2. 数据类型对齐

关键经验:类型一致性
场景后端类型前端处理注意事项
布尔状态Booleannull/true/false避免空字符串
分页参数IntegerNumber确保数值类型
时间字段LocalDateTimeString统一格式化
枚举值EnumString/Number保持值一致
实际案例:状态字段处理
// ❌ 错误做法
const queryParams = {usableStatus: ''  // 空字符串无法转换为Boolean
}// ✅ 正确做法
const queryParams = {usableStatus: null  // null表示不筛选,true/false表示具体状态
}

🎨 组件开发模式

1. 页面组件结构

标准页面模板
<template><div class="page-container"><!-- 查询表单 --><div class="search-form"><el-form :model="queryParams" :inline="true"><!-- 查询条件 --></el-form></div><!-- 操作工具栏 --><div class="toolbar"><el-button type="primary" @click="handleAdd">新增</el-button></div><!-- 数据表格 --><el-table :data="dataList" v-loading="loading"><!-- 表格列 --></el-table><!-- 分页组件 --><pagination v-model:page="queryParams.pageNum"v-model:limit="queryParams.pageSize":total="total"@pagination="getList"/></div>
</template><script setup>
import { reactive, ref, onMounted } from 'vue'
import { ElMessage } from 'element-plus'// 响应式数据
const loading = ref(false)
const dataList = ref([])
const total = ref(0)// 查询参数
const queryParams = reactive({pageNum: 1,pageSize: 10,// 其他查询字段
})// 获取列表数据
const getList = async () => {loading.value = truetry {const response = await apiMethod(queryParams)if (response.code === 200) {dataList.value = response.data.data || []total.value = response.data.total || 0} else {ElMessage.error(response.message || '获取数据失败')}} catch (error) {console.error('获取数据失败:', error)ElMessage.error('网络错误,请稍后重试')} finally {loading.value = false}
}// 页面初始化
onMounted(() => {getList()
})
</script>

2. 组件复用策略

通用组件抽取
// components/pub/Pagination.vue - 分页组件
// components/layout/AppHeader.vue - 页面头部
// components/layout/Sidebar.vue - 侧边栏
业务组件分类
// components/dict/ - 字典管理相关组件
// components/report/ - 报表管理相关组件
//   ├── management/ - 报表列表管理
//   ├── designer/ - 报表设计器
//   └── preview/ - 报表预览

🔧 开发工具配置

1. Vite配置优化

// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'export default defineConfig({plugins: [vue()],resolve: {alias: {'@': path.resolve(__dirname, 'src')}},server: {port: 3000,proxy: {'/defined-report': {target: 'http://localhost:8080',changeOrigin: true}}}
})

2. 请求拦截器配置

// utils/request.js
import axios from 'axios'
import { ElMessage } from 'element-plus'const service = axios.create({baseURL: process.env.VUE_APP_BASE_API,timeout: 5000
})// 请求拦截器
service.interceptors.request.use(config => {// 添加token等通用处理return config},error => {console.log(error)return Promise.reject(error)}
)// 响应拦截器
service.interceptors.response.use(response => {const res = response.data// 统一错误处理if (res.code !== 200) {ElMessage.error(res.message || '系统错误')return Promise.reject(new Error(res.message || 'Error'))}return res},error => {console.log('err' + error)ElMessage.error(error.message)return Promise.reject(error)}
)export default service

🐛 常见问题与解决方案

1. 分页查询问题

问题描述

前端发送分页请求时,后端返回"系统繁忙"错误

根本原因
  1. 参数类型不匹配(字符串 vs 布尔值)
  2. 缺少默认分页参数
解决方案
// 前端:确保参数类型正确
const queryParams = reactive({pageNum: 1,           // Number类型pageSize: 10,         // Number类型usableStatus: null    // null/Boolean类型
})
// 后端:添加默认构造函数
public ReportFormsPageParam() {super();this.setPageNum(1);this.setPageSize(10);this.setIsAsc("desc");
}

2. 状态管理最佳实践

组件内状态
// 使用 reactive 管理表单数据
const formData = reactive({name: '',status: null
})// 使用 ref 管理简单状态
const loading = ref(false)
const visible = ref(false)
跨组件状态
// 使用 provide/inject
// 父组件
provide('userInfo', userInfo)// 子组件
const userInfo = inject('userInfo')

📊 性能优化实践

1. 组件懒加载

// router/index.js
const routes = [{path: '/report/list',component: () => import('@/components/report/management/ReportList.vue')}
]

2. 表格虚拟滚动

<!-- 大数据量表格优化 -->
<el-table-v2:columns="columns":data="data":width="700":height="400"fixed
/>

3. 请求防抖

import { debounce } from 'lodash-es'// 搜索防抖
const handleSearch = debounce(() => {getList()
}, 300)

🔍 调试与测试

1. 开发调试

// 开发环境日志
if (process.env.NODE_ENV === 'development') {console.log('API请求参数:', params)console.log('API响应数据:', response)
}

2. API测试

# 使用PowerShell测试API
Invoke-WebRequest -Uri 'http://localhost:3000/defined-report/report/selectByPage' `-Method POST `-ContentType 'application/json' `-Body '{"pageNum": 1, "pageSize": 10}'

📝 开发规范

1. 命名规范

  • 文件命名: PascalCase (ReportList.vue)
  • 组件名: PascalCase (ReportList)
  • 方法名: camelCase (handleQuery)
  • 常量名: UPPER_SNAKE_CASE (API_BASE_URL)

2. 代码注释

/*** 获取报表列表数据* @param {Object} params 查询参数* @param {Number} params.pageNum 页码* @param {Number} params.pageSize 每页大小* @returns {Promise<Object>} 返回报表列表数据*/
const getReportList = async (params) => {// 实现逻辑
}

3. 错误处理

try {const response = await apiCall()// 成功处理
} catch (error) {console.error('操作失败:', error)ElMessage.error('操作失败,请稍后重试')// 错误恢复逻辑
}

🚀 部署与发布

1. 构建配置

// package.json
{"scripts": {"dev": "vite","build": "vite build","preview": "vite preview"}
}

2. 环境配置

// .env.development
VUE_APP_BASE_API = '/api'
VUE_APP_ENV = 'development'// .env.production
VUE_APP_BASE_API = 'https://api.example.com'
VUE_APP_ENV = 'production'

📈 项目总结

成功经验

  1. 前后端类型对齐: 避免了大量的类型转换问题
  2. 组件化开发: 提高了代码复用性和维护性
  3. 统一错误处理: 提升了用户体验
  4. API层抽象: 便于接口管理和维护

改进建议

  1. 引入TypeScript: 提供更好的类型安全
  2. 添加单元测试: 保证代码质量
  3. 性能监控: 添加性能指标收集
  4. 文档完善: 建立完整的组件文档

技术债务

  1. 部分组件耦合度较高,需要进一步解耦
  2. 缺少统一的状态管理方案
  3. 错误边界处理不够完善
  4. 缺少自动化测试覆盖

🎯 最佳实践总结

  1. API优先设计: 前后端并行开发的基础
  2. 类型一致性: 减少运行时错误的关键
  3. 组件化思维: 提高开发效率的核心
  4. 错误处理: 用户体验的重要保障
  5. 性能意识: 从开发阶段就要考虑性能优化
  6. 文档驱动: 良好的文档是团队协作的基础

通过这个项目的实践,我们建立了一套完整的前端开发流程和规范,为后续项目提供了宝贵的经验和参考。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/92255.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/92255.shtml
英文地址,请注明出处:http://en.pswp.cn/web/92255.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NFC 三大模式对比

以前以为nfc只是点对点通讯&#xff0c;没想到现在nfc的功能很强大NFC 三大模式对比&#xff08;回顾&#xff09;模式作用手机是...Reader 模式读取卡、标签内容主动设备&#xff08;读卡器&#xff09;Card Emulation 模式模拟公交卡/门禁卡/银行卡被动设备&#xff08;卡&am…

JSON、JSONObject、JSONArray详细介绍及其应用方式

第一部分&#xff1a;什么是JSON?&#x1f31f;比喻&#xff1a;JSON 是「快递公司统一的 “通用快递单”」&#x1f4a1;场景代入你想给朋友寄生日礼物&#xff08;比如一台 “游戏机”&#xff09;&#xff0c;这台游戏机有自己的属性&#xff1a;名称&#xff1a;"游戏…

Linux系统编程--权限管理

权限管理第二讲 权限管理1. Shell命令以及运行原理1.1 知识引入1.2 概念介绍1.3 具体示例2. Linux权限问题2.1 权限概念2.2 用户分类2.3 切换用户2.4 用户提权2.5 文件权限管理2.5.1 文件访问者的分类&#xff08;角色&#xff09;2.5.2 文件类型和访问权限&#xff08;事物属性…

【智能硬件】X86和ARM架构的区别

详细解释X86架构和ARM架构之间的区别以及它们各自的特点。X86 架构定义与历史定义&#xff1a;X86是一种计算机处理器体系结构&#xff0c;最初由英特尔公司开发。它是一系列指令集的集合体。历史&#xff1a;最早的X86架构是Intel 8086处理器&#xff0c;在1978年发布。后续发…

玳瑁的嵌入式日记D13-0806(C语言)

指针1.指针指针 就是地址(地址就是内存单元的编号)指针变量 (结合语境) eg&#xff1a;定义一个指针指针这一类数据 --- 数据类型 --- 指针类型 (1).指针 是什么 (2).指针类型 int a; //int数据类型 a是int型变量 //a的空间 想来存储 整型数据 2.指针的定义 基类型 * 指针变量名…

密码学基础知识总结

密码学基础知识总结 一、Base编码 1. Base系列特征 编码类型字符集特征Base160-9, A-F密文长度偶数Base32A-Z, 2-7包含数字2-7Base64a-z,0-9,,/,密文长度是8的倍数Base36A-Z,0-9仅支持整数加密Base910-9,a-z,A-Z,特殊符号高密度编码Base100Emoji表情表情符号组成 2. 典型题型…

PostgreSQL 中 pg_wal文件过多过大的清理方法及关键注意事项的总结

PostgreSQL 中 pg_wal文件过多过大的清理方法及关键注意事项的总结 以下是针对 PostgreSQL 中 pg_wal 文件过多过大的清理方法及关键注意事项的总结 一、安全清理 WAL 文件的完整流程 1. 确认数据库和备份完整性 备份验证&#xff1a;确保最近的物理备份&#xff08;如 pg_base…

Django事务支持

1.事务概念 事务是一组不可分割的操作序列&#xff0c;这些操作要么全部执行&#xff0c;要么全部不执行。事务具有四个关键属性&#xff0c;通常称为 ACID 特性&#xff1a; 原子性&#xff08;Atomicity&#xff09;&#xff1a;事务是一个不可分割的工作单位&#xff0c;事务…

<form> + <iframe> 方式下载大文件的机制

使用 <form> <iframe> 方式下载大文件的机制之所以稳定&#xff0c;核心在于其‌分块传输‌和‌浏览器沙箱隔离‌设计。以下是技术原理详解&#xff1a; 一、底层工作机制 ‌分块传输协议‌ 表单提交后&#xff0c;服务器按 Transfer-Encoding: chunked 分块返回数…

Python--OCR(2)

一、明确 OCR 任务边界首先定义 OCR 系统的核心目标&#xff1a;场景&#xff1a;印刷体&#xff08;如文档、发票&#xff09;/ 手写体&#xff08;如笔记&#xff09;/ 特定场景&#xff08;如车牌、身份证&#xff09;输入&#xff1a;图像格式&#xff08;JPG/PNG&#xff…

基于Django的计算机资源爬虫及可视化系统的设计与实现

文章目录有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试可以私信博主一、项目背景二、项目目标三、系统架构与技术选型四、系统功能模块五、应用场景与价值六、项目特色与创新点七、总结每文一语有需要本项目的代码或文档以及全部资源&#xff0c;或者部署调试…

SH3001六轴传感器应用(二)(IIC驱动开发)

一、前言我这边使用的开发板原本已经做好了该sensor的驱动&#xff0c;但是使用过程中发现&#xff0c;原始驱动sensor是通过事件的方式上报的&#xff0c;加速度和陀螺仪数据并不同步&#xff0c;不满足使用要求&#xff0c;只有重新写一个iic的驱动&#xff0c;进行sensor数据…

面试题:基础的sql命令

基础的 SQL 命令主要用于对数据库进行查询、新增、修改、删除等操作&#xff0c;可分为以下几类&#xff1a;一、数据查询&#xff08;SELECT&#xff09;用于从表中获取数据&#xff0c;是最常用的命令。 基本语法&#xff1a;SELECT 列名1, 列名2... FROM 表名 WHERE 条件;示…

Leetcode-3488距离最小相等元素查询

依旧二分&#xff0c;链接如下3488. 距离最小相等元素查询 看题目是个循环数组&#xff0c;记得当时做过一道什么题也是循环数组&#xff0c;就想着直接数组复制一下&#xff0c;然后跟上一道题一样&#xff0c;用hashmap来存储value的值以及value对应下标的vector。 和灵神的…

C++中的关联容器

文章目录使用关联容器定义关联容器关键字类型的要求pair类型用作返回类型关联容器上的操作关联容器的迭代器关联容器和算法添加元素删除元素map的下标操作访问元素无序容器对关键字的要求关联容器支持高效的关键字查找和访问。两个主要的关联容器的类型是map和set。其中map中的…

【Git】git提交代码报错Git: husky > pre-commit

git提交代码报错原因 这个问题是因为当你在终端输入git commit -m “XXX”,提交代码的时候,pre-commit(客户端)钩子&#xff0c;它会在Git键入提交信息前运行做代码风格检查。如果代码不符合相应规则&#xff0c;则报错&#xff0c;而它的检测规则就是根据.git/hooks/pre-commi…

Unity开发者快速认识Unreal 的C++(六)GameMode之PlayerController

继承关系&#xff1a;Aactor&#xff0c;INavAgentInterface <--- AController<--- PlayerController &#xff0c;PlayerController也是一个Actor,继承了Actor的一些通用的属性和工具函数下图是PlayerController初始化组件的一个子阶段从图中可以得到的信息是&#xf…

Vue 3 服务端渲染(SSR)与客户端渲染(CSR)的区别及解决方案

1. SSR与CSR的区别1.1. SSR的原理服务端渲染&#xff08;SSR&#xff09;是在服务器端将 Vue 组件渲染为 HTML 字符串&#xff0c;并将其发送给客户端。这种方式与客户端渲染&#xff08;CSR&#xff09;不同&#xff0c;后者是在浏览器中执行 JavaScript 来生成 HTML。在 SSR …

Matlab快速回顾

一1.数值 显示 格式format style 设置eg: pi format longE;or2.清除指令clc 清除命令行窗口clear 清除工作区cls3.搜索路径设置path(path,E:\ads\)oraddpath4.M文件用户把要实现的命令写在一个以.m为扩展的文件中&#xff0c;然后由matlab系统进行解读&#xff0c;最后运行结果…

开源低代码+AI引擎:百特搭企业级开发平台的演进

在数字化转型进入深水区的今天&#xff0c;企业应用开发面临前所未有的复杂挑战&#xff1a;既要快速响应业务需求&#xff0c;又要确保系统灵活可控&#xff1b;既要降低技术门槛&#xff0c;又要保障核心安全。传统开发模式与单一形态的低代码工具已难以满足多层次需求。融合…