[]2024年第五届蓝桥杯全国软件和信息技术专业人才大赛(Web 应用开发)
一、爱拼才会赢(5分)
介绍
由爱拼社举办的拼图赛进到最后关,1 号选蓝披荆斩棘成为全场。本关卡需要选使 CSS Grid 布局完成拼图,但是由于蓝技术平有限,拼图的效果没有达到预期。现在邀请你作 为协助嘉宾帮助蓝优化拼图的效果。
本题需要在已提供的基础项中,使 CSS 让拼图正确显示。
准备
在浏览器中预览 index.html 效果如下:
目标
请使 Grid 完善 css/style.css 中的 TODO 代码,使 article 元素下第个 div 在右侧占据 2 列的位置,第 6 个 div 在左侧占据 2 列的位置,最终实现下图效果。
提示: grid-column: start / end; ,其中 start 对应值为数字,表示格项的起始位置。 end 对 应值为数字,表示格项的结束位置。
规定
- 请勿修改 css/style.css 件外的任何内容。
- 请严格按照考试步骤操作,切勿修改考试默认提供项中的件名称、件夹路径、class 名、id 名、图名等,以免造成判题法通过。
解题
1.思路:
在 grid-column 属性中,数值表示网格项的起始位置和结束位置。起始位置是指网格线的位置,结束位置是指网格线的下一个位置。
因此,当设置 grid-column: 2 / 4; 时,表示该元素从第 2 条网格线开始,到第 4 条网格线结束,占据了第 2 到第 3 列的位置。类似地,grid-column: 1 / 3; 表示该元素从第 1 条网格线开始,到第 3 条网格线结束,占据了第 1 到第 2 列的位置。
2.解题:
/* TODO:待补充代码 在 grid-column 后填空*/ /* 第二个 div */ section div:nth-of-type(2) { grid-column: 2/4; /*待补充代码 */ } /* 第六个 div */ section div:nth-of-type(6) { grid-column: 1/3; /*待补充代码 */ }
二、窗外的细雨(5分)
介绍
夏天到了,天预报今天有。红和蓝正在留意天变化,准备在下前将窗关闭并收服。请 结合向对象知识,实现点击“ 天即将变化”按钮后红和蓝分别去关窗和收服的效果。
准备
在浏览器中预览 index.html 效果如下:
目标
完善 js/index.js 件中的 TODO 部分,实现以下标:
- 完善 registerObserver 法,实现观察者注册,即将接收到的观察者对象 observer 添加到MessageSubject 类的所有观察者数组 observers 。
- 完善 notifyObservers 法,实现消息泡内容的更改,即所有观察者调update 法。(已提供)。
请注意代码的通性,观察者可以被限添加。
完成后,点击 天即将变化按钮 ,效果如下:
规定
- 请勿修改 js/index.js 件外的任何内容。
- 请严格按照考试步骤操作,切勿修改考试默认提供项中的件名称、件夹路径、class 名、id 名、图名等,以免造成判题法通过。
解题
1.思路:
根据题目要求,在registerObserver 方法中我们可以使用**push( )将观察者添加到observers数组中。在notifyObservers 方法中,使用forEach()**遍历观察者数组,依次调用每个观察者的 update 方法。
只需两行代码即可。
2.解题:
// MessageSubject 类表示被观察者,即天气 class MessageSubject { constructor() { // 用一个数组来存储所有观察者 this.observers = []; } // 注册观察者 registerObserver(observer) { //TODO:待补充代码 this.observers.push(observer); } // 通知所有观察者执行相应的操作 update(已提供) notifyObservers() { //TODO:待补充代码 this.observers.forEach(observer => { observer.update(); // 调用每个观察者的 update 方法 }); } }
三、年会不能停(10分)
介绍
蓝胖在公司上班多年,公司直没有举什么年会活动,很多员都在背后抱怨。板为了安抚 ,让蓝胖设计个抽奖活动,蓝胖设置的奖品有机、空调、平板、200 现,并且设置对应的 中奖概率分别为 10% , 20% , 30% , 40% 。
准备
在浏览器中预览 index.html 效果如下:
目标
完成 index.html 中的 TODO 部分代码 ,实现以下标:
- 不使任何第三库的情况下,请求奖品数据(请求地址必须使提供的常量 MockUrl),将请求 数据赋值给已有 list 变量,并在 .reward 元素内(注意:不是循环 .reward 元素)正确渲染 奖品。
请求来的数据如下:
奖品在 .reward 元素中的 DOM 结构如下:
标 1 完成后效果如下:
2.完善 reward 法,返回值是根据相应概率从 list 中选取奖品的索引,为数值类型。
- 机【索引为 0】的概率是 10%。
- 空调【索引为 1】的概率是 20%。
- 平板【索引为 2】的概率是 30%。
- 200 现【索引为 3】的概率是 40%。
规定
- 请勿修改 index.html 件外的任何内容。
- 请严格按照考试步骤操作,切勿修改考试默认提供项中的件名称、件夹路径、class 名、id 名、图名等,以免造成判题法通过。
解题
1.思路:
目标一:
题目要求不能使用第三方库请求数据,那么我们可以考虑使用fetch方法从MockUrl获取奖品数据并赋值给list(如图3.1),之后在模板中使用 v-for 指令遍历奖品列表,显示每个奖品的图片、名称、等级和中奖概率(如图3.2)。
图3.1
图3.2
目标二:
首先生成一个随机数 rand,然后遍历奖品列表,累加每个奖品的概率,当随机数小于等于累加值时,返回当前奖品的索引。(如图3.3)
图3.3
2.解题:
完整index.html代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>年会不能停</title> <link rel="stylesheet" href="./css/style.css"> </head> <body> <div id="app"> <h1 class="title">抽奖活动</h1> <div class="reward" v-if="list&&showList"> <!-- TODO:待补充代码 --> <div v-for="item in list" :key="item.title"> <img class="reward-image" :src="item.src" /> <div class="reward-title">{{ item.title }}</div> <div class="reward-level">{{ item.prizeLevel }}</div> <div class="reward-probability">中奖概率:{{ item.probability }}</div> </div> </div> <div v-else> <img class="reward-image" :src="goods.src" alt="Reward Image"> <div class="reward-title">{{ goods.title }}</div> <div class="reward-level">{{ goods.prizeLevel }}</div> <div class="tips">恭喜你中奖啦!</div> </div> <div class="button" v-if="showList"> <button @click="handleReward">抽奖</button> </div> </div> <script src="./lib/vue.global.prod.js"></script> <script> const { createApp, ref } = Vue; let reward; // 定义reward 函数 -> 检测需要,请勿修改或删除 const MockUrl= `./mock/data.json`; // 请求地址 const app = createApp({ setup() { const list = ref([]); // 奖品列表 // TODO:待补充代码 const MockUrl = `./mock/data.json`; Vue.onMounted(() => { fetch(MockUrl) .then(response => response.json()) .then(data => { list.value = data; }); }); const goods = ref(null); const showList = ref(true); reward = () => { // TODO:待补充代码 const rand = Math.random() * 100; let sum = 0; for (let i = 0; i < list.value.length; i++) { sum += parseInt(list.value[i].probability); if (rand <= sum) { return i; } } return list.value.length - 1; }; const handleReward = () => { const i = reward(); goods.value = list.value[i]; showList.value = false; }; return { list, goods, showList, handleReward, reward }; }, }); const vm = app.mount('#app'); </script> </body> </html>
四、照片展览馆(10分)
介绍
蓝是名摄影爱好者,他如同收集宝藏般收藏了量精美的摄影作品。有天,他中萌了个 美妙的构想—— 创建个独特的平台,将他珍藏的这些摄影珍品展示给世界,不仅便他随时回味,还 能让其他欣赏到这些视觉杰作。
然,他并不熟悉 Vue 和 Element Plus 。快来帮助他把梦想变为现实吧!
准备
在浏览器中预览 index.html 效果如下:
目标
请在 components/List.js 件中补全代码,具体需求如下:
- 在
元素上 增加限滚动的配置,使户滑动到距离底部 48 像素时调 loadMoreData 函数。并在 loadMoreData 函数中补全代码,调已定义的 loadNextPageData 加载下数据增加到已有的数据列表 变量 data 中。loadNextPageData 函数返回的是个 promise ,于获取下的数据,数据格式如下( 注意每次 调 loadNextPageData 返回的数据是不同的 ) :
2.在 组件中增加配置,使点击照时,显示当前照的全屏预览图。
在 components/List.js 件中写好了来根据照 id 获取图源地址的函数 getImageSourceById ,其参是照 id , 返回值是对应的图源地址 。
本项中使到的 element-plus 相关 API 如下:
- Infinite Scroll (限滚动)
在要 实现滚动加载的列表上添加 v-infinite-scroll ,并赋值相应的加载法,可实现滚动到底部时 动执加载法。
- Image (图)
图容器,在保留所有原 img 的特性下,持懒加载,定义占位、加载失败等。
最终效果可参考件夹下的 gif 图,图名称为 effect.gif
规定
- 不要修改除 components/List.js 外的任何件。
- 请严格按照考试步骤操作,切勿修改考试默认提供项中的件名称、件夹路径、class 名、id 名、图名等,以免造成判题法通过。
解题
1.思路:
目标一:
根据提供的 element-plus 相关 API,在**
<div class="scroll-container">
元素上添加了v-infinite-scroll
指令,并指定了加载更多数据的方法为loadMoreData
。同时,使用infinite-scroll-distance=“48”,****实现**户滑动到距离底部 48 像素时调 loadMoreData 函数。在loadMoreData中调用loadNextPageData(),之后再将下一页数据添加到已有数据列表中。
目标二:
在
<el-image>
组件中使用**preview-src-list
**属性来开启图像预览功能,并传入当前图像的源地址。2.解题:
完整代码:
const template = ` <!-- TODO: 待补充代码 --> <div class="scroll-container" v-infinite-scroll="loadMoreData" infinite-scroll-distance="48"> <div v-for="(item) in data" :key="item.title" class="card-container"> <!-- TODO: 待补充代码 --> <el-image :src="getImageSourceById(item.id)" class="photo" fit="contain" :preview-src-list="[getImageSourceById(item.id)]"> <template #error> <photo-error /> </template> </el-image> <span class="desc-line">作者: {{ item.author }}</span> <span class="desc-line">摄于: {{ item.location }}</span> <span class="desc-line">设备: {{ item.device }}</span> </div> </div>`; const List = { template, setup() { const { ref } = Vue; const data = ref([]); // 页面数据 /** 根据 id 获取 url */ function getImageSourceById(id) { return `./images/${id}.jpg`; } /** 页面滑动到底部时,加载更多数据 */ async function loadMoreData() { // TODO: 待补充代码 const nextPageData = await loadNextPageData(); // 调用加载下一页数据的函数 data.value = [...data.value, ...nextPageData]; // 将下一页数据添加到已有数据列表中 } return { data, getImageSourceById, loadMoreData, }; }, };
五、蓝桥云课开发者大会(15分)
介绍
蓝桥云课开发者会直播测试作正在进中,在直播测试时,发现了些技术问题,导致了聊天功能 和点赞功能的暂时失效。作为前端程师,你需要迅速动起来,致于迅速修复这问题,以确保您 的会议体验不受任何扰。
准备
目标
请在 js/index.js 件中的 TODO 部分,实现以下标:
1. 实现聊天功能:输聊天内容后,按下回键将触发 handleSend 法。请补充 handleSend 法中的 TODO 部分,实现 获取输框(标签 )元素的值 ,并将聊天消息的 dom 段插 到聊天区域中( class=msg-area ) ,然后 清空输框的值 。
2. 请补充 onMouseUp 法中的 TODO 代码,实现点赞和连续点赞的统计功能:点击点赞按钮 ( class=btn-like )时,将 点赞总次数显示在 .like-total>span 处;如果连续点赞 次数于等 于 5 ,则将 连续点赞次数显示在 .like-continuous>span 处并显示出连续点赞的样式 (即将class=like-continuous 的元素 display 设置为 block )
连续点赞的判断规则如下:
如果此次点赞的时间距离上次点赞的时间于 400ms ,则算连续点赞,否则为连续点赞中断,则从 1 重新开始计算连续点赞次数。注意:可以有多次连续点赞。
标 2 最终效果:
规定
- 请勿修改 js/index.js 件外的任何内容。
- 请严格按照考试步骤操作,切勿修改考试默认提供项中的件名称、件夹路径、class 名、id 名、图名等,以免造成判题法通过。
解题
1.思路:
目标一:
通过**document.querySelector(‘input’)获取到页面中的输入框元素,并通过inputElement.value.trim()**获取输入框的值并去除首尾空格,赋值给inputValue变量。
之后,判断inputValue是否为空,如果不为空则继续执行后续操作。
使用**document.querySelector(‘.msg-area’)**获取到页面中的消息区域元素。
创建一个新的div元素msgItem作为消息项。
创建两个span元素authorSpan和messageSpan,分别用于显示作者和消息内容,设置相应的文本内容和样式,并将它们添加到msgItem中。
最后,将msgItem添加到消息区域msgArea中,并清空输入框的值。
function handleSend() {
// TODO:目标1 待补充代码
const inputElement = document.querySelector(‘input’);//)获取到页面中的输入框元素
const inputValue = inputElement.value.trim();//获取输入框的值并去除首尾空格,赋值给inputValue变量
if (inputValue !== ‘’) {//inputValue是否为空,如果不为空则继续执行后续操作
const msgArea = document.querySelector(‘.msg-area’);//获取到页面中的消息区域元素
const msgItem = document.createElement(‘div’);//创建一个新的div
msgItem.classList.add(‘msg-item’);//msgItem作为消息项
const authorSpan = document.createElement(‘span’);//创建两个span元素authorSpan和messageSpan,
//分别用于显示作者和消息内容,设置相应的文本内容和样式
authorSpan.classList.add(‘author’);
authorSpan.innerText = ‘阳阳?:’;
const messageSpan = document.createElement(‘span’);
messageSpan.innerText = inputValue;
msgItem.appendChild(authorSpan);//添加到msgItem中
msgItem.appendChild(messageSpan);
msgArea.appendChild(msgItem);//将msgItem添加到消息区域msgArea中
inputElement.value = ‘’;//并清空输入框的值
}
// TODO: END
// 将聊天区域滚动到底部
msgArea.scrollTop = msgArea.scrollHeight;
}目标二:
2.解题:
六、JavaScript代码规范检查器(15分)
介绍
JavaScript 是种泛使的编程语,为了保证代码的质量和致性,需要有套规范和标准来指导 编写代码。本题提供了个实现基本 JavaScript 代码规范实时检查功能的具,可以帮助开发者快速发 现并修复代码中的问题,提代码质量和可维护性。
准备
目标
请在 codeLint.js 件中的 TODO 部分,完善 checkCode 函数,实现代码规范检查。
函数功能说明:
checkCode 函数于实时检查 JavaScript 代码的规范性。该函数接收个名为 code 的参数表示 code.js 件的内容。
函数返回值为包含代码中存在问题的数组 issues 。 issues 数组的规则是:每个元素都必须是个对 象,并且只能包含以下两个属性: lineNumber 是问题所在的号, message 是问题的具体描述。
?? checkCode 函数需要完成以下标:
- 如果在代码中使了 console ,则将 message 设为 “避免在产代码中使 console”。
- 如果使了 var 关键字来声明变量,则将 message 设为 “禁使 var 声明变量,推荐使 let 或 const”。
- 如果定义了但是没有使的变量,则将 message 设为 “变量 variableA 定义未使”,并实际的 变量名替换 variableA 。代码中已经提供并调了 extractVarName() 函数,于获取当前 let 或 const 定义的变量名,如果有值则返回变量名,否则返回 null 。
- checkCode 函数的返回值 issues 数组需要按照号 ( lineNumber ) 从到的顺序升序排列, 如果没有发现问题,则返回个空数组。
规定
- 请严格按照考试步骤操作,切勿修改考试默认提供项中的件名称、件夹路径、class 名、id 名、图名等,以免造成判题法通过。
解题
暂无,欢迎补充
1.思路;
2.解题:
七、搜索指数(20分)
介绍
搜索指数是指于衡量特定搜索词或短语在搜索引擎中的受欢迎程度的指标。通常情况下,搜索指数可 以衡量出段时间内搜索特定关键词或短语的数量。搜索指数可以帮助营销员、SEO 专业员和企业 决策者了解市场趋势和消费者兴趣的变化,以便根据这些变化调整他们的策略和营销活动。
·本题会提供组户的搜索记录,需要你按照要求将其处理成所需的数据结构并正确渲染在上。
准备
在浏览器中预览 index.html 效果如下:
目标
请在 js/index.js 件中的 TODO 部分,完善 getxAxis 和 getSeriesData 函数,实现以下 标:
1. 补充 getxAxis 函数中的代码, 根据参数 searchKey 和 platform 字段,提取参数 data 中的 期 , 去重 并 升序排序 ,最终存储在数组 xAxis 中返回。
最终返回的数组数据结构如下:
2. 补充 getSeriesData 函数中的代码,根据参数 searchKey 和 platform 字段对参数 data 进 条件筛选,注意与参数 dateArr 所存储的期进对应,提取 data 中的 count 属性,将 同期下的 count 字段值累加之和保存数组 sData 中返回。
最终效果:
解题