这个作业属于哪个课程 | 软件工程23年春季 |
---|---|
这个作业要求在哪里 | 结对第二次作业–编程实现 |
结对学号 | 222000123、222000214 |
这个作业的目标 | 结对编程、部署云服务器、撰写博客与PPT |
其他参考文献 | 优快云、博客园等 |
文章目录
一、git仓库链接和代码规范链接
1.1 git仓库地址
1.2 代码规范地址
二、PSP表格
PSP | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 20 |
• Estimate | • 估计这个任务需要多少时间 | 30 | 20 |
Development | 开发 | 730 | 1000 |
• Analysis | • 需求分析 | 30 | 45 |
• Learning | • 学习相关技术 | 90 | 125 |
• Discussion | • 结对讨论 | 40 | 60 |
• Design Spec | • 具体设计 | 30 | 30 |
• Design | • 具体代码编写 | 480 | 600 |
• Test and Improvement | • 代码测试与改进 | 60 | 140 |
Reporting | 报告 | 80 | 100 |
• Achievements Exhibition | • 项目成果展示 | 40 | 60 |
• Problem Analysis & Postmortem | • 问题的分析和事后总结 | 40 | 40 |
合计 | 840 | 1080 |
三、成品展示
3.1 云服务器地址
👉这是云服务器地址
(过期时间:2023-10-18)
3.2 成品演示
演示视频
四、结对讨论过程描述
本来我们打算完成一个前后端分离项目,但是由于时间比较赶,前端都有点完成不了,于是我们转为纯前端vue开发,数据先存在前端的js文件中
五、设计实现过程
5.1 功能结构图
5.2 实现过程
-
首页:使用ElementUI轮播图组件展示一些澳网的新闻图片,在轮播图组件中渲染图片和设置自动轮播、滑动等效果
-
选手排名:使用表格显示个人得分排名。在文件中定义一个数据数组来存储选手的得分信息,使用ElementUI的表格组件读取数组中的信息并展示
-
每日赛况:使用Vue的动态渲染来展示数据,通过按钮组实现每日比赛的切换,不同的按钮传递不同的消息进而展示不同的赛况信息
-
晋级图:定义晋级图组件,并传递选手晋升路线的数据,鼠标悬停时高亮展示选手详细信息
-
详细赛况:每日赛况页面跳转过来时,携带不同的消息,进而展示不同比赛的详细信息
-
了解更多:展示澳网的相关故事与基本介绍
六、代码说明
每日赛程页面设计
-
页面的名称为 Daily.vue,包含一个标题组件和一个内容区域;
-
每日赛况内容存储在数组中,每个数组包含了比赛的信息,如比赛类型、比赛选手、比分等等;
-
点击页面上的按钮可以切换显示不同日期的比赛;
-
通过计算属性content,根据当前选中的日期来确定要显示哪些比赛信息;
-
getWinner方法用于确定比赛的获胜者,它根据两个选手的得分来判断谁是赢家,添加class进行样式修改;
-
toDetails方法用于将用户导航到详细赛况页面,它使用Vue路由器的$router.push方法实现跳转;
<!-- 每日赛况主要内容区域 -->
<div class="mainContent" style="margin: 0 30px;width: 900px;">
<el-card class="box-card" v-for="(item, index) in content" :key="index"
style="margin: 10px 10px;display: inline-block;width: 400px; border-radius: 30px">
<el-row :gutter="10">
<el-col class="show" :span="14">
<!-- 比赛类型 -->
<strong>{{ item.type }}</strong>
<br>
<!-- 比赛场地 -->
<span class="text">{{ item.round }}</span>
</el-col>
<el-col class="show" :span="5" offset="3">
<strong>Complete</strong>
<br>
<!-- 比赛时间 -->
<span class="text">{{ item.time }}</span>
</el-col>
</el-row>
<hr class="divide">
<el-row :gutter="10" :class="getWinner(item.score1, item.score2)">
<el-col :span="2">
<img :src="item.nation1" class="nationIcon" />
</el-col>
<!-- 比赛选手 -->
<el-col class="show" :span="7" offset="2">
{{ item.player1 }}
</el-col>
<!-- 比赛得分 -->
<el-col class="show" :span="6" offset="7">
{{ item.score1 }}
</el-col>
</el-row>
<hr class="divide">
<el-row :gutter="10" :class="getWinner(item.score2, item.score1)">
<el-col :span="2">
<img :src="item.nation2" class="nationIcon" />
</el-col>
<!-- 比赛选手 -->
<el-col class="show" :span="7" offset="2">
{{ item.player2 }}
</el-col>
<!-- 比赛得分 -->
<el-col class="show" :span="6" offset="7">
{{ item.score2 }}
</el-col>
</el-row>
<hr class="divide">
<!-- 跳转到详细赛况 -->
<el-row>
<el-button round class="more" @click="toDetails(index + 1)">查 看 详 情</el-button>
</el-row>
</el-card>
</div>
methods: {
// 传递消息方法
setMessage(value) {
this.message = value
},
// 获取获胜者方法
getWinner(score, otherScore) {
const scores1 = score.split(' ');
const scores2 = otherScore.split(' ');
const sum = scores1.reduce((total, score) => total + parseInt(score), 0);
const otherSum = scores2.reduce((total, score) => total + parseInt(score), 0);
return sum > otherSum ? 'winner' : '';
},
// 跳转到详细界面方法
toDetails(panel) {
this.$router.push({ name: 'Details', params: { panel: panel } })
}
},
导航栏组件
-
导航栏组件使用了 Element UI 库定义的水平导航菜单。菜单有六个item,每个item都由一个 el-menu-item 组件包裹在一个 router-link 组件中,用于链接到应用程序的不同路由;
-
default-active 属性设置初始活动菜单项的索引,@select 事件在选择菜单项时触发,调用 handleSelect 方法。background-color、text-color 和 active-text-color 属性设置菜单的样式;
<template>
<el-menu :default-active="activeIndex2" class="el-menu-demo" mode="horizontal" @select="handleSelect"
background-color="#545c6446" text-color="#fff" active-text-color="#ffd04b">
<el-col :span="4" style="margin-top: 5px"><img id="logo" src="../components/img/ao.png"></el-col>
<router-link to="/main">
<el-col :span="4">
<el-menu-item index="1">首页</el-menu-item>
</el-col>
</router-link>
<router-link to="/daily">
<el-col :span="4">
<el-menu-item index="2">每日赛程</el-menu-item>
</el-col>
</router-link>
<router-link to="/rank">
<el-col :span="4">
<el-menu-item index="4">选手排名</el-menu-item>
</el-col>
</router-link>
<router-link to="/promotion">
<el-col :span="4">
<el-menu-item index="5">晋级图</el-menu-item>
</el-col>
</router-link>
<router-link to="/about">
<el-col :span="4">
<el-menu-item index="6">了解更多</el-menu-item>
</el-col>
</router-link>
</el-menu>
</template>
卡片组件设计
-
该卡片组件用于显示两位选手的比赛成绩和国家信息,并根据两位选手的得分比较来确定胜者并添加相应的样式;
-
getWinner方法用于比较两位选手的得分,并返回一个CSS类名,以确定哪位选手是赢家。如果第一个选手的得分高于第二个选手,则将CSS类名“winner”添加到第一个选手的元素中;如果第二个选手的得分高于第一个选手,则将CSS类名“winner”添加到第二个选手的元素中。如果两个选手得分相同,则不会添加任何样式;
-
该组件使用Element UI库中的el-card和el-col组件来布局和显示信息,使用v-for指令来显示每个选手的得分。
<template>
<!-- 模仿中继器组件 -->
<el-card class="box-card">
<!-- 比较成绩,获取胜者,添加样式 -->
<div class="player" :class="getWinner(scores1, scores2)">
<!-- 国家图片 -->
<el-col :span="3"><img :src="nationList[0].nation" class="image"></el-col>
<!-- 选手姓名 -->
<el-col :span="3"><span>{{ names[0].name }}</span></el-col>
<!-- 比赛得分 -->
<el-col :span="6" offset="12">
<span class="score" v-for="item in scores1">{{ item.score }}</span>
</el-col>
</div>
<el-divider></el-divider>
<div class="player" :class="getWinner(scores2, scores1)">
<el-col :span="3"><img :src="nationList[1].nation" class="image"></el-col>
<el-col :span="3"><span>{{ names[1].name }}</span></el-col>
<el-col :span="6" offset="12">
<span class="score" v-for="item in scores2">{{ item.score }}</span>
</el-col>
</div>
</el-card>
</template>
<script>
export default {
name: "Repeater",
data() {
return {
}
},
props: {
// 国家图片的url
nationList: {
type: Array
},
// 选手姓名
names: {
type: Array
},
// 选手1得分
scores1: {
type: Array
},
// 选手2得分
scores2: {
type: Array
}
},
methods: {
getWinner(scores, otherScores) {
const sum = scores.reduce((total, score) => total + parseInt(score.score), 0);
const otherSum = otherScores.reduce((total, score) => total + parseInt(score.score), 0);
return sum > otherSum ? 'winner' : '';
}
},
}
</script>
不同组件之间的参数传递(以Title.vue为例)
<template>
<div style="margin:10px;border-radius: 20px">
<!-- 接收各页面title参数,显示出来 -->
<div class="banner">
{{ title }}
</div>
</div>
</template>
<script>
export default {
name: "Title",
props: {
title: {
type: String,
}
}
}
</script>
<style scoped>
.banner {
font-size: xx-large;
text-align: center;
color: #f1e4c9;
background-image: linear-gradient(97deg, #17caea, #6078ea);
box-shadow: 6px 6px 6px #626e85;
border-radius: 60px;
line-height: 60px;
height: 60px;
}
</style>
在首页中引用Title.vue
<template>
<div id="main" >
<!-- 传递title参数 -->
<Title :title="title"></Title>
<carousel style="width: 100%;margin: 0 auto;background-color:#fefefe;"></carousel>
</div>
</template>
<script>
import Carousel from "../components/Carousel";
import Title from "../components/Title";
export default {
name: "Main",
components: {Title, Carousel},
data(){
return{
title:"首页•资讯",
}
}
}
</script>
七、心路历程和收获
222000123:
虽然之前自己有学过Vue和SpringBoot框架,但是并没有认真写过一个项目,只懂得一些基本的语法,写起项目来磕磕碰碰,很多要用的技术想得起来却不会使用;还有许多本来可以简单实现的操作由于自己想得太复杂了,于是实现起来变得非常困难,还是得多去向别人学习,借鉴他人实用的开发方式;这次项目时间有点赶,由于刚开始没有好好规划时间,做起来手忙脚乱,后面确定了方向和使用的技术后,规划好每天要完成的任务,写起项目来才开始顺滑起来。
通过这次结对编程,我明白了不断学习回顾技术相关知识点不如多去实战写写项目积累经验,毕竟,光眼睛学会了是不够了,这样后面开发才能更加得心应手;还有,一定要做好规划,不能想到什么先写什么,这样后面项目的推进会变得非常混乱。
222000214:
- 先说问题吧,此次主要问题大概是自己的技术不过关,比如框架的学习有点赶鸭子上架,实际上自己并没有很好的运用框架来方便项目实现;其次就是过于依赖现成的模板库了,于是思维定势了,一些原生代码能够简单实现的内容还浪费了不少时间;所以说,学框架还是要深入理解,实战熟悉,否则很容易变成半吊子。
- 感觉这次结对编程中的最大收获,就是发现学习技术的路还很长,自己还要多多实践,积累项目开发经验;然后就是认为自己时间不够就乱了阵脚,抗压能力较弱这个问题也要慢慢改正了,否则也很容易影响到其他人的情绪。还是要积极地去看待并解决问题,遇到问题也要及时与伙伴商量!
八、评价结对队友
王惠对曹斯杰的评价:
曹斯杰同学做事认真积极、执行力强,善于学习新技术,没有拖延的情况,积极按照时间规划推进项目进度;通过与他的交流与合作,能够对项目所用的技术有更深刻的理解,一些自己不了解的技术也能与他进行互补;总的来说,曹斯杰同学办事效率很高,对于项目整体的方向有合理地规划,解决问题能力很强,是一位优秀可靠的队友。
曹斯杰对王惠的评价:
王惠同学在结对过程中给予了我不少帮助,也乐于分享自己学过的技术,让我能够快速的上手一些没怎么深入学习过的框架;由于这次作业时间紧、工作量大,所以自己多少有点消极,但是王惠同学能够及时根据结对进度,积极讨论调整,能很好的解决我遇到的难题,让我的心理负担少了不少;总的说来,与王惠结对合作还是很愉快的。