结对第二次作业——编程实现

222200411张晨阳 2024-09-30 22:26:52
这个作业属于哪个课程https://bbs.csdn.net/forums/2401_CS_SE_FZU
这个作业要求在哪里https://bbs.csdn.net/topics/619333839
结对学号222200410_222200411
这个作业的目标使用web技术编程实现上次作业的原型设计,包括基础功能和附加功能的实现并进行部署,同时在截止之前提交一份博客
其他参考文献《构建之法》

@

目录

  • 一、CodeArt仓库链接和代码规范链接
  • 1.1 CodeArt仓库地址
  • 1.2 代码规范链接
  • 1.3 部署后的访问链接
  • 二、PSP表格
  • 三、成品展示
  • 四、结对讨论过程描述
  • 4.1 讨论过程描述
  • 4.2 结对讨论截图
  • 五、设计实现过程
  • 5.1 功能分析
  • 5.2 实现过程设计概述
  • 5.3 设计思路简述
  • 5.4 遇到的问题和解决方式
  • 六、代码说明
  • 6.1 关键代码展示(解释思路)
  • 关键功能1:
  • 具体实现思路:
  • 关键功能2:
  • 具体实现思路:
  • 6.2 代码规范的制定和遵守
  • 七、心路历程和收获(各自)
  • 心路历程与收获(222200410)
  • 心路历程与收获(222200411)
  • 八、评价结对队友
  • 附:commit记录截图

一、CodeArt仓库链接和代码规范链接

1.1 CodeArt仓库地址

222200410第二次结对作业仓库地址
222200411第二次结对作业仓库地址

1.2 代码规范链接

  1. Vue 3: 官方的 Vue 3 代码规范提供了详细的指南,以帮助开发者编写清晰、一致的代码。官方风格指南

  2. HTML/CSS/JavaScript: 编码规范 by @mdo 提供了一套实用的 HTML 和 CSS 代码规范,以及 JavaScript 编写指南。编码规范

  3. JavaScript: MDN Web 文档项目提供了 JavaScript 代码示例编写指南,包括现代 JavaScript 特性的使用和注释规范。JavaScript 代码示例编写指南

1.3 部署后的访问链接

可访问链接

二、PSP表格

活动预估时间实际时间
计划阶段290分钟300分钟
理解项目需求58分钟60分钟
制定项目计划59分钟60分钟
学习新技术/工具120分钟120分钟
定义代码规范58分钟60分钟
定义分支策略55分钟60分钟
开发阶段820分钟840分钟
基础功能实现355分钟360分钟
奖牌榜排名118分钟120分钟
每日赛程&赛程详细信息119分钟120分钟
对阵表118分钟120分钟
附加功能实现234分钟240分钟
首页推荐117分钟120分钟
了解更多117分钟120分钟
部署阶段170分钟180分钟
准备部署环境58分钟60分钟
部署应用到服务器58分钟60分钟
测试部署环境54分钟60分钟
发布阶段180分钟180分钟
发起Pull Request59分钟60分钟
合并代码60分钟60分钟
发布Release版本61分钟60分钟
文档阶段290分钟300分钟
撰写博客草稿118分钟120分钟
编辑和校对博客118分钟120分钟
发布博客54分钟60分钟
总计2330分钟2460分钟

三、成品展示

以下将进行此次编码实现的结果展示,具体代码实现介绍详见第六部分。
首页展示
  作为基础功能要求之外的附加页面,可以说首页就是一个项目的门面。而在原型设计中,我们将其设计得图文并茂,来提高用户的体验感和兴趣。在此次编码实现中,我们针对原型设计进行微调,以展现更好的呈现效果和内容丰富度。以下将一一进行详细介绍。
首页封面

  这是首页第一幕,首先就是经过特殊处理契合整体色调的埃菲尔铁塔
  以“2024 Paris”和奥运五环共同构成了网页的logo。而导航栏我们则将其分为四个板块,分别为首页、奖牌榜、赛程以及了解更多。我们为导航栏添加了流畅的动态效果,当鼠标移入时,将会呈现出下划线的效果,提示用户已选中此块;当用户单击时,则会跳转到相应界面;而当鼠标移出相应区域时下划线效果就会消失。
  当用户想要了解奥运会更多信息时,如下所示,点击页面中的按钮“了解更多”,同样也可以跳转到了解更多的页面。

请添加图片描述

首页轮播图

  当页面下滑,映入眼帘的就是奥运精彩瞬间的轮播图,轮播图将不停轮播选取的几张奥运健儿们比赛过程中的图片。选择这种表现形式是想通过奥运健儿的高光时刻来表现奥运精神,体现网页主旨,丰富网页内容。

请添加图片描述

首页栏目

  再下滑就是为首页制作的三个展示栏目,分别展示了部分奖牌榜、比赛以及奥运会相关信息,同时一一对应相应的页面。为了使页面的呈现的效果更丰富,我们同样为此添加了动态效果。当鼠标移入展示框时,将会呈现出变灰的效果,移出时则恢复原来的样式。而按钮“complete”则是鼠标移入后变白,移除后恢复,当单击此按钮时则会跳转到对应的页面,为用户展示完整信息。

请添加图片描述


请添加图片描述


请添加图片描述

奖牌榜展示
   奖牌榜则采用了较为简洁的展示效果,通过“卡片式”呈现此次奥运会的奖牌总榜,包括排序、国家名称、金牌数、银牌数、铜牌数以及奖牌总数等属性。用户通过鼠标的滚动可以查看完整的奖牌榜。而关于此页面的导航栏,所实现的效果与首页一致,关于导航栏的呈现后续就不一一赘述。

请添加图片描述

每日赛程展示
   关于赛程,同样通过"卡片“的形式来呈现比赛信息(时间、大项、比赛、对战双方),同时我用户可通过日期的下拉列表选择想要查询的日期,即可刷新赛程数据。

请添加图片描述

详细赛况展示(非足球)
   点击相应比赛的卡片,则会跳转到该比赛的详细赛况页面,用户点击不同分组的按钮就会切换到相应分组的详细赛况。

请添加图片描述

详细赛况展示(足球)
详细赛况

   对于足球项目,详细赛况页面呈现将更为丰富,增加展示了出赛名单(对战双方各自的上场队员及替补队员的号数、姓名和位置)和比赛详情(对阵双方的得分点)。同时还增设了对战表的选项卡供用户切换页面。而页面左上方的Back按钮则是供用户返回上一页。

请添加图片描述

Back按钮供用户返回上一页

请添加图片描述

对阵表
   对阵表展现了足球每一轮次的比赛双方和最终得分,并通过线条的连接展示了比赛晋级关系。同时当鼠标移动到某支队伍的比赛信息上时,其他轮次中的该队伍将会做高亮展示。同样对阵表页面也可以通过点击详细赛况跳转回赛况页面。

高亮展示

请添加图片描述


对阵表页面也可以通过点击详细赛况跳转回赛况页面

请添加图片描述

了解更多展示
  为了使网站内容更加丰富,我们增设了了解更多的板块,主要向用户提供此次奥运会的其他信息。

请添加图片描述

四、结对讨论过程描述

4.1 讨论过程描述

  1. 理解原型设计
    我们首先对原型设计的每个页面进行了详细分析,包括布局、颜色方案、字体和图标等。我们讨论了用户如何与界面交互,以及这些交互如何转化为实际的功能需求。

    详细讨论内容:

    • 奖牌榜排名:分析了奖牌榜的布局和展示方式,讨论了如何实现无限滚动和排序。
    • 每日赛程:讨论了如何展示每一天的赛事信息,包括比赛类型、时间、项目、参赛国家和比分。特别关注了如何实现日期切换和详细赛程信息的查看。
    • 对阵表:分析了对阵表的布局和交互方式,讨论了如何实现比赛的高亮显示。
  2. 任务分配
    我们根据原型设计将任务分解为前端和数据来源两大块,并进一步细分为具体的功能模块。

    详细讨论内容:

    • 前端任务:包括页面布局、组件实现、用户交互和数据展示。
    • 数据来源:包括数据获取、处理和管理。
  3. 技术栈选择
    我们讨论了不同技术栈的优缺点,最终选择了Vue3、Node.js。

    详细讨论内容:

    • Vue:用于构建用户界面,讨论了组件化开发的优势和动态交互效果的实现。
    • Node.js:用于构建。
  4. 数据获取策略
    我们讨论了如何使用Python来爬取网页数据,并确定了数据爬取的合法性和合规性(仅用于教学内容)。

    详细讨论内容:

    • 数据爬取工具:确定了使用Python。
    • 数据爬取计划:为每日赛程、详细赛况分别制定了爬取计划。
  5. 界面实现讨论
    我们之前的原型设计使用了墨刀设计了用户界面原型,本次作业我们讨论了如何将原型设计转化为实际的UI组件。

    详细讨论内容:

    • 奖牌榜排名:讨论了如何设计奖牌榜的布局和排序逻辑。
    • 每日赛程:讨论了如何设计日期切换组件和详细赛程信息的展示方式。
    • 对阵表:讨论了如何实现布局和设计比赛的高亮显示。
  6. 功能实现细节
    我们讨论了每个功能的实现细节,包括数据处理、用户交互和界面展示。

    详细讨论内容:

    • 奖牌榜排名:讨论了如何设计数据结构,如何从爬取的数据中提取排名信息。
    • 每日赛程:讨论了如何设计日期切换功能,如何展示详细赛程信息。
    • 对阵表:讨论了如何实现鼠标悬停时的交互效果。
  7. 问题解决策略
    我们针对开发中可能遇到的问题,讨论了解决策略和备选方案。

    详细讨论内容:

    • 数据准确性:讨论了如何验证爬取数据的准确性。
    • 前端同步:讨论了如何确保前端数据展示的同步性。
  8. 部署策略
    我们讨论了如何将应用部署到CodeArt华为云服务器,并确定了部署流程和回滚策略。

    详细讨论内容:

    • 部署流程:讨论了部署步骤和环境配置。
    • 回滚策略:讨论了在部署失败时的回滚方案。
  9. 文档和博客撰写
    我们讨论了项目文档的结构和内容,并确定了博客撰写的分工和发布计划。

    详细讨论内容:

    • 项目文档:讨论了文档的各个部分,包括项目概述、技术、功能实现、部署和扩展功能。
    • 博客撰写:讨论了博客的结构和内容,以及如何使用Markdown格式化文档。
  10. 沟通和协作工具
    我们确定了使用Git和CodeArt进行代码版本控制。

    详细讨论内容:

    • 代码版本控制:讨论了如何使用Git和CodeArt进行代码管理。

通过这些详细的讨论和协作,我们确保了项目的顺利进行,并在规定的时间内完成了功能的开发和部署。

4.2 结对讨论截图

请添加图片描述

五、设计实现过程

5.1 功能分析

  1. 基础功能分析

    功能1:奖牌榜排名

    • 目的:展示各参赛国家的奖牌数量和排名。
    • 需求
      • 展示各个国家金牌、银牌、铜牌的数量并进行排序。
      • 显示国家的国旗和总奖牌数。
    • 用户交互
      • 用户可以通过鼠标滚动查看所有国家的奖牌情况。

    功能2:每日赛程

    • 目的:展示每天的赛事安排和结果。
    • 需求
      • 显示比赛类型、比赛时间、比赛项目、参赛国家和比分。
      • 支持通过日历来切换查看不同日期的赛程。
      • 支持点击查看每场比赛的详细赛程信息。
    • 用户交互
      • 用户可以通过日历控件选择日期。
      • 用户可以点击特定赛事查看详细信息。

    功能3:对阵表

    • 目的:以图表形式展示比赛的晋级过程和结果。
    • 需求
      • 展示参赛国家在不同阶段的比赛结果。
      • 支持高亮显示当前鼠标悬停的国家队伍在不同阶段(1/4决赛、半决赛、决赛)的对阵信息。
    • 用户交互
      • 用户将鼠标悬停在某支队伍时,显示其在不同阶段(1/4决赛、半决赛、决赛)的对阵信息。。
  2. 附加功能分析

    附加功能1:首页

    • 目的:提供巴黎奥运会的图文,利用导航栏划分模块,增加用户交互,增加用户对赛事的兴趣。
    • 需求
      • 提供关于巴黎奥林匹克运动会的图片信息,如奥运精彩时刻、奥运栏目等。
      • 使用图文结合的方式展示信息。
      • 提供互动元素,如轮播图、栏目跳转等。
    • 用户交互
      • 用户可以浏览图文信息。
      • 用户可以点击导航栏进入其他想要查看的模块轮播图和栏目进行互动。
      • 用户可以点击轮播图和栏目进行互动。

    附加功能2:了解更多

    • 目的:介绍巴黎奥林匹克运动会的背景信息,增加用户对赛事的兴趣。
    • 需求
      • 提供关于巴黎奥林匹克运动会的详细信息,如历史、文化、重要事件等。
      • 使用图文结合的方式展示信息。
      • 提供互动元素,如视频、图集等。
    • 用户交互
      • 用户可以浏览图文信息。

    附加功能3:详细赛况

    • 目的:提供比赛的详细信息,包括参赛国家、出赛名单和比赛详情。
    • 需求
      • 展示比赛的详细数据,如参赛队伍、比赛时间、比赛地点。
    • 用户交互
      • 用户可以查看特定比赛的详细信息。
  3. 其他说明

    数据来源

    • 目的:获取项目所需的数据。
    • 需求
      • 合法合规地爬取网页数据。(仅用于教学内容)
      • 确保数据的准确性和完整性。

    部署

    • 目的:将项目部署到服务器,确保其可访问性。
    • 需求
      • 选择适合的云服务器。
      • 配置服务器环境。
      • 确保应用的稳定性和安全性。

通过以上功能分析,我们可以清晰地理解每个功能的目的、需求和用户交互方式,为后续的开发工作提供指导。

5.2 实现过程设计概述

  1. 系统设计

    **技术栈**:

    • 前端:Vue 3
    • 数据格式:JSON
    • 数据存储:本地存储,动态加载
    • 样式:HTML+CSS+JavaScript

    **开发环境**:

    • 代码编辑器:Visual Studio Code
    • 版本控制:Git
    • 项目管理工具:CodeArt

    **构建工具**:

    • Vue CLI:用于快速构建Vue应用
    • Webpack:模块打包器

    **部署**:

  1. 功能架构图

    以下是功能架构图:

    请添加图片描述

:仅列出了主要的路由跳转,具体的成果中的跳转将会更加丰富。

  1. 系统创新性

    **数据动态加载**:

    • 使用Vue 3的异步组件加载技术,按需加载数据,提高应用的加载速度和性能。

    **组件化架构**:

    • 将每个页面拆分为多个Vue组件,提高代码的可维护性和可重用性。

    **响应式设计**:

    • 使用CSS的响应式设计,确保网站在不同设备上均有良好的用户体验。

    **交互式用户界面**:

    • 利用Vue 3的响应式和组件化特性,创建交互式用户界面,如页面栏目的跳转、日期的切换等等。
  2. 合理性

    **前端路由**:

    • 使用Vue Router实现页面的路由管理,提供流畅的页面体验。

    **代码分割**:

    • 利用Webpack的代码分割功能,实现组件级别的按需加载,优化资源加载时间。

    **性能优化**:

    • 利用Vue 3的优化特性,如组件的懒加载,提高应用性能。

    **用户体验**:

    • 通过精心设计的UI/UX,确保用户界面直观易用,提升用户满意度。

    **可访问性**:

    • 网站对所有用户都是可访问的。

    **准确性**:

    • 实现数据的正确性。

通过以上设计,我们可以确保项目的顺利进行,并在规定的时间内完成所有功能的开发和部署。

5.3 设计思路简述

  1. 项目结构设计

**页面**:

  • 使用Vue Router进行页面路由管理。

**组件化**:

  • 将每个功能模块设计为一个Vue组件,如奖牌榜、每日赛程等。
  • 使用props进行父子组件的数据传递。
  • 使用事件抛出自定义事件进行子父组件的通信。

**数据与工具函数**:

  • 创建一个数据文件夹,包含所有与数据获取和处理相关的函数。
  • 使用现代JavaScript的异步特性,如async/await。

**样式管理**:

HTML结构设计

  • 使用语义化的HTML标签来构建页面结构。
  • 通过组件化的方式组织HTML,使其与Vue组件相匹配。

CSS样式设计

  • 响应式设计

    • 利用媒体查询(Media Queries)实现响应式布局,确保在不同设备上都能提供良好的用户体验。
    • 使用flexbox或CSS Grid布局来创建灵活的布局结构。
  • 样式重用

    • 创建可重用的样式组件库,减少代码冗余。
    • 使用Vue组件的scoped属性来实现样式的局部作用域。

JavaScript交互设计

  • Vue.js:使用Vue.js来处理用户交互逻辑,如事件监听、数据绑定等。
  • 条件渲染:使用Vue的指令(如v-ifv-show)来实现条件性渲染,动态改变页面布局和样式。
  • 动态样式
    • 使用Vue的:class:style绑定来动态应用CSS类和样式。
    • 通过计算属性(computed properties)和方法(methods)来动态生成样式值。

**代码规范**:

  • 采用ESLint进行代码质量和风格的检查。

    1. 数据管理设计

**本地JSON文件**:

  • 将所有需要展示的数据存储在本地项目目录下的JSON文件中。
  • 使用webpack或其他构建工具在编译时将引入JSON数据。

**动态数据加载**:

  • 利用Vue的生命周期钩子,在组件创建时加载数据。
  • 使用Vue的<template><script><style>进行组件封装。

**数据模拟**:

  • 在开发阶段,使用数据模拟页面样式。

**数据更新策略**:

  • 对于需要更新数据的页面,使用Vue的watchcomputed属性实现。

    1. 用户界面设计

**响应式布局**:

  • 使用媒体查询和flexbox或grid系统设计响应式布局。
  • 确保在手机、平板和桌面等不同设备上都有良好的展示效果。

**交互设计**:

  • 设计直观的用户操作流程,如点击、滑动等。
  • 使用Vue的v-on指令绑定事件处理器。

**视觉反馈**:

  • 对用户的操作给予即时反馈,如按钮点击效果、鼠标绑定事件等。

    1. 性能优化设计

**代码分割**:

  • 使用Vue CLI内置的代码分割功能,分割组件代码。

**资源懒加载**:

  • 对图片和视频资源使用懒加载技术,减少初次加载时间。

  1. 维护和扩展性设计

**文档编写**:

  • 编写清晰的开发文档。

**模块化**:

  • 保持代码的模块化和组件的独立性,便于未来的维护和扩展。

通过以上设计思路,我们可以确保项目按照预期完成,并在未来能够方便地进行维护和扩展。

5.4 遇到的问题和解决方式

  1. 项目结构设计问题

**问题**:随着项目页面的增加和复杂度的提升,文件和目录变得难以管理,不管是不同功能模块的页面的划分还是子父组件之间的调用。

**解决方式**:

  • 组件划分:根据功能和路由将页面划分为不同的Vue组件。

  • 目录结构:创建一个清晰的目录结构,包括componentsviewsrouterassets等。

  • Vue CLI:使用Vue CLI的vue create命令来初始化项目,它提供了一个合理的默认项目结构。

    1. 数据管理问题

**问题**:数据的状态管理在多组件间变得复杂。

**解决方式**:

  • 组件的data属性:对于局部状态,使用组件的data属性。

  • Prop Drilling:通过props将数据传递给子组件,但注意不要过度使用。

    1. 响应式布局问题

**问题**:在不同设备上提供良好的用户体验。自适应一直是前端实现页面样式时需要特别注意的问题。在不同设备上,页面的呈现效果可能大不相同,如果没有自适应,在一些设备上页面的呈现效果会不理想。而在实现自适应的过程中我们也遇到了困难,花费了一定时间进行“测试”和调整。

**解决方式**:

  • Flexbox/CSS Grid:使用现代布局技术来创建响应式布局。
  • 媒体查询:使用CSS媒体查询来适配不同屏幕尺寸。
  1. 数据获取和展示问题

**问题**:从本地JSON文件动态加载数据。在每日赛程和详细赛况那个模块是需要动态加载数据的。用户通过切换日期查看不同日期的赛程信息,这个过程是需要数据的动态加载的。而在爬取下来的json数据中,由于比赛项目的不同和特殊性,不同比赛项目的数据结构是不一样的,在对于数据的处理和加载上遇到了一定的挑战。

**解决方式**:

  • **Webpack的require.context()**:使用Webpack的这一功能来动态加载一个文件夹中的所有JSON文件。
  • Vue的生命周期钩子:在组件的createdmounted钩子中加载数据。
  1. 用户交互问题

**问题**:实现复杂和流畅的用户交互。在这个作业中,功能模块和页面是相对较多的,如何设计和实现页面的跳转逻辑正确也是一个值得思考的问题。

**解决方式**:

  • **Vue的v-on**:使用Vue的v-on指令来监听用户事件。

  • 计算属性和观察者:使用计算属性和Vue的watch选项来响应数据变化。

  • Vue Router的导航守卫:使用导航守卫来处理路由跳转逻辑。

    1. 代码规范和一致性问题

**问题**:保持代码风格一致。由于这次作业不同于个人实战那样可以有自己的代码风格,这是一次结对完成的任务。而不同个体之间的代码风格可能大不相同。为了解决保持项目代码规范和风格的相对一致性这个问题,我们也投入了一些时间来确定规则

**解决方式**:

  • ESLint:使用ESLint来检查代码规范。
  • 沟通交流:相互之间约定大致的代码风格
  1. 部署问题

**问题**:将项目相关的环境配置再次移植部署到服务器,window和服务器的Linux环境与依赖存在冲突。

**解决方式**:

  • Docker:使用Docker容器化应用,确保环境一致性。
  • 使用Docker Compose:通过Docker Compose来定义和运行多容器应用。在docker-compose.yml文件中,可以为每个服务指定网络配置,以避免网络冲突。

六、代码说明

6.1 关键代码展示(解释思路)

关键功能1

实现每日赛程中的某场比赛跳转到对应赛程详情,赛程详情展示该比赛属于的大项下所有比赛,需分具体比赛项目(A组B组等)查看

具体实现思路

实现点击每日赛程中的某场比赛跳转到对应比赛详情背后的传值与接收值

  • 在每日赛程(DailySchedule.vue)中,使用了 Vue Router 的 push 方法和路由的 query 参数来导航和传递数据
    goToMatchDetails(matchData) {
    
      const routeParams = {
    
       name: 'MatchDetail',
    
       query: {
    
    ​    disciplineName: matchData.disciplineName,
    
    ​    specificEvent: matchData.specificEvent,
    
    ​    matchCode: matchData.matchCode,
    
       }
    
      };
    
    
    
      // 检查是否存在 competitors 属性,并且它不为空
    
      if (matchData.competitors && matchData.competitors.length >= 2) {
    
       // 如果存在,添加 competitors 的 name 到路由参数
    
       routeParams.query.team1Name = matchData.competitors[0].name;
    
       routeParams.query.team2Name = matchData.competitors[1].name;
    
      }
    
    
    
      // 无论如何,都要推送这三个基本属性
    
      this.$router.push(routeParams);
    
     },

  • 在赛程详情(MatchDetail.vue)页面中,使用 useRoute 钩子获取当前路由的引用,允许访问路由的参数,再从路由查询参数中获取数据,并更新响应式引用的值,获得传过来并存储的值
import { ref, onMounted, computed } from 'vue';
    
    import { useRoute } from 'vue-router';
    
    
    
    export default {
    
     setup() {
    
      const route = useRoute();
    
      const disciplineName = ref('');
    
      const specificEvent = ref('');
    
      const matchCode = ref('');
    
      const team1Name = ref('');
    
      const team2Name = ref('');
    
    
    
      onMounted(async () => {
    
       const { disciplineName: dn, specificEvent: se, matchCode: mc, team1Name: t1, team2Name: t2 } = route.query;
    
       disciplineName.value = dn;
    
       specificEvent.value = se;
    
       matchCode.value = mc;
    
       team1Name.value = t1;
    
       team2Name.value = t2;

使用python脚本重新组织数据形式为更适合详细赛程的json文件,从以日期为文件索引修改为以大项为文件索引

import json
import os
from collections import defaultdict

 #获取当前目录下的所有json文件
json_files = [f for f in os.listdir('.') if f.endswith('.json') and os.path.isfile(f)]

 #创建一个字典来存储归类后的数据
grouped_data = defaultdict(lambda: defaultdict(list))

 #遍历所有json文件
for file_name in json_files:
    # 读取JSON数据
    with open(file_name, 'r', encoding='utf-8') as file:
        json_data = json.load(file)

 #遍历数据
for item in json_data:

#创建result文件夹(如果不存在)
result_folder = 'result'
if not os.path.exists(result_folder):
    os.makedirs(result_folder)

#遍历归类后的字典,写入文件
for discipline_name, events in grouped_data.items():

#创建一个列表来存储归类后的比赛数据
​    events_list = []
   for specific_event, items in events.items():
        event_data = {"specificEvent": specific_event, "items": items}
        events_list.append(event_data)
        
  #写入新的JSON文件到result文件夹
  output_file_name = os.path.join(result_folder, discipline_name + '.json')
    with open(output_file_name, 'w', encoding='utf-8') as f:
        json.dump(events_list, f, indent=4, ensure_ascii=False)
           print(f"处理后的数据已写入到 {output_file_name}")

将加载的数据解析成结构化格式,并存储在响应式变量中:matchList 存储所有比赛的详细信息。

stages存储所有不重复的比赛阶段。activeStage 存储当前选中的比赛阶段。

const jsonModule = await import(`@/assets/match/result/result/${disciplineName.value}.json`);
const data = jsonModule.default || jsonModule;
// 解析 JSON 数据并填充到 matchList
data.forEach(group => {
  group.items.forEach(event => {
    const match = {
      id: event.matchCode,
      group: event.specificEvent,
      team1: event.competitors[0].name,
      code1: event.competitors[0].noc.replace('./country_images/', ''),
      score1: event.competitors[0].mark,
      team2: event.competitors[1].name,
      code2: event.competitors[1].noc.replace('./country_images/', ''),
      score2: event.competitors[1].mark,
      time: `${event.date.month}月${event.date.day}日 ${event.startDate}`,
      status: event.competitors[0].winnerLoserTie === 'W' ? '已结束' : event.competitors[1].winnerLoserTie === 'W' ? '已结束' : '进行中'
    };
    matchList.value.push(match);


if (!stages.value.includes(event.specificEvent)) {
  stages.value.push(event.specificEvent);
}

  });
});

根据路由参数specificEvent初始化当前选中的比赛阶段,确保高亮显示当前具体比赛项目和具体该场比赛。

if (specificEvent.value && stages.value.includes(specificEvent.value)) {
  activeStage.value = specificEvent.value;
} else if (stages.value.length > 0) {
  activeStage.value = stages.value[0];
}

使用计算属性 paginatedMatches 实现分页逻辑,根据当前选中的比赛阶段和页码计算当前页应显示的比赛列表。

  const paginatedMatches = computed(() => {
   if (!activeStage.value) return [];
   const start = (currentPage.value - 1) * pageSize.value;
   return matchList.value.filter(m => m.group === activeStage.value).slice(start, start + pageSize.value);
  });

使用计算属性 totalPages 计算并存储总页数,基于当前阶段下的比赛列表总数和每页显示的比赛数。

 computed: {
  totalPages() {
   return Math.ceil(
​    this.matchList.filter((m) => (this.activeStage ? m.group === this.activeStage : true)).length / this.pageSize
   );
  },
 },

提供 filterMatchesByStage 等方法,允许用户选择不同的比赛阶段,并在切换阶段时重置分页到第一页。

 methods: {
  goBack() {
   window.history.back();

  },
  prevPage() {
   if (this.currentPage > 1) {
​    this.currentPage--;
   }
  },
  nextPage() {
   if (this.currentPage < this.totalPages) {
​    this.currentPage++;
   }
  },
  getFlagUrl(code) {
   return require(`@/assets/country_images/${code}`); // 调整路径
  },

  filterMatchesByStage(stage) {
   this.activeStage = stage;
   this.currentPage = 1; // 重置到第一页
  },
 },
关键功能2:

实现了一个比赛信息展示和管理的功能,可以根据通过选择日期加载对应日期的所有赛事,并展示该场赛事基本信息

具体实现思路:

日期范围处理:组件提供了一个getDates函数,用于生成两个日期之间的所有日期数组。这通常用于创建日期选择器,允许用户选择一个特定的日期。

// 生成日期数组

const getDates = (startDate, endDate) => {
 const date = new Date(startDate);
 const dates = [];
 while (date <= new Date(endDate)) {
  dates.push(
   `${date.getFullYear()}-${(date.getMonth() + 1)
​    .toString()
​    .padStart(2, '0')}-${date
​    .getDate()
​    .toString()
​    .padStart(2, '0')}`
  );
  date.setDate(date.getDate() + 1);
 }
 return dates;
};

动态数据加载:提供了loadMatches方法,用于根据选择的日期动态加载对应的JSON文件,该文件包含当日的比赛数据。

 // 动态加载对应日期的 JSON 文件
 async loadMatches() {
​    // 清空上次加载的比赛数据this.matches = []; // 清空 matches 数组
  const dateKey = this.selectedDate.slice(5).replace('-', '');
  console.log(`Loading matches for date: ${this.selectedDate}`); // 日志1:打印正在加载的日期

  try {

   // 根据选择的日期加载对应的 JSON 文件

   const matchData = await import(`@/assets/match/result/${dateKey}.json`);

   console.log('Match data loaded:', matchData.default || matchData); // 日志2:打印加载的数据



   this.processMatches(matchData.default || matchData);

   console.log('Matches processed:', this.matches); // 日志3:打印处理后存储在matches数组中的数据
  } catch (error) {

   console.error('Error loading match data:', error);
  }
 },

数据处理:提供了processMatches方法,用于处理加载的比赛数据,包括映射每个比赛数据和为每个参赛者加载国旗图片路径。

// 处理匹配数据

 processMatches(matches) {
  console.log('Processing matches...'); // 日志4:开始处理数据
  this.matches = matches.map(match => {
   match.competitors = match.competitors.map(competitor => {
​    if (competitor.noc) {
​     // 加载国旗图片路径
​     competitor.noc = require(`@/assets/match/country_images/${competitor.noc.split('/').pop()}`);
​     console.log(`Flag loaded for ${competitor.name}: ${competitor.noc}`); // 日志5:打印国旗图片路径
​    } else {
​     console.warn(`No NOC for competitor ${competitor.name}`); // 日志6:警告没有NOC的情况
​    }

​    return competitor;
   });
   
   return match;
  });
 },

6.2 代码规范的制定和遵守

以下是针对所使用的语言(HTML+CSS+JavaScript、Vue 3)的一份简要的代码规范,且在项目中严格遵守:
链接: codestyle.md

七、心路历程和收获(各自)

心路历程与收获(222200410)

  在这次结对作业中,我深刻体会到了合作的力量。我们从项目启动时的规划讨论,到技术选型,再到功能实现,每一步都凝聚了我们共同的努力。我负责的部分是奖牌榜、了解更多完整页面的实现以及首页、对阵表、详细赛况的部分页面样式设计以及博客的主要撰写,这对我来说是一个不小的挑战,因为我需要深入理解Vue 3的响应式系统和组件通信机制。在开发过程中,我们遇到了数据绑定和状态管理的问题,但通过查阅文档、搜索在线资源和相互讨论,我们逐渐找到了解决方案。代码审查环节让我们的代码更加健壮,也让我学会了如何编写更规范、更易读的代码。在部署阶段,我体验了将应用部署到服务器的过程。这次经历不仅提升了我的技术能力,也锻炼了我的沟通和协作能力。

心路历程与收获(222200411)

  这次结对作业是一次宝贵的学习经历。我们从项目的需求分析开始,一步步走到了最终的部署。在这个过程中,我负责了每日赛程和详细赛况的功能实现,这让我有机会深入探索Vue 3的强大功能,尤其是它的响应式数据绑定和组件系统。我们在开发中遇到了一些难题,比如如何优化数据加载的性能,以及如何实现复杂的用户交互。通过不断的尝试和结对队友之间的协作,我们最终克服了这些挑战。代码审查帮助我们保持了代码的质量,也让我学会了如何从别人的代码中学习。在部署过程中,我学习了服务器的基本知识和部署策略。这次合作不仅让我的技术有了显著的提升,也让我认识到了团队合作的重要性。

八、评价结对队友

222200410对222200411的评价:
  我的队友在整个项目中表现出了极高的专业素养和团队精神。他对前端技术有较清晰的认识,尤其是在Vue 3和JavaScript方面展现出了很强的能力。在面对复杂的功能实现时,他总是能够耐心地研究问题,并提出新的解决方案。同时他非常可靠,他总是愿意伸出援手,无论是在代码审查还是在解决技术难题时。他的团队合作精神和积极的态度为结对创造了一个非常积极的工作环境。他的沟通非常有效,总是能够及时地提供反馈和建议,帮助团队保持在预期的轨道上。

222200411对222200410的评价:
  我的队友在本项目中展现了卓越的专业技能和团队协作能力。她对前端开发有着深刻的理解,特别是在html和css样式方面表现突出。面对项目中的各式页面,她都能很快的找到实现思路快速编写好页面。面对页面组件之间错综复杂相互影响的css样式,她总是能细心耐心的一点点调整,使页面样式达到最完美的状态。她的积极态度和团队精神为团队营造了一个高速前进的工作环境。她的沟通技巧非常出色,总是能够提供及时、有价值的反馈和建议,确保项目按计划顺利推进。

附:commit记录截图

222200410的commit记录:

在这里插入图片描述

222200411的commit记录:

请添加图片描述

请添加图片描述

...全文
244 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复
AJAX——新手快车道 前言 AJAX是什么? 首先、AJAX是一种很酷的技术,一旦采用了AJAX,就能让你的Web页面, 你的网站,甚至连同你们公司,都变得很酷。在Web2.0的时代里,不使用一点 AJAX技术的网站,就会显得很老土,很落伍。 但是,这样的理解,其实是很肤浅的。仅仅是从一个外行,从一个使用者的 角度出发,来理解AJAX,就像我在本书的第一章AJAX我也行中那样,开发 出很愚蠢,甚至都没有资格被称之为AJAX应用的纯IE、XMLHTTP应用。 AJAX更酷的一点在于,对于传统的Web开发人员来说,AJAX所运用的, 是更加先进的,更加标准化的,更加和谐高效的,完整的Web开发技术体系。 遵循这样的体系开发Web应用,能让你的开发过程变得更加轻松,也能使你们 的开发团队,显得很酷。在Web2.0 的时代里,还在采用过时的技术来开发 Web,会显得很老土,很落伍。 AJAX的相关组成技术,每一个都已经出现了N年以上了,对这些技术的 组合运用,也远远早于AJAX这个名词出现之前。所以,我真正敬佩的,并非提 出 AJAX这个缩写的Jesse James Garrett。而是那些早在N年以前,就已经在探索、 实践的先行者,他们始终在追求的:是更好的用户体验,以及更好的开发体验。 这样的精神,才是最可宝贵的,也是最值得我们学习的。许多年过去以后,当我 们再回头来看当年的这些热门技术,也许早已经变得老土,变得落伍了。在这样 的历程中,哪些人会成长为高手?会成长为大师呢?就是那些永不满足,永远 在追求更好的用户体验,永远在追求更好的开发体验的人! 新手如何上路 软件开发这个领域,永远都在飞速发展,大家都必须不断的学习新的知识、 技能、框架、IDE、甚至新的语言。传说中的骨灰级高手们,就像传说中的大侠, 任何武器、哪怕是一块木头到了他们手里,也能发挥惊人的威力,人家练了几十 年的看家本领,他们随手使来,也竟然像是打娘胎里就开始练了一样。为什么? 就算不吹那么玄的,平常我们能够碰到的那些老手,在学新东西的时候, 也比那些新手学得更快,理解得更深,运用得更熟练。而新手们呢?往往就会漫 无头绪,焦头烂额,以一副张着茫然的大眼睛的经典表情,出现在各大论坛的 新手求助区里。他们欠缺的,究竟是什么呢?为什么老手学新东西,就没遇到那 么多困难呢? 泛泛地说,自然是经验上的欠缺。仔细地说来,又可以分为三个方面: 一、本质,一种技术与另一种技术之间,往往会有本质上的相通之处,当你 对一种技术的理解与思考越来越深入时,学习一种新技术也会更加容易。触类旁 通,举一反三的能力,就是来自于对于技术本质的追寻。 二、地图,本质上或多或少的相通,也提示着我们技术之间的相互关联,当 你了解的技术越多,了解得越是深入,在你的内心,就能建立起越发清晰的技 术地图。各种知识都有一个自然、合理的位置。那么当一个老手要学习一门新技术 的时候,他其实并非在探索一个全新的、未知的领域,而是有很多脉络可寻,也 很多已知可以帮助他们快速了解未知。 三、技巧,面对同样的未知,面对同样的难题,新手们一筹莫展,而老手们 却掌握着更多的技巧和手段,帮助他们试探可能性、缩小问题的范围、迅速定位 问题、不犯明显愚蠢的错误、甚至能够列举出更具命中力的搜索关键词,而这些 技巧,都帮助老手在前进的道路上,更少跌倒,即使跌倒,也能更快的爬起来。 作为一本写给新手的入门书籍,我们希望展现给读者的,是一个老手如何 学习新技术的过程。我们相信,这样的一个学习过程,对于新手来说,是更具有 价值的。 何谓快车道 必须老老实实的承认,我吹牛了!老手虽然会比新手学习得更快一些,但 是也同样会碰到麻烦,遇到障碍,感觉头痛。如果没有真正的专家的指导,我不 可能如此迅速地将AJAX掌握到目前这样的程度,要真是让我自学三个月,然 后就写出书来的话,那真是在骗钱了。 老手能够快速学习的另一个重要的诀窍是:认识很多牛人朋友 如果没有李锟与赵泽欣的专家级指导与帮助,如果没有与李锟AJAX结对 编程的体验,如果没有三个人在MSN上无数次的长聊,我想要在短期内建立起: 对于AJAX本质的理解; 对于整个AJAX以及相关技术地图的理解; 对于AJAX编程开发所需要的很多技巧、手段的掌握; 几乎是不可能的。 如果没有(N多需要感谢的人)的(N多方面的帮助),我们这本书,也 不可能以现在这样的深度,以(N个月)内完成的速度,送到读者的面前。 希望这本书,能够对大家快速学习AJAX,有所帮助。

109

社区成员

发帖
与我相关
我的任务
社区描述
202401_CS_SE_FZU
软件工程 高校
社区管理员
  • FZU_SE_TeacherL
  • 032002124林日臻
  • 助教姜词杰
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧