【蓝桥杯Web】2022年第十三届蓝桥杯Web大学组国赛真题解析
前言
省赛真题解析见:
2022年第十三届蓝桥杯Web大学组省赛真题解析(完整版)
2022年第十三届蓝桥杯Web大学组省赛真题解析(精华版)
更多蓝桥杯题解请查阅专栏:蓝桥杯
之前写省赛解析时篇幅过长,写的花里胡哨的,导致文章阅读体验不好,这次就不整那些了,直接贴代码,解析都写在代码注释里了,相信各位老大稍微思考一下就能够理解了,同样的,相应的真题代码
也会分享给大家:
「蓝桥杯」https://www.aliyundrive.com/s/7fsobhSy8dZ 提取码: 34pi
如果在阅读文章时大佬有好的见解,或者发现了问题,还请多多留言,互相探讨
文章目录
- 前言
- 1、分一分(5分)
- 2、新鲜的蔬菜(5 分)
- 3、水果消消乐(10分)
- 4、用什么来做计算A (10分)
- 5、开学礼物大放送(15 分)
- 6、权限管理(15 分)
- 7、一起会议吧(20分)
- 8、天气趋势A (20分)
- 9、JSON生成器(25 分)
- 10、商城管理系统(25 分)
- 总结心得
1、分一分(5分)
/*** @param {Object} oldArr* @param {Object} num* */
const splitArray = (oldArr, num) => {// TODO:请补充代码实现功能let newArr = [];// 升序排序后解构赋值深拷贝给oldArr2let oldArr2 = [...oldArr.sort((a, b) => a - b)];const len = oldArr2.length;for (let i = 0, j = 0; i < len; i += num, j++) {// splice() 方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。newArr[j] = oldArr2.splice(0, num);}return newArr;
};
module.exports = splitArray; // 检测需要,请勿删除
2、新鲜的蔬菜(5 分)
/* TODO:待补充代码 */#box1 {display: flex;justify-content: center;align-items: center;
}#box2,
#box3 {display: flex;flex-direction: column;justify-content: space-between;
}#box2 span:nth-child(2),
#box3 span:nth-child(3) {align-self: flex-end;
}#box3 span:nth-child(2) {align-self: center;
}
3、水果消消乐(10分)
// TODO:请补充代码
function startGame() {$("img").show(500);$("#start").hide();$("img").hide(500);// 已经点击的数量let i = 0;// 存放已经点击的元素let clickImg = [];[...$(".img-box")].forEach((item) => {item.onclick = function () {i++;if (i <= 2) {$(item.children).show();clickImg.push(item);if (i === 2) {setTimeout(() => {let score = $("#score")[0];if (clickImg[0].children[0].alt ===clickImg[1].children[0].alt) {score.innerHTML = Number(score.innerHTML) + 2;$(clickImg[0]).css({// 隐藏元素且保留元素所占位置visibility: "hidden",});$(clickImg[1]).css({visibility: "hidden",});} else {score.innerHTML = Number(score.innerHTML) - 2;$(clickImg[0].children[0]).hide();$(clickImg[1].children[0]).hide();}clickImg = [];i = 0;}, 400);}}};});
}
4、用什么来做计算A (10分)
// TODO:请补充代码
const btn = document.getElementsByClassName("calc-button");
const formula = document.getElementById("formula");
const result = document.getElementById("result");// 计算机表达式展示
let showText = "";
// 计算结果
let num = "";[...btn].forEach((item) => {item.onclick = function () {switch (this.id) {// 点击 =case "equal":// eval() 函数会将传入的字符串当做 JavaScript 代码进行执行。num = eval(showText.replace("x", "*").replace("÷", "/"));result.value = num;return;// 点击 √case "sqrt":num = eval(showText.replace("x", "*").replace("÷", "/"));num = Math.sqrt(num);result.value = num;return;// 点击 ACcase "reset":showText = "";num = "";formula.value = showText;result.value = num;return;default:showText += this.innerHTML;formula.value = showText;return;}};
});
5、开学礼物大放送(15 分)
考察的只是简答的页面实现,每个人的实现方式不同,代码差异也很大,这里就不放代码了
6、权限管理(15 分)
$(function () {// 使用 ajax 获取 userList.json 数据并渲染到页面getData();// 为按钮添加事件$("#add").click(function () {// TODO:补充代码,实现功能// 获取选中的optionlet option = $("#leftSelect option:selected");// jQ方法:each() 遍历jQ获取的节点option.each((index, item) => {// 删除左侧对应的option$(`#leftSelect option[value=${item.value}]`).remove();// 向右侧添加option$("#rightSelect")[0].add(new Option(item.value, item.value));});changeAccess("管理员", option);});$("#addAll").click(function () {// TODO:补充代码,实现功能let option = $("#leftSelect option");option.each((index, item) => {$(`#leftSelect option[value=${item.value}]`).remove();$("#rightSelect")[0].add(new Option(item.value, item.value));});changeAccess("管理员", option);});$("#remove").click(function () {// TODO:补充代码,实现功能let option = $("#rightSelect option:selected");option.each((index, item) => {$(`#rightSelect option[value=${item.value}]`).remove();$("#leftSelect")[0].add(new Option(item.value, item.value));});changeAccess("普通用户", option);});$("#removeAll").click(function () {// TODO:补充代码,实现功能let option = $("#rightSelect option");option.each((index, item) => {$(`#rightSelect option[value=${item.value}]`).remove();$("#leftSelect")[0].add(new Option(item.value, item.value));});changeAccess("普通用户", option);});
});/*** 修改权限* @param {Object} right 要修改的权限* @param {Object} changeList 要修改权限的用户列表*/
function changeAccess(right, changeList) {// TODO:补充代码,实现功能changeList.each((index, item) => {// 将option.value与tr.name对应,找到对应的td并修改其内容// jQ方法::last 获取最后个元素$(`#userList tr[name=${item.value}] td:last`).html(right);});
}
// 异步获取数据
function getData() {// TODO:补充代码,实现功能$.ajax("./js/userList.json").then((res) => {res.forEach((item) => {// jQ方法:html() 设置html内容$("#userList tbody").html($("#userList tbody").html() +` <tr name=${item.name}><td>${item.name}</td><td>${item.right ? "管理员" : "普通用户"}</td> </tr>`);});});
}
7、一起会议吧(20分)
<!DOCTYPE html>
<html><head><meta charset="utf-8" /><title>一起会议吧</title><link rel="stylesheet" type="text/css" href="./css/index.css" /><link rel="stylesheet" href="./css/iconfont/iconfont.css" />
</head><body><div id="app"><!-- TODO:请在下面实现需求 --><!-- 登录/注销窗口 --><div class="login"><div class="left-tools"><a class="close-btn"></a><a class="shrink-btn"></a></div><h3>{{isLogin?'注销':'登录'}}</h3><p v-if="!isLogin">选择用户:<select id="selectUser" @change="changeOption($event)"><option :value="item.id" v-for="item in list" :key="item.id">{{item.name}}</option></select></p><p v-else>当前用户为:{{loginUser.name}}</p><a class="login-btn" @click="btn">{{isLogin?'注销':'登录'}}</a></div><!-- 右侧显示用户列表窗口按钮 --><button id="show" class="right-btn" v-if="!showUser&&isLogin" @click="showUser=true"><span class="iconfont icon-left-arrow"></span></button><!-- 用户列表窗口 --><div class="user-dialog" v-if="isLogin&&showUser"><!-- 用户列表窗口上侧工具栏 --><ul class="tools"><li class="tools-left"><button :class="{'active':isButton<0}" @click="isButton=-1"><span class="iconfont icon-close"></span></button><button :class="{'active':isButton=='0'}" @click="isButton=0"><span class="iconfont icon-dialog"></span></button><button :class="{'active':isButton>0}" @click="isButton=1"><span class="iconfont icon-list"></span></button></li><li class="tools-right"><button class="show-list" @click="showUser=false"><span class="iconfont icon-retract"></span></button></li></ul><!-- 用户列表 --><ul class="say-list"><li><span class="iconfont icon-microphone"></span></li><li class="line"></li><li>正在讲话:{{list.find(item=>item.isHost).name}};</li></ul><ul class="user-list"><li v-show="isButton>=0"><img class="header" :src="loginUser.imgPath" /><div class="user-name"><span class="iconfont icon-user header-icon" v-if="loginUser.isHost"></span><span class="iconfont icon-microphone"></span> {{loginUser.name}}</div></li><li v-for="item in list" :key="item.id" v-if="item.id!==loginUser.id" v-show="isButton>0"><img class="header" :src="item.imgPath" /><div class="user-name"><span class="iconfont icon-user header-icon" v-if="item.isHost"></span><span class="iconfont icon-microphone"></span> {{item.name}}</div></li></ul></div></div><script type="text/javascript" src="./js/vue.js"></script><script type="text/javascript" src="./js/axios.min.js"></script><script type="text/javascript">// TODO:请在下面实现需求new Vue({el: "#app",data: {// 用户列表list: [],// 选择用户idvalue: '1',// 是否登录isLogin: false,// 是否显示用户参会窗口showUser: true,// 登录的用户信息loginUser: {},// 用户列表显示效果切换的状态isButton: 0},created() {axios.get('./js/userList.json').then(res => {this.list = res.data})},methods: {btn() {this.isLogin = !this.isLoginif (this.isLogin) {this.loginUser = this.list.find(item => item.id == this.value)} else {this.loginUser = {}this.value = '1'this.isButton = 0this.showUser = true}},// 选择下拉框用户时changeOption(e) {this.value = e.target.value}}});</script>
</body></html>
8、天气趋势A (20分)
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>天气趋势</title><meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /><link rel="stylesheet" type="text/css" href="css/style.css" /><script src="./js/axios.js"></script><script src="js/vue.min.js" type="text/javascript" charset="utf-8"></script><script src="js/echarts.min.js" type="text/javascript" charset="utf-8"></script>
</head><body><div id="app"><div class="top-bar">2022年 Y 城全年温度统计图</div><!-- 主体 --><div class="container"><!-- 月份 --><div class="month"><ul><!-- TODO:待补充代码 在下面的 li 标签中完成 12个月份 (即 monthList) 的渲染 --><!-- 选择月份的英文名称等于数据中的key,代表这条数据选中 --><li v-for="(item,key,index) in monthList" :class="[monthName===key?'active':'']" @click="changeMonth(key,index)">{{item}}</li></ul></div><div class="chart"><!-- TODO:待补充代码 --><!-- currentMonth 未来七天和本月 tab 切换,只有当前月才显示 --><!-- 选择月份的序号(对应月份-1)等于当前月份的标志(当前月份-1)时显示 --><div id="currentMonth" v-if="monthNumber===nowMonth"><div class="title"><h3>{{typeTitle}}</h3><div class="type" @click="clickType($event)"><span id="seven" :class="{'active':!type}">未来7天</span><span id="current" :class="{'active':type}">本月</span></div></div></div><div id="chart"></div></div></div></div>
</body></html>
<script>// TODO:待补充代码var vm = new Vue({el: "#app",data: {chart: null, // 图表chartOptions: null, // 图表配置项typeTitle: "本月天气",monthList: {January: "1月",February: "2月",March: "3月",April: "4月",May: "5月",June: "6月",July: "7月",August: "8月",September: "9月",October: "10月",November: "11月",December: "12月",},// 请求到的全部数据data: [],// 选择月份的英文名称monthName: 'January',// 选择月份的序号(对应月份-1)monthNumber: 0,// 当前月份的标志(当前月份-1)nowMonth: new Date().getMonth(),// x轴,y轴数据yData: [],xData: [],// 未来7天和本月数据的状态type: 1},mounted: async function() {const res = await axios.get('./js/weather.json');this.data = res.data;// 初始化x轴和y轴数据this.yData = res.data[0]['January'];// 根据y轴温度数据条数的多少判断x轴有多少天this.xData = [...this.yData.map((e, i) => i + 1)];// 初始化 echartsthis.$nextTick(() => {this.initChart();});},methods: {initChart() {// 初始化图表this.chart = echarts.init(document.getElementById("chart"));// 配置项this.chartOptions = {grid: {top: 35,bottom: 5,left: 10,right: 10,containLabel: true,},tooltip: {trigger: "axis",axisPointer: {lineStyle: {color: {type: "linear",x: 0,y: 0,x2: 0,y2: 1,colorStops: [{offset: 0,color: "rgba(255,255,255,0)",}, {offset: 0.5,color: "rgba(255,255,255,1)",}, {offset: 1,color: "rgba(255,255,255,0)",}, ],global: false,},},},},xAxis: [{type: "category",boundaryGap: false,axisLabel: {formatter: "{value}",fontSize: 12,margin: 20,textStyle: {color: "#bfbfbf",},},axisLine: {lineStyle: {color: "#e9e9e9",},},splitLine: {show: true,lineStyle: {color: "#f7f7f7",},},axisTick: {show: false,},// x 轴显示的数据,日期data: this.xData,}, ],yAxis: [{boundaryGap: false,type: "value",axisLabel: {textStyle: {color: "#bfbfbf",},formatter: `{value}\u2103`,},nameTextStyle: {color: "#fff",fontSize: 12,lineHeight: 40,},splitLine: {lineStyle: {color: "#f7f7f7",},},axisLine: {show: true,lineStyle: {color: "#e9e9e9",},},axisTick: {show: false,},}, ],series: [{name: "天气",type: "line",smooth: false,showSymbol: false,symbolSize: 0,zlevel: 3,itemStyle: {color: "#ff6600",borderColor: "#a3c8d8",},lineStyle: {normal: {width: 3,color: "#ff6600",},},areaStyle: {normal: {color: new echarts.graphic.LinearGradient(0,0,0,1, [{offset: 0,color: "#ff6600",}, {offset: 0.8,color: "#ff9900",}, ],false),},},// Y 轴显示的数据,即温度数据data: this.yData,}, ],};// 调用此方法设置 echarts 数据this.chart.setOption(this.chartOptions);},// 切换月份changeMonth(month, index) {this.monthName = month;this.monthNumber = index;this.yData = this.data[index][month];this.xData = [...this.yData.map((e, i) => i + 1)];// 如果切换到了当前月份,将type状态重置以下if (index === this.nowMonth) {this.type = 1}this.initChart()},// 切换未来7天和本月clickType(e) {switch (e.target.id) {case "seven":this.type = 0;// 解构赋值更新x,y坐标轴的数据[this.xData, this.yData] = this.getSevenData();break;case "current":this.type = 1this.yData = this.data[this.monthNumber][this.monthName]this.xData = [...this.yData.map((e, i) => i + 1)]break;}this.initChart();},// 获取未来七天数据getSevenData() {let newXdata = [],newYdata = [];// 利用循环一天一天的获取for (let i = 0; i < 7; i++) {// 当前时间let now = new Date();// now.getTime()为当前时间戳 time为需要获取的那天的时间戳let time = now.getTime() + 1000 * 60 * 60 * 24 * i;// 用setTime转换,将now转换为需要获取的那天的时间// now.setTime(time)既是设置now的日期为:从1970.1.1开始走过time毫秒后的日期now.setTime(time);newXdata.push(`${now.getMonth() + 1}/${now.getDate()}`)if (this.monthNumber === now.getMonth()) {// 如果当前选择的月份与获取那天的时间所处月份一样,则直接取当前y轴里的数据newYdata.push(this.yData[now.getDate() - 1])} else {// 如果当前选择的月份与获取那天的时间所处月份不同,说明进入到了下一月份,取下一月份的数据let nextMonth = this.data[now.getMonth()];// 因为不确定月份数据里的key是啥,不能直接取,所以采用for in遍历对象间接获取数据for (const key in nextMonth) {newYdata.push(nextMonth[key][now.getDate() - 1])}}}return [newXdata, newYdata]}},});
</script>
9、JSON生成器(25 分)
这个我是真的不会。。。
在线求大佬解答
10、商城管理系统(25 分)
// menuList 仅为示例数据,非实际使用数据,实际使用数据层级不确定(可能是四级五级六级等),数据结构与 menuList 一致
// 1. `parentId` 如果为 `-1`,则表示此条数据为顶级数据。
// 2. `parentId` 为该条数据的父级数据的 `id`。let menuList = [{ parentId: -1, name: "添加管理员", id: 10, auth: "admin" },{ parentId: 10, name: "管理员权限分配", id: 11, auth: "admin-auth" },{ parentId: -1, name: "商品管理", id: 1, auth: "product" },// { parentId: 6, name: "赤门网络暗杀速度还等哈说", id: 12, auth: "product" },{ parentId: 1, name: "商品列表", id: 4, auth: "productList" },{ parentId: 4, name: "商品分类", id: 5, auth: "category" },{ parentId: 5, name: "添加分类", id: 8, auth: "addClassification" },{ parentId: 4, name: "商品上架", id: 6, auth: "product" },{ parentId: -1, name: "评论管理", id: 2, auth: "comments" },{ parentId: -1, name: "个人中心", id: 3, auth: "profile" },
];/*** @param {*} menuList 传入的数据* @return {*} menus 转化后的树形结构数据,auths 转化后的权限列表数组*/const getMenuListAndAuth = (menuList) => {// TODO:待补充代码let menus = [],auths = [],// emenus存放那些还未找到上级(未被push的项)emenus = [],// 项是否被落下(是否未被push)isDiscard = true;// 创建一个能够递归查找push的函数function addChildren(fat, chil) {fat.forEach((fatItem) => {if (fatItem.id === chil.parentId) {fatItem.children.push(chil);// 只要项被push了,说明它没有被落下,立即修改isDiscardisDiscard = false;return;} else {// 递归addChildren(fatItem.children, chil);}});}// 遍历原数据menuList.forEach((item) => {// 每一次遍历数据时都提前默认isDiscard为true,因为此时数据还未被pushisDiscard = true;item.children = [];auths.push(item.auth);if (item.parentId === -1) {menus.push(item);isDiscard = false;} else {addChildren(menus, item);// 一次遍历结束了,如果isDiscard还为true,即还未被push// 说明这一项的父级还没有出现,为了防止这一项丢失,将它暂存到emenus中if (isDiscard) {emenus.push(item);}}});// 转换的过程结束了,如果emenus不为空,说明有项被丢弃落下了// 项被落下的原因是:它的父级比它出现的晚,在顺序遍历到它时,因前面没有它的父级,导致它无法被接收if (emenus.length !== 0) {// 这时其它项已经全部加入menus,此时再次将emenus中被落下的项向menus中添加肯定能加上emenus.forEach((item) => {addChildren(menus, item);});}return { menus, auths }; // menus 转化后的树形结构数据,auths 转化后的权限列表数组
};// 请勿删除和修改以下代码
try {module.exports = { getMenuListAndAuth };
} catch (e) {}
总结心得
如果说之前省赛是一场大水,这次国赛就是实实在在的旱田了,不含一点水分(当时考的时候是这样感觉的),还记得当时刚开考看到第一题先要排序,我立马就想到了数组原型上有自带的排序方法,但讽刺的是我忘记了它是哪个,log
打印了Array.prototype
,然后看着哪个像我就试哪一个,但最终一看时间已经过去半小时了,我急了,不得已采用冒泡排序这种笨但很简单的方法
就这样我在想api
上浪费了太多时间,究其原因还是我的基础不够牢固
因为省赛太过水了,考前一直感觉可能国赛也就那样吧,考试的时候我也是不慌不忙,慢慢的做,遇到有好法子能实现但是一时半刻想不起api
的我也不跳过,就一直在那想,可时间就这样拖着拖着就没了,当我真正意识到时间不够了,不能再拖的时候,已经晚了。
哎,现在回过头重新做了一遍题,发现我写最后一题的时间还没有考试时在第一题上浪费的时间一半多,考试时因为最后时间不够,最后一题压根就没看,真是讽刺啊。
感谢这次蓝桥杯的经历,让我真正认识到了自己的不足和努力的方向。
谨以此篇记录我这一段失败的经历
【蓝桥杯Web】2022年第十三届蓝桥杯Web大学组国赛真题解析相关推荐
- 【蓝桥杯Web】2022年第十三届蓝桥杯Web大学组省赛真题解析(精华版)
- 【蓝桥杯Web】2022年第十三届蓝桥杯Web大学组省赛真题解析(完整版)
- 第十一届蓝桥杯python大学组国赛真题
试题 A: 美丽的 2 [问题描述] 小蓝特别喜欢 2,今年是公元 2020 年,他特别高兴. 他很好奇,在公元 1 年到公元 2020 年(包含)中,有多少个年份的数位中包含数字 2? 这道题送分题 ...
- 历届蓝桥杯Scratch编程国赛 初级 中级 青少年编程比赛国赛真题解析【持续更新 已更新至27题】
历届蓝桥杯国赛真题 第十三界.十二届.十一届等历届青少年蓝桥杯Scratch编程比赛国赛真题解析 国赛真题01-河马带球[试看] [蓝桥杯国赛真题01]Scratch河马带球 少儿编程蓝桥杯Scrat ...
- 蓝桥杯到底难不难?(内附第11届省赛+国赛真题解析)
前几天有粉丝留言蓝桥杯的事,刚好猪哥之前也参加过,就想和大家聊聊关于蓝桥杯的那些事! 今天猪哥会讲讲之前自己为什么参加蓝桥杯,拿到的成绩,以及讲解去年的真题,让大家感受一下真实比赛题目难度! 文章目录 ...
- 【蓝桥杯】 《3W字数总结》 蓝桥杯Java必备基础知识以及国赛真题解析
本文会持续更新,如果对您有帮助的话可以点点关注,双击 本人2021年蓝桥杯C++B组国二,今年转战Java,并整理此文,希望能够对大家有所帮助,第一次写这么长的文章,可能有的地方写的不是很好,还请大家 ...
- 【第十二届蓝桥杯国赛真题】2021年第12届蓝桥杯JAVA B组国赛真题
- 【蓝桥杯国赛真题08】python约分 蓝桥杯青少年组python编程 蓝桥杯国赛真题解析
目录 python约分 一.题目要求 1.编程实现 2.评分标准 二.解题思路 1.案例分析
- 2014年蓝桥杯c/c++B组省赛真题解析
一.啤酒和饮料 啤酒每罐2.3元,饮料每罐1.9元.小明买了若干啤酒和饮料,一共花了82.3元. 我们还知道他买的啤酒比饮料的数量少,请你计算他买了几罐啤酒. 注意:答案是一个整数.请通过浏览器提交答 ...
最新文章
- 【非广告,纯干货】这大概是我看过最有温度的面经分享(已收割京东美团技术专家offer)
- 80端口被屏蔽解决方法,80端口穿透之NAT端口映射技术
- mybatis与mysql的优点_MyBatis的优缺点以及特点
- JavaScript Binding
- 每次都需要解释大量指令?使用 PolarDB-X 向量化引擎
- IDEA自动勾选显示类型(specify type)
- 解决genemotion模拟器冲突导致的Android Studio无法启动ADB的问题
- Unity3d import package 无标准资源包
- Google Earth Engine(GEE)——将原始影像进行升尺度计算(以海南省为例)
- Ubuntu网络连接激活失败
- 【Windows Server】由于没有远程桌面授权服务器可以提供许可证
- TextRank算法学习笔记
- desktop window manager
- Rust 图像处理库 image-rs
- 运维体系框架标准化模型简介
- java学习笔记02
- 变分推断中的ELBO(证据下界)
- 利用二维码进行市场推广的十大新玩法
- 怎么用linux获得数据的标题,开源|NLPCC2017(中文)新闻标题分类示例代码以及数据描述...
- x小学计算机知识竞赛方案,竞赛方案精编小学竞赛方案