欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > 【路径查询组件优化记录:数据处理与显示逻辑重构】

【路径查询组件优化记录:数据处理与显示逻辑重构】

2025/3/13 13:51:49 来源:https://blog.csdn.net/weixin_37342647/article/details/146208155  浏览:    关键词:【路径查询组件优化记录:数据处理与显示逻辑重构】

路径查询组件优化记录:数据处理与显示逻辑重构

一、优化背景与目标

在路径查询系统中,station-display.vue 组件负责展示查询结果,包括线路名称、站点信息和换乘方案等关键信息。通过代码审查,发现了两个需要优化的问题:

  1. 线路名称显示错误:连接线上显示的线路名称取自下一个站点而非当前站点
  2. 数据处理分散:数据字段处理逻辑分散在多处,导致维护困难

优化目标是在不影响现有功能的前提下,修正显示错误并提高代码的可维护性。

二、具体改动点与前后对比

1. 线路名称显示逻辑修正

问题:在站点连接线上,线路名称错误地显示了下一个站点的线路,而非当前站点的线路。

修改前代码

<template v-for="(station, idx) in path.stations" :key="'conn-' + idx"><div v-if="idx < path.stations.length - 1" class="station-connection" :style="{left: `calc(${(idx + 0.5) * 100 / (path.stations.length - 1)}%)`,transform: 'translateX(-50%)'}"><span class="line-station-info">{{ path.stations[idx + 1].lineName ? path.stations[idx + 1].lineName.replace('地铁', '') : '' }}/{{path.stations[idx + 1].stationNum || 0 }}站</span></div>
</template>

修改后代码

<template v-for="(station, idx) in path.stations" :key="'conn-' + idx"><div v-if="idx < path.stations.length - 1" class="station-connection" :style="{left: `calc(${(idx + 0.5) * 100 / (path.stations.length - 1)}%)`,transform: 'translateX(-50%)'}"><span class="line-station-info">{{ path.stations[idx].lineName ? path.stations[idx].lineName.replace('地铁', '') : '' }}/{{path.stations[idx + 1].stationNum || 0 }}站</span></div>
</template>

效果对比

  • 修改前:连接线显示的是下一个站点的线路名称,例如从1号线到2号线的连接线会显示"2号线/3站"
  • 修改后:连接线显示的是当前站点的线路名称,例如从1号线到2号线的连接线会显示"1号线/3站"

视觉变化
用户现在能看到正确的线路信息,特别是在换乘点,能清晰地知道当前所在的线路,而不是错误地显示即将换乘的线路。

2. 数据处理逻辑集中化

a. 总站数显示字段统一

修改前代码

<div class="line-time-station"><span class="line-name">{{ path.lineName || '暂无线路名称' }}</span><span class="time-station" v-if="path.duration">{{secondToMinute(path.duration) }}分钟/{{ path.allNum || 0}}站</span>
</div>

修改后代码

<div class="line-time-station"><span class="line-name">{{ path.lineName || '暂无线路名称' }}</span><span class="time-station" v-if="path.duration">{{secondToMinute(path.duration) }}分钟/{{ path.totalStations || 0}}站</span>
</div>

效果对比

  • 修改前:直接使用API返回的allNum字段
  • 修改后:使用统一处理后的totalStations字段,但值仍来自API的allNum
b. 数据处理函数重构

修改前代码

// 处理站点数据
const processStations = (path) => {const stations = [];if (path.schedulesList && path.schedulesList.length > 0) {// 添加起始站stations.push({stationType: '0',stationName: path.originStationName || path.schedulesList[0]?.stationName || '',lineName: `${path.schedulesList[0]?.lineId || ''}号线`,stationNum: path.schedulesList[0]?.stationNum || 0});// 添加中间站/换乘站for (let i = 1; i < path.schedulesList.length; i++) {const station = path.schedulesList[i];const isLastStation = i === path.schedulesList.length - 1;stations.push({stationType: isLastStation ? '1' : '2',stationName: isLastStation ?(path.destStationName || station.stationName || '') :(station.stationName || ''),lineName: `${station.lineId || ''}号线`,stationNum: station.stationNum || 0});}} else if (path.originStationName && path.destStationName) {// 只有起终点信息的情况stations.push({stationType: '0',stationName: path.originStationName,lineName: `${path.originLineId || ''}号线`,stationNum: 0});stations.push({stationType: '1',stationName: path.destStationName,lineName: `${path.endLineId || ''}号线`,stationNum: 0});}return stations;
};// 查询按钮点击处理
const handleQuery = async () => {// ... 验证代码 ...try {// 调用API查询路径const response = await api.findOdPath(params);if (response && Array.isArray(response) && response.length > 0) {pathResults.value = response.map(path => ({programmeType: path.simpleType || 0,programmeIndex: path.programmeIndex || 1,lineName: path.lineName || `${path.endLineId || ''}号线 (${path.originStationName || ''} - ${path.destStationName || ''})`,duration: path.travelTime || 0,stationNum: path.stopList?.length || 0,transferNum: path.transferNum || 0,stations: processStations(path),nameScope: path.nameScope || '',simpleType: path.simpleType || '0',schedulesList: path.schedulesList || [],allNum: path.allNum || 0}));// ... 选择路径代码 ...}} catch (error) {// ... 错误处理 ...}
};// watch中的数据处理
watch(() => props.selectedPath, (newPath) => {// ... 其他代码 ...if (newPath) {try {// ... 线路和站点处理代码 ...// 更新路径结果pathResults.value = [{programmeType: newPath.programmeType || 0,programmeIndex: newPath.programmeIndex || 1,lineName: newPath.lineName || '',duration: newPath.duration || 0,stationNum: newPath.stationNum || 0,transferNum: newPath.transferNum || 0,stations: newPath.stations || [],nameScope: newPath.nameScope || '',simpleType: newPath.simpleType || '0',schedulesList: newPath.schedulesList || []}];selectedPathIndex.value = 0;} catch (error) {// ... 错误处理 ...}}
}, { immediate: true, deep: true });

修改后代码

// 数据处理工具函数
/*** 处理路径数据,统一数据格式* @param {Object} rawPath - 原始路径数据* @returns {Object} - 处理后的路径数据*/
const processPathData = (rawPath) => {// 处理站点数据const stations = processStations(rawPath);return {programmeType: rawPath.simpleType || 0,programmeIndex: rawPath.programmeIndex || 1,lineName: rawPath.lineName || `${rawPath.endLineId || ''}号线 (${rawPath.originStationName || ''} - ${rawPath.destStationName || ''})`,duration: rawPath.travelTime || 0,stationNum: rawPath.stopList?.length || 0,transferNum: rawPath.transferNum || 0,stations: stations,nameScope: rawPath.nameScope || '',simpleType: rawPath.simpleType || '0',schedulesList: rawPath.schedulesList || [],totalStations: rawPath.allNum || 0 // 直接使用接口返回的allNum};
};/*** 处理站点数据,统一数据格式* @param {Object} path - 路径数据* @returns {Array} - 处理后的站点数组*/
const processStations = (path) => {const stations = [];if (path.schedulesList && path.schedulesList.length > 0) {// 添加起始站stations.push(createStationData({stationType: '0',stationName: path.originStationName || path.schedulesList[0]?.stationName || '',lineId: path.schedulesList[0]?.lineId || '',stationNum: path.schedulesList[0]?.stationNum || 0}));// 添加中间站/换乘站for (let i = 1; i < path.schedulesList.length; i++) {const station = path.schedulesList[i];const isLastStation = i === path.schedulesList.length - 1;stations.push(createStationData({stationType: isLastStation ? '1' : '2',stationName: isLastStation ? (path.destStationName || station.stationName || '') : (station.stationName || ''),lineId: station.lineId || '',stationNum: station.stationNum || 0}));}} else if (path.originStationName && path.destStationName) {// 只有起终点信息的情况stations.push(createStationData({stationType: '0',stationName: path.originStationName,lineId: path.originLineId || '',stationNum: 0}));stations.push(createStationData({stationType: '1',stationName: path.destStationName,lineId: path.endLineId || '',stationNum: 0}));}return stations;
};/*** 创建标准化的站点数据对象* @param {Object} data - 站点原始数据* @returns {Object} - 标准化的站点数据*/
const createStationData = ({ stationType, stationName, lineId, stationNum }) => ({stationType,stationName,lineName: `${lineId}号线`,stationNum
});// 查询按钮点击处理
const handleQuery = async () => {// ... 验证代码 ...try {const response = await api.findOdPath(params);if (response && Array.isArray(response) && response.length > 0) {// 使用processPathData处理每条路径数据pathResults.value = response.map(processPathData);// ... 选择路径代码 ...}} catch (error) {// ... 错误处理 ...}
};// watch中的数据处理
watch(() => props.selectedPath, (newPath) => {// ... 其他代码 ...if (newPath) {try {// ... 线路和站点处理代码 ...// 使用processPathData处理路径数据pathResults.value = [processPathData(newPath)];selectedPathIndex.value = 0;} catch (error) {// ... 错误处理 ...}}
}, { immediate: true, deep: true });

代码结构对比

  • 修改前

    • 数据处理逻辑分散在多处
    • 相同的数据转换逻辑在不同地方重复
    • 缺乏统一的数据处理入口
    • 字段名称不统一(有些地方用allNum,有些地方没有)
  • 修改后

    • 引入了集中的数据处理函数processPathData
    • 添加了辅助函数createStationData标准化站点数据
    • 统一了字段命名(使用totalStations
    • 添加了详细的函数注释

维护性对比

  • 修改前

    • 修改字段名需要在多处搜索和替换
    • 添加新字段需要修改多个地方
    • 数据格式转换逻辑分散,难以统一修改
  • 修改后

    • 修改字段名只需在processPathData函数中更新
    • 添加新字段只需在processPathData和接口定义中添加
    • 数据格式转换集中在专门的函数中,便于统一修改

三、"一处修改"原则的实现与验证

为了验证"一处修改"原则的实现效果,可以通过几个常见的变更场景来对比:

场景1:修改字段名

需求:将总站数的字段名从allNum改为stationTotal

修改前需要的操作

  1. 搜索所有使用allNum的地方(至少2处:handleQuery和模板)
  2. 修改每个地方的字段名
  3. 确保没有遗漏任何使用点

修改后只需的操作

  1. processPathData函数中修改:
return {// ...其他字段totalStations: rawPath.stationTotal || 0 // 从allNum改为stationTotal
};
  1. 所有使用totalStations的地方自动使用新的数据来源

场景2:添加新字段

需求:添加一个新字段estimatedArrivalTime(预计到达时间)

修改前需要的操作

  1. 在handleQuery中添加字段
  2. 在watch处理中添加字段
  3. 在接口定义中添加字段

修改后只需的操作

  1. processPathData函数中添加:
return {// ...其他字段estimatedArrivalTime: rawPath.estimatedArrivalTime || null
};
  1. PathResult接口中添加:
interface PathResult {// ...其他字段estimatedArrivalTime?: Date | null;
}

场景3:修改线路名称格式

需求:将线路名称格式从"X号线"改为"Line X"

修改前需要的操作

  1. 搜索所有创建lineName的地方(至少6处)
  2. 修改每个地方的格式转换逻辑

修改后只需的操作

  1. 只需修改createStationData函数:
const createStationData = ({ stationType, stationName, lineId, stationNum }) => ({stationType,stationName,lineName: `Line ${lineId}`, // 从"X号线"改为"Line X"stationNum
});

四、优化收益分析

1. 功能正确性提升

  • 线路名称显示正确:用户现在能看到正确的线路名称,提高了信息准确性
  • 数据一致性:统一使用接口返回的 allNum 值,确保与后端数据一致

2. 代码可维护性提升

  • 集中的数据处理:所有数据转换逻辑都集中在几个相关函数中
  • 单一修改点:修改字段名或添加新字段只需在一处修改
  • 清晰的职责划分:每个函数都有明确的职责和注释

3. 开发效率提升

  • 降低维护成本:后续需求变更时,只需修改相应的处理函数
  • 减少错误风险:标准化的数据处理减少了手动处理的错误可能性
  • 提高代码可读性:函数命名和结构更加清晰,新开发者更容易理解

4. 代码量对比

  • 修改前:数据处理逻辑约120行代码,分散在多处
  • 修改后:数据处理逻辑约100行代码,集中在专门的函数中

五、潜在风险与影响面

1. 风险点

  • 数据依赖性:现在完全依赖接口返回的 allNum 值,如果接口不返回该字段,将显示为0
  • 渲染一致性:如果其他组件直接使用 allNum 而非 totalStations,可能导致显示不一致

2. 影响范围

  • 直接影响station-display.vue 组件中的路径显示
  • 间接影响:任何依赖此组件输出数据的父组件
  • 用户影响:用户将看到更准确的线路名称和站点信息

六、总结

此次优化通过两个关键改动点解决了显示问题并提高了代码质量:

  1. 修正线路名称显示:确保连接线显示正确的线路信息,提高了用户体验
  2. 重构数据处理逻辑:通过引入专门的数据处理函数,实现了"一处修改"原则

通过前后代码对比,可以清晰地看到重构后的代码结构更加清晰、职责划分更加明确,维护成本显著降低。特别是在面对字段变更、数据格式调整等常见需求时,新的代码结构可以大大减少修改点,降低出错风险。

虽然createStationData等辅助函数看起来很简单,但它们是整个数据处理架构的重要组成部分,为代码的长期维护奠定了基础。这种渐进式的重构方法在不影响现有功能的前提下,有效提升了代码质量,为后续的功能迭代和维护创造了更好的条件。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词