110
社区成员
这个作业属于哪个课程 | 2024软件工程实践 |
---|---|
这个作业要求在哪里 | 结对第二次作业——编程实现 |
结对学号 | 222200118,222200107 |
这个作业的目标 | 编码实现网页原型 |
其他参考文献 | 《构建之法》 |
PSP | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 30 |
•Estimate | • 估计这个任务需要多少时间 | 30 | 30 |
Development | 开发 | 900 | 1200 |
•Analysis | • 需求分析 | 30 | 30 |
•Learning | • 学习新技术 | 600 | 900 |
•Coding Standard | •代码规范 | 20 | 20 |
• Code | • 具体编码 | 600 | 660 |
• Deploy | • 部署服务器 | 60 | 180 |
Reporting | 报告 | 60 | 60 |
• Test Repor | • 测试报告 | 30 | 30 |
• Size Measurement | • 计算工作量 | 10 | 10 |
• Postmortem & Process Improvement Plan | • 事后总结, 并提出过程改进计划 | 20 | 20 |
合计 | 1595 | 2070 |
点击该按钮,会出现可选择的页面,例如首页、奖牌榜等五个选项,点击即可跳转。若没有跳转,再点击一下选择页面会消失。
黑色面板放置在结尾,可点击跳转到指定界面
首页左上角是跳转按钮;开头会有五张图流转播放,每3s一次;往下移动,会有两个大面板,点击跳转按钮会分别跳转到奖牌榜和每日赛况;再往下移动就是黑色面板的结尾。
奖牌榜通过爬虫获得数据存入TotalData.json,然后将获取到数据放存入面板再用for语句进行垂直放置。
当点击日期按钮,会出现可选日期。最后,选择按钮即可跳转到日期的相关赛程。
当鼠标移动到某一场比赛会显示高亮。
了解更多设置了三个按钮,会分别跳转到三个关于奥林匹克的介绍中,三个界面会有返回键返回至了解更多,同时最底下都配有黑色的面板。
任务刚发布时就已经开始分工,遇到问题会在qq群讨论
一起合作完成作业照片
黑色面板代码
<template>
<div class="parent-container">
<!-- 使用全局组件 MenuComponent -->
<MenuComponent />
<img :src="imagePath" alt="Top Image1" class="top-blue-image" />
<img :src="imagePath_1" alt="Second Image1" class="second-image" />
<p class="first-text">顺序 NOC</p>
<div style="margin-left:6%">
<div v-for="ranking in rankings" :key="ranking.country" class="white-panel">
<span style="position: absolute;margin-left:6%;font-weight: bold">{{ ranking.rank }}</span>
<img :src="ranking.qizi" :style="{ 'margin-left': '12%', 'width': '60px' }" />
<span style="position: absolute;margin-left:20%">{{ ranking.country }}</span>
<span style="position: absolute;margin-left:57%">{{ ranking.gold }}</span>
<span style="position: absolute;margin-left:69%">{{ ranking.silver }}</span>
<span style="position: absolute;margin-left:81%">{{ ranking.bronze }}</span>
<span style="position: absolute;margin-left:90%;font-weight: bold">{{ ranking.total }}</span>
</div>
</div>
<div class="last-panel">
<img :src="imgSrc" class="img" />
<button @click="navigate('FirstPage')">首页</button>
<button_1 @click="navigate('SecondPage')">奖牌榜</button_1>
<button_2 @click="navigate('ThirdPage')">每日赛程</button_2>
<button_3 @click="navigate('LastPage')">了解更多</button_3>
</div>
</div>
</template>
<script>
import axios from 'axios';
import imagePath_2 from '@/assets/2.png';
import imagePath from '@/assets/11.jpg';
import imagePath_1 from '@/assets/12.png';
export default {
data() {
return {
imagePath: imagePath,
imagePath_1: imagePath_1,
imgSrc: imagePath_2,
rankings: []
};
},
methods: {
navigate(pageName) {
if (this.$route.name!== pageName) {
this.$router.push({ name: pageName });
}
},
},
created() {
axios.get('TotalDate.json')
.then(response => {
this.rankings = response.data.rankings;
});
},
};
</script>
跳转按钮
<template>
<div>
<!-- 圆形按钮 -->
<div class="floating-button-container">
<button class="menu-button" @click="showPanel = !showPanel">
<span class="bar"></span>
<span class="bar"></span>
<span class="bar"></span>
</button>
</div>
<!-- 大面板 -->
<div v-if="showPanel" class="panel" style="position: absolute; top: 90px; left: 40px; z-index: 9999;">
<!-- 小按钮容器 -->
<div class="button-group">
<button class="small-button" style="font-size: 32px;" @click="goToFirstPage">首页</button>
<button class="small-button" style="font-size: 32px;" @click="goToSecondPage">奖牌榜</button>
<button class="small-button" style="font-size: 32px;" @click="goToThirdPage">每日赛程</button>
<button class="small-button" style="font-size: 32px;" @click="goToDuiZhenTu">对阵表</button>
<button class="small-button" style="font-size: 32px;" @click="goToLastPage">了解更多</button>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
showPanel: false // 控制面板显示的数据属性
};
},
methods: {
goToFirstPage() {
if (!this.$route.name || this.$route.name!== 'FirstPage') {
this.$router.push({ name: 'FirstPage' });
}
},
goToSecondPage() {
if (!this.$route.name || this.$route.name!== 'SecondPage') {
this.$router.push({ name: 'SecondPage' });
}
},
goToThirdPage() {
if (!this.$route.name || this.$route.name!== 'ThirdPage') {
this.$router.push({ name: 'ThirdPage' });
}
},
goToDuiZhenTu() {
if (!this.$route.name || this.$route.name!== 'DuiZhenTu') {
this.$router.push({ name: 'DuiZhenTu' });
}
},
goToLastPage() {
if (!this.$route.name || this.$route.name!== 'LastPage') {
this.$router.push({ name: 'LastPage' });
}
},
}
};
</script>
循环获取数据的代码
<div style="margin-left:6%">
<div v-for="ranking in rankings" :key="ranking.country" class="white-panel">
<span style="position: absolute;margin-left:6%;font-weight: bold">{{ ranking.rank }}</span>
<img :src="ranking.qizi" :style="{ 'margin-left': '12%', 'width': '60px' }" />
<span style="position: absolute;margin-left:20%">{{ ranking.country }}</span>
<span style="position: absolute;margin-left:57%">{{ ranking.gold }}</span>
<span style="position: absolute;margin-left:69%">{{ ranking.silver }}</span>
<span style="position: absolute;margin-left:81%">{{ ranking.bronze }}</span>
<span style="position: absolute;margin-left:90%;font-weight: bold">{{ ranking.total }}</span>
</div>
</div>
router/index.js,即跳转到js文件
import Vue from 'vue';
import Router from 'vue-router';
import FirstPage from '../components/FirstPage.vue';
import SecondPage from '../components/SecondPage.vue';
import ThirdPage from '../components/ThirdPage.vue';
import LastPage from '../components/LastPage.vue';
import LastPage_1 from '../components/LastPage_1.vue';
import LastPage_2 from '../components/LastPage_2.vue';
import LastPage_3 from '../components/LastPage_3.vue';
import DuiZhenTu from '../components/DuiZhenTu.vue';
Vue.use(Router);
export default new Router({
mode: 'history',
routes: [
{
path: '/',
name: 'FirstPage',
component: FirstPage,
},
{
path: '/secondpage',
name: 'SecondPage',
component: SecondPage,
},
{
path: '/thirdpage',
name: 'ThirdPage',
component: ThirdPage,
},
{
path: '/lastpage',
name: 'LastPage',
component: LastPage,
},
{
path: '/lastpage_1',
name: 'LastPage_1',
component: LastPage_1,
},
{
path: '/lastpage_2',
name: 'LastPage_2',
component: LastPage_2,
},
{
path: '/lastpage_3',
name: 'LastPage_3',
component: LastPage_3,
},
{
path: '/duizhentu',
name: 'DuiZhenTu',
component: DuiZhenTu,
},
],
});
App.vue(主要的vue文件)
<template>
<div>
<!-- <router-link to="/">FirstPage</router-link>
<router-link to="/secondpage">SecondPage</router-link> -->
<!-- 使用 router-view 来显示匹配的路由组件 -->
<router-view></router-view>
</div>
</template>
<script>
import Vue from 'vue';
import router from './router';
import MenuComponent from './components/MyButton.vue';
import BlackPanel from './components/BlackPanel.vue';
import LastPage_1 from './components/LastPage_1.vue';
import LastPage_2 from './components/LastPage_2.vue';
import LastPage_3 from './components/LastPage_3.vue';
Vue.component('MenuComponent', MenuComponent);
Vue.component('BlackPanel', BlackPanel);
Vue.component('LastPage_1', LastPage_1);
Vue.component('LastPage_2', LastPage_2);
Vue.component('LastPage_3', LastPage_3);
export default {
name: 'App',
router, // 使用路由
};
</script>
<style>
/* 全局样式 */
</style>
json文件:
对阵图的交互,实现名字一样的会同时亮起
<div class="big-panel" style="top: 800px; left: 240px;">
<div class="panel" @mouseenter="onMouseEnterPanel1First" @mouseleave="onMouseLeavePanel1First" style="top:5px;">
<img src="https://gstatic.olympics.com/s1/t_original/static/noc/oly/3x2/180x120/FRA.png" alt="description">
<span class="text-left" style="font-weight: bold;">法国</span>
<span class="text-right" style="font-weight: bold;">1</span>
</div>
<div class="panel" @mouseenter="onMouseEnterPanel1Second" @mouseleave="onMouseLeavePanel1Second" style="top:60px;">
<img src="https://olympics.com/OG2024/assets/images/flags/OG2024/ARG.webp" alt="description1">
<span class="text-left">阿根廷</span>
<span class="text-right" style="font-weight: bold;">1(5)</span>
</div>
</div>
<script>
import imagePath from '@/assets/24.jpg';
import imagePath_1 from '@/assets/25.png';
import imagePath_2 from '@/assets/26.png';
export default {
data() {
return {
imagePath: imagePath,
imagePath_1: imagePath_1,
imagePath_2: imagePath_2,
};
},
methods: {
onMouseEnterPanel1First() {
this.highlightPanels('法国');
},
onMouseLeavePanel1First() {
this.resetPanels();
},
onMouseEnterPanel1Second() {
this.highlightPanels('阿根廷');
},
onMouseLeavePanel1Second() {
this.resetPanels();
},
onMouseEnterPanel2First() {
this.highlightPanels('埃及');
},
onMouseLeavePanel2First() {
this.resetPanels();
},
onMouseEnterPanel2Second() {
this.highlightPanels('巴拉圭');
},
onMouseLeavePanel2Second() {
this.resetPanels();
},
onMouseEnterPanel3First() {
this.highlightPanels('摩洛哥');
},
onMouseLeavePanel3First() {
this.resetPanels();
},
onMouseEnterPanel3Second() {
this.highlightPanels('美国');
},
onMouseLeavePanel3Second() {
this.resetPanels();
},
onMouseEnterPanel4First() {
this.highlightPanels('日本');
},
onMouseLeavePanel4First() {
this.resetPanels();
},
onMouseEnterPanel4Second() {
this.highlightPanels('西班牙');
},
onMouseLeavePanel4Second() {
this.resetPanels();
},
onMouseEnterPanel5First() {
this.highlightPanels('法国');
},
onMouseLeavePanel5First() {
this.resetPanels();
},
onMouseEnterPanel5Second() {
this.highlightPanels('埃及');
},
onMouseLeavePanel5Second() {
this.resetPanels();
},
onMouseEnterPanel6First() {
this.highlightPanels('摩洛哥');
},
onMouseLeavePanel6First() {
this.resetPanels();
},
onMouseEnterPanel6Second() {
this.highlightPanels('西班牙');
},
onMouseLeavePanel6Second() {
this.resetPanels();
},
onMouseEnterPanel7First() {
this.highlightPanels('法国');
},
onMouseLeavePanel7First() {
this.resetPanels();
},
onMouseEnterPanel7Second() {
this.highlightPanels('西班牙');
},
onMouseLeavePanel7Second() {
this.resetPanels();
},
onMouseEnterPanel8First() {
this.highlightPanels('埃及');
},
onMouseLeavePanel8First() {
this.resetPanels();
},
onMouseEnterPanel8Second() {
this.highlightPanels('摩洛哥');
},
onMouseLeavePanel8Second() {
this.resetPanels();
},
highlightPanels(countryName) {
const panels = document.querySelectorAll('.panel');
panels.forEach(panel => {
const country = panel.querySelector('.text-left').textContent;
if (country === countryName) {
panel.classList.add('hovered');
panel.querySelectorAll('.text-left,.text-right').forEach(textElement => {
textElement.style.color = 'white';
});
}
});
},
resetPanels() {
const panels = document.querySelectorAll('.panel');
panels.forEach(panel => {
panel.classList.remove('hovered');
panel.querySelectorAll('.text-left,.text-right').forEach(textElement => {
textElement.style.color = 'black';
});
});
},
},
};
</script>
问题①
困难描述:一开始我们结对作业没有进行太过详细的解释,只是简单的分工。到了后面几天发现222200118用的是vue3,222200107用的是vue2,虽然差别不大,但是两人的代码在对方的vscode上都带不动。
解决方法:因为22220107做的内容较多,所以将主要的工具设置为vue2。接着,222200118将vue2的制作流程学会,并转换成功;同时,222200107将他的vue2的全部代码给22220118,因为两者本来差别都不大,都成功运行。
是否解决:是的,虽然刚开始有些不知所措,但通过查阅资料并实践操作,逐渐解决问题。
收获:在分好工后还要确定好团队的制作工具等制作细节。
问题②
困难描述:在设计跳转按钮时,总是会有灰色的大面板在按底下,同时将按钮的vue文件与别的交互时,出现了大范围的错版,当时我们两个都以为是电脑卡了都没在意,直到我们两个人的页面都出现了错版才意识到问题的严重性......
解决方法:style scoped和style的区别!一个是全局的,一个是当前vue的,当时没有注意到这个问题,困扰了我们一天才发现这个问题(感谢chatgtp)
是否解决:解决。
收获:在编程时,一定要在意细节。同时当两个人都出现问题时,一定不是设备的问题,是代码的问题(害得222200107当时改局部ccs改的贼难受),同时,出现问题一定要及时去问别人,结合别人的经验才能更好地解决问题,不要死磕!
问题③
困难描述:有一次一不小心把vscode关闭,当时还没弄好华为云,导致修改好的代码消失,尤其是在搞对阵图的时候一大串的交互消失,最后只能重做。
解决方法:无!只能下次做好的时候记得把修改好的代码传送进华为云中,这样才能保证因为误触导致的代码再修改。
是否解决:无。
收获:一定要记得及时保存代码!一定要及时上传到华为云中!
222200118 to 222200107:结对过程非常愉快,我们二人可以长短互补。因为已经是第二次的合作了,相互熟悉后效率大大提高。
222200107 to 222200118:非常好队友,使我原地旋转。与熟悉的人一起完成任务是之前没有的体验,我们能再次一起互帮互助,过程愉快。