去年报了个蓝桥杯Web,昨天刚打完省赛,10道题基本无压力 (果然是圈钱杯),最后一道可能会扣点分,整理一下赛后直播的答案,也包括职业院校组的,给需要的小伙伴们:
1. 智能停车系统 ⭐️
考点: flex 布局
解题答案:
.cars {
position: absolute;
z-index: 2;
display: flex;
width: 600px;
height: 600px;
flex-direction: column;
/* TODO: 请在下方编写题目代码,不要更改其他选择器里的代码 */
flex-wrap: wrap;
align-content:space-between;
justify-content:space-between;
}
2. 分享点滴 ⭐️
考察:对象的遍历,字符串基本操作
答案1:
function appendParamsToURL(url, params) {
// 创建一个空字符串来存储参数字符串
let str = "";
// 遍历参数对象中的每个键
for (const key in params) {
// 将键值对追加到字符串中
str += `${key}=${params[key]}&`;
}
// 移除字符串末尾的 "&" 符号
str = str.slice(0, -1);
// 判断是否原始 URL 已包含查询字符串(通过是否包含 "?" 符号来判断)
// 如果已包含查询字符串,则设置 sym 变量为 "&",用于以 "&" 作为分隔符追加参数
// 否则,设置 sym 变量为 "?",作为查询字符串的起始符号
let sym = url.includes("?") ? "&" : "?";
// 连接原始 URL、sym 符号和参数字符串,并返回最终的 URL
return `${url}${sym}${str}`;
}
答案2:
function appendParamsToURL(url, params) {
// 使用 Object.entries() 获取参数对象的所有键值对并按照规则拼接
const paramArray = Object.entries(params).map(
([key, value]) => `${key}=${value}`
);
// 使用join方法拼接参数字符串
const paramString = paramArray.join("&");
// 判断URL中是否已包含参数
let sym = url.includes("?") ? "&" : "?";
// 返回拼接后的URL
return `${url}${sym}${paramString}`;
}
3. 布局切换 ⭐️
考察 DOM 操作、class 类名操作
option.addEventListener('click', function () {
for (const otherOption of layoutOptions) {
// 移除其他选项的 active 类
otherOption.classList.remove('active');
}
// TODO:待补充代码
this.classList.add('active'); // 为当前选项添加active类
}
4. 产品 360 度展示 ⭐️⭐️
考察:Promise、循环
答案1:
const pipeline = async (initialValue, sequence) => {
let res = initialValue;
for (const fn of sequence) {
res = await fn(res);
}
return res;
};
答案2:
const pipeline = (initialValue, sequence) => {
let res = Promise.resolve(initialValue);
for (const fn of sequence) {
res = res.then((result) => fn(result));
}
return res;
};
5. 多表单验证 ⭐️
考察element-plus组件的使用
const validateName = (rule, value, callback) => {
if (value === "") {
callback(new Error("请输入姓名"));
} else {
const reg = /[^\u4e00-\u9fa5]/g;
if (reg.test(value)) {
callback(new Error("只能输入汉字"));
}
callback();
}
};
// TODO-3:书写表单校验规则,并绑定到对应表单上
const rules = reactive({
name: [
{ required: true, message: "请输入姓名", trigger: "blur" },
{ validator: validateName, trigger: "blur" },
],
sex: [{ required: true, message: "请选择性别", trigger: "change" }],
age: [{ required: true, message: "请输入年龄", trigger: "blur" }],
isCompetition: [
{ required: true, message: "请选择是否参加过编程比赛", trigger: "change" },
],
isEntrepreneurship: [
{ required: true, message: "请选择是否有过创业经历", trigger: "change" },
],
});
6. 找回连接的奇幻之旅 ⭐️⭐️⭐️
考察:函数封装、闭包
function resetableOnce(fn) {
let done = false; // 标记函数是否已执行
let result; // 保存函数执行的结果
/**
* 保证只执行一次的函数
* @returns {Any} 返回函数fn的执行结果
*/
function runOnce() {
if (!done) {
// 如果之前没有执行过,则执行函数fn,并保存结果
result = fn.apply(this, arguments);
done = true; // 标记为已完成,确保之后不再执行
}
// 返回之前执行的结果
return result;
}
/**
* 重置函数的执行状态
*/
function reset() {
done = false; // 重置done为false,允许函数再次执行
}
// 返回控制对象
return { runOnce, reset };
}
7. 悠然画境 ⭐️⭐️
考察数组操作、字符串操作
function generateAndDisplayImages(imageCount, selectedText) {
// TODO:待补充代码 根据数量和用户输入在页面上生成图片并显示到 .right-panel 元素中
let count = 0;
artDataArray.forEach((el) => {
let tags = el.tags.split("、");
tags.forEach((tag) => {
if (selectedText.includes(tag)) {
count++;
}
});
el["count"] = count;
count = 0;
});
artDataArray.sort((a, b) => {
return b.count - a.count; // 从小到大 -> a.age - b.age
});
let b = artDataArray.slice(0, imageCount);
return b;
}
8. 简易 JSX 解析器 ⭐️⭐️
考察 dom 操作、字符串方法
/**
* 将驼峰式命名转换为短横线命名
* @param {string} str - 驼峰式命名的字符串
* @returns {string} - 转换后的短横线命名字符串
*/
function camelToDash(str) {
let result = "";
let hasUppercase = false; // 标记字符串中是否包含大写字母
for (let i = 0; i < str.length; i++) {
let char = str.charAt(i);
// 检查当前字符是否为大写字母
if (char === char.toUpperCase()) {
hasUppercase = true;
if (i > 0) {
result += "-"; // 在大写字母前添加短横线
}
result += char.toLowerCase(); // 将大写字母转换为小写字母并添加到结果中
} else {
result += char; // 如果不是大写字母,直接添加到结果中
}
}
// 如果字符串中没有大写字母,则直接返回原字符串
if (!hasUppercase) {
return str;
}
return result;
}
const jsx = (type, config) => {
/* TODO: 请完善 jsx 函数的代码实现 */
const dom = document.createElement(type);
for (let key in config) {
const prop = config[key];
if (key === "style") {
// 处理样式
let styleStr = Object.entries(prop)
.map((item) => {
return `${camelToDash(item[0])}:${item[1]}`;
})
.join(";");
dom.setAttribute("style", styleStr);
} else if (typeof prop === "function") {
dom[key] = prop;
} else if (key === "children") {
// 处理 children
if (typeof prop === "string") {
dom.appendChild(document.createTextNode(prop));
} else {
prop.forEach((child) =>
typeof child === "string"
? dom.appendChild(document.createTextNode(child))
: dom.appendChild(child)
);
}
} else {
// 处理其他属性
dom.setAttribute(key, prop);
}
}
return dom;
};
9. tree 命令助手 ⭐️⭐️⭐️
考察 fs
、递归函数
function generateTree(dirPath) {
// 读取目录下的所有文件和文件夹
const files = fs.readdirSync(dirPath);
const tree = [];
files.forEach(file => {
const filePath = path.join(dirPath, file);
const isDirectory = fs.statSync(filePath).isDirectory();
if (isDirectory) {
// 如果是目录,则递归生成子目录的文件树
const subtree = generateTree(filePath);
tree.push({ name: file, children: subtree });
} else {
// 如果是文件,则直接添加到文件树
tree.push({ name: file });
}
});
return tree;
}
10. Github 明星项目统计 ⭐️⭐️⭐️
考察 vue3 v-for
、Echarts
数据处理
<select name="language" id="language" @change="changeHandle" v-model="language">
<option v-for="language in languages" :value="language">{{language}}</option>
</select>
<script>
setup() {
const changeHandle = () => {
let newData = chartData.value.filter(item => item.language === language.value);
if (language.value === 'All') {
newData = chartData.value;
}
newData = newData.slice(pageStart.value - 1, pageEnd.value);
xData.value = newData.map(item => item.name);
yData.value = newData.map(item => item.stars);
initChart();
};
}
</script>
11. 小蓝驿站 ⭐️⭐️⭐️
考察 vue3 v-for
、ref
、数据处理
// 目标 1
<ul class="contacts-list">
<!-- 使用 Vue 的 v-for 指令循环渲染 sortedContacts 中的每个联系人组 -->
<li
class="contacts-group"
v-for="(group, groupIndex) in sortedContacts"
:key="groupIndex"
>
<!-- 如果联系人组中有联系人,则显示该组的标题 -->
<div v-if="group.contacts.length > 0" class="contacts-group-title">
{{ group.letter }}
</div>
<!-- 使用 v-for 指令循环渲染每个联系人 -->
<ul>
<li
class="contact-item"
v-for="(contact, contactIndex) in group.contacts"
:key="contactIndex"
>
<!-- 显示联系人名字 -->
<span class="contact-name">{{ contact.name }}</span>
<button class="del-contact-button">删除</button>
</li>
</ul>
</li>
</ul>
<script>
setup() {
// 目标 2
const addContact = () => {
// TODO:待补充代码 目标 2
if (newContact.value.trim() !== "") {
// 获取新联系人名字的首字母并转为大写
const firstLetter = newContact.value[0].toUpperCase();
// 查找是否有相同首字母的联系人组
const groupIndex = contacts.value.findIndex(
(group) => group.letter === firstLetter
);
if (groupIndex > -1) {
// 如果找到了相同首字母的联系人组,就添加到该组
contacts.value[groupIndex].contacts.push({ name: newContact.value });
} else {
// 如果没有找到相同首字母的联系人组,就新建一个组,并添加到联系人列表
const newGroup = {
letter: firstLetter,
contacts: [{ name: newContact.value }],
};
contacts.value.push(newGroup);
}
}
// TODO:END
// 添加完成清空联系人输入框
newContact.value = "";
};
}
</script>
12. 商品浏览足迹 ⭐️⭐️⭐️
考察 axios
请求、数据处理
window.onload = async ()=> {
const res = await axios("./js/data.json");
const newData = getData(res.data);
showData(newData);
};
/**
* 将同一天浏览的相同商品去重并作为数组返回
* @param {Array} defaultData json 文件中读取到的原始数据
* @returns 去重后的数据,数据结构与 defaultData 相同
*/
const removeDuplicates = defaultData => {
let newData = [];
// TODO:在下面补充代码,最终完成该函数封装
defaultData.forEach((defaultGoods) => {
const defaultDate = new Date(defaultGoods.viewed_on);
const dD = `${defaultDate.getFullYear()}-${
defaultDate.getMonth() + 1
}-${defaultDate.getDate()}`;
defaultGoods.date = dD;
let hadThisGoods = false;
newData.forEach((tmpGoods) => {
const tmpDate = new Date(tmpGoods.viewed_on);
const tD = `${tmpDate.getFullYear()}-${
tmpDate.getMonth() + 1
}-${tmpDate.getDate()}`;
if (tmpGoods.id == defaultGoods.id && tD == dD) {
hadThisGoods = true;
}
});
if (!hadThisGoods) {
newData.push(defaultGoods);
}
});
return newData;
}
/**
* 将去重后的数据根据字段 viewed_on(格式化为 YYYY-MM-DD) 降序排序
* @param {*} defaultData 去重后的数据
* @returns 根据字段 viewed_on(格式化为 YYYY-MM-DD) 降序排序
*/
const sortByDate = defaultData => {
let newData = [];
// TODO:在下面补充代码,最终完成该函数封装
function sortByProperty(property, asc) {
return function (value1, value2) {
let a = new Date(value1[property]);
let b = new Date(value2[property]);
// 默认升序
if (asc == undefined) {
return a - b;
} else {
return asc ? a - b : b - a;
}
};
}
newData = defaultData.sort(sortByProperty("date", false));
return newData;
}
/**
* 将去重排序后的所有商品数据,作为一个对象存储并返回,
* 该对象的所有 `key` 为浏览商品的当天日期(即,字段 viewed_on 格式化为 YYYY-MM-DD),
* `value` 为当天浏览的所有商品(以数组形式表现)。
* @param {Array} defaultData 重后的所有商品数据
* @returns
*/
const transformStructure = defaultData => {
let newData = {};
// TODO:在下面补充代码,最终完成该函数封装
// 月份和日期 不足10的前面补0
defaultData.forEach(item=>{
let date=new Date(item.date) ;
let y = date.getFullYear()
let m = date.getMonth()+1
m=m<10?'0'+m:m
let d = date.getDate();
d=d<10?'0'+d:d
item.date=`${y}-${m}-${d}`;
})
newData = defaultData.reduce((aD, item) => {
console.log(item);
if (!aD[item.date]) {
aD[item.date] = [];
aD[item.date].push(item);
} else {
if (!aD[item.date].includes(item.date)) {
aD[item.date].push(item);
}
}
return aD;
}, {});
return newData;
}
13. 扫雷游戏 ⭐️⭐️⭐️⭐️
考察二维数组操作、递归
function mineSweeperAlgorithms(arr, { row, col }) {
if (flagData[row][col]) return;
flagData[row][col] = true;
const { positionWithoutMineArr, count } = getAroundAndCount(arr, {
row,
col,
});
if (count == 0) {
// 如果当前格子周围没有地雷,递归执行扫雷算法
positionWithoutMineArr.forEach((around) => {
mineSweeperAlgorithms(arr, around);
});
}
}
14.NPM Download Simulator ⭐️⭐️⭐️⭐️
考察:获取数据类型、 promise.race
function myRace(iterable) {
return new Promise((resolve, reject) => {
if (!(Symbol.iterator in Object(iterable))) {
reject(
new TypeError(
`${Object.prototype.toString
.call({ iterable })
.slice(-8, -1)
.toLocaleLowerCase()} is not iterable`
)
);
return;
}
const promises = Array.from(iterable);
let resolvedOrRejected = false;
for (const promise of promises) {
Promise.resolve(promise).then(
(value) => {
if (!resolvedOrRejected) {
resolvedOrRejected = true;
resolve(value);
}
},
(reason) => {
if (!resolvedOrRejected) {
resolvedOrRejected = true;
reject(reason);
}
}
);
}
});
}
当然,web只要最终实现的效果和题目中描述的一致,那就能得分,上面答案只是参考。总体感觉难度不大,希望能进一波国赛吧
java省三嘿嘿
你好我想转载到我的博客供学习,可以吗,会标明出处
当然可以
虽然看不懂,但也无法阻挡赵总牛逼。
我居然一题都不会