【蓝桥杯】第十五届省赛大学真题组真题解析
一、智能停车系统
1、知识点
(1)flex-wrap
控制子元素的换行方式
属性值有:
- no-wrap不换行
- wrap伸缩容器不够则自动往下换行
- wrap-reverse伸缩容器不够则自动往上换行
(2)align-content调整多行侧轴对齐方式
align-items
调整单行侧轴对齐方式
控制子元素在交叉轴上的对齐方式
属性值有:
- flex-start侧轴的起始位置对齐
- flex-end侧轴的终止位置对齐
- center侧轴的中间位置对齐
- space-around伸缩项目之间的距离相等是距离边缘间距的2倍
- space-between伸缩项目之间的距离相等,距离边缘间距为0
- space-evenly伸缩项目之间的距离相等是距离边缘间距的1倍
(3)justify-content调整主轴对齐方式
控制子元素在主轴上的对齐方式
属性值有:
- flex-start侧轴的起始位置对齐
- flex-end侧轴的终止位置对齐
- center侧轴的中间位置对齐
- space-around伸缩项目之间的距离相等是距离边缘间距的2倍
- space-between伸缩项目之间的距离相等,距离边缘间距为0
- space-evenly伸缩项目之间的距离相等是距离边缘间距的1倍
2、题解
flex-wrap: wrap;
align-content: space-between;
justify-content: space-between;
二、布局切换
1、知识点
(1)classList
- add添加类
- remove移除类
- toggle切换类:如果元素已有该类名则移除,没有则添加
2、题解
layoutOptions.forEach(function (option) {
// 经典模式,浏览模式,工具模式点击事件
option.addEventListener('click', function () {
// TODO:待补充代码
document.querySelector('.active').classList.remove('active');
option.classList.toggle('active')
// TODO:END
// 以下代码无需修改
// 根据不同选项进行布局处理
if (this === layoutOptions[0]) {
// Classic mode
tool.style.display = "none"; // 隐藏工具
layoutContainer.classList.add('two-column-layout'); // 添加两列布局类
layoutContainer.classList.remove('three-column-layout'); // 移除三列布局类
} else if (this === layoutOptions[1]) {
// Browse mode
tool.style.display = "none"; // 隐藏工具
layoutContainer.classList.add('three-column-layout'); // 添加三列布局类
layoutContainer.classList.remove('two-column-layout'); // 移除两列布局类
} else if (this === layoutOptions[2]) {
// Tool mode
tool.style.display = 'flex'; // 显示工具
}
mode.style.display = 'none'; // 隐藏布局容器
});
});
三、产品360度展示
1、知识点
(1)Promise对象
Promise对象是一个构造函数,用来封装异步操作并且返回成功或者失败的结果
回调函数:函数A作为参数引入函数B,则称函数A为回调函数
可以防止“回调地狱”现象产生
回调地狱:多个异步代码需要按顺序执行产生多层嵌套现象,可读性极差
- 存在一个异步任务
//封装一个异步操作
const p = new Promise((resolve,reject) => {
//调用一下两个参数可相应改变promise状态的值
resolve('获取成功')
//或
reject('获取失败')
})
p.then((data)=>{
//then内部接受一个回调函数(resolve()),回调函数的参数设置为data
console.log(data)
})
.catch((err)=>{
console.log(err)
})
- 存在两个异步任务
//封装一个异步操作
const p = new Promise((resolve,reject) => {
//调用两个参数可改变promise状态的值
resolve('获取成功')
//或
reject('获取失败')
})
p.then((data)=>{
console.log(data)
//分配第二个异步任务的功能,作为p.then的返回值
return p1 = new Promise((resolve,reject) => {
//调用两个参数可改变promise状态的值
resolve('获取成功')
//或
reject('获取失败')
})
})
//用于处理上一个then返回的promise对象
.then((data)=>{
console.log(data)
})
.catch((err)=>{
console.log(err)
})
(2)async、await语法糖
在promise的基础上简化了异步代码的编写。
async可以定义异步函数,使该函数返回一个promise对象。如果异步函数返回一个值则会被promise.resolve包装 如果异步函数返回异常则会被promise.reject包装。
await被用于被async定义的异步函数中,用于等待一个promise对象完成,并返回一个promise值。如果await后面不是一个promise对象,那么他会被转换成一个已解决的promise对象。
function one(){
return 'one'
}
function two(){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('two')
},2000)
})
}
function three(){
return 'three'
}
async function run(){
console.log(one())
console.log(await two())//可以等待two的异步函数执行完再往下继续执行
console.log(three())
}
(3)Promise.resolve方法
可以将一个普通值转换为状态为fulfilled的promise对象
(4)reduce方法
reduce方法是js数组对象中的一个高阶方法,他对数组中的每个元素执行一个自定义的回调函数,并将结果汇总为单个值
语法:数组名.reduce(callback(accumulator,currentValue,currentIndex(可选),array()可选),initialValue(可选))
- 参数
- callback是一个自定义的回调函数,参数可以设置accumulator,currentValue,currentIndex,array
- accumulator:累加器,可保存上一次回调函数的返回值;在第一次调用回调函数时如果设置了initialValue,则accumulator初始值为initialValue,如果没有设置initialValue,则accumulator的初始值为数组中的第一个元素(必选)
- currentValue:当前正在处理的数组元素(必选)
- currentIndex:当前正在处理的数组元素的所以(可选)
- array:调用reduce()方法的数组(可选)
- initialValue:第一次调用callback函数时,accumulator的初始值(可选)
- 返回值
reduce()方法最后一次回调函数的返回值
2、题解
简单的promise链式调用
const pipeline = (initialValue, sequence) => {
// TODO: 待补充代码
return sequence.reduce((promise,currentFn)=>{
return promise.then((result)=>{
return currentFn(result)
})
},Promise.resolve(initialValue))
};
在第一次调用时,promise对象为Promise.resolve(initialValue),其解决值为initialValue。
在后续调用中,promise对象为then方法中返回的新promise对象,其解决值为上一个函数调用后的值。
async await语法糖
const pipeline = async (initialValue, sequence) => {
// TODO: 待补充代码
let result = initialValue
for (const fn of sequence){
result = await fn(result)
}
return result
};
如果await后面不是一个promise对象,那么他会被转换成一个已解决的promise对象。
3、思路
pipeline函数的设计目标是按顺序依次执行sequence数组中的所有函数,并且每个函数的输入是上一函数的输出。
- 通过reduce方法遍历sequence数组,并且将返回值设置为初始值的已解决promise对象形式
在 pipeline 函数中,sequence 数组里的函数既可以是同步函数,也可以是返回 Promise 的异步函数。通过将初始值 initialValue 包装成一个已解决状态的 Promise(使用 Promise.resolve(initialValue)),可以确保后续处理的一致性。
- promise.then会在promise状态变为fulfilled时执行内部的回调函数(第一次循环时,initalValue已经是一个已解决的promise对象所以会立即执行回调函数)
- 在回调函数内部,currentFn(result)会调用当前函数,并传入上一个promise的结果作为参数result。
当currentFn是同步函数时,会立刻执行并且返回一个值,由于then的特性(then方法期望得到一个promise对象),返回的值会被包装成一个已解决的promise对象(Promise.resolve(返回值))。
当currentFn是异步函数时,会等待promise状态由pending转变为resolved,然后返回一个已解决的promise对象。
- 返回的已解决的promise对象会重新传入管道函数的参数promise累加器,进行下一轮的遍历
四、多表单检验
1、知识点
(1)Element-plus
ElementPlus 是一个基于 Vue 3 构建的开源 UI 组件库,它为开发者提供了一系列丰富、高质量且易于使用的组件,能够帮助开发者快速搭建美观、功能强大的 Web 应用程序。
(2)创建表单数据和校验规则
使用reactive来创建表单数据对象,同时定义校验规则。
- 创建表单数据
const form = reactive({
name: '',
sex: '',
age: '',
isCompetition: '',
isEntrepreneurship: '',
footnote: ''
})
- 创建校验规则
通常使用rules对象定义每个表单字段的校验规则,每个规则的字段是一个数组,内部可以包含多个校验规则,常见的规则属性包括:
required
表示该字段是否为必填项message
校验不通过时的错误提示信息trigger
制定验证逻辑的触发方式blur
失去焦点时触发change
值改变时触发
min
和max
用于限制字符串或数组的长度
- 自定义校验规则
如果内置的校验规则无法满足需求时可以使用自定义校验函数,如:
const validatePassword = (rule, value, callback) => {
if (value === "") {
callback(new Error("请输入密码"));
} else if (value !== ruleForm.pass) {
callback(new Error("密码输入不一致"));
} else {
callback();
}
};
在这个示例中,validatePassword 是一个自定义的校验函数,它接收三个参数:rule(当前校验规则)、value(当前字段的值)和 callback(回调函数)。在校验过程中,根据不同的情况调用 callback 函数,若校验通过则直接调用 callback(),若校验不通过则调用 callback(new Error(‘错误信息’)) 抛出错误。
(3)正则表达式检验
test
方法:test 是正则表达式对象的一个方法,它接受一个字符串作为参数,用于检测该字符串是否包含符合正则表达式规则的部分。如果找到匹配项,test 方法返回 true;否则返回 false。
(4)reactive函数
- reactive是Vue3提供的一个函数,他的作用是将一个普通的JavaScript对象转换为一个响应式对象。当对象属性发生变化时,与之相关的视图会自动更新
- reactive函数期望接受一个合法的对象字面量作为参数。对象字面量是由花括号包裹,包含一系列键对值的结构,键是属性名,值可以是各种数据类型。reactive函数内不能声明函数与变量,只能包含对象字面量
2、题解
// TODO:待补充代码
const rules = reactive({
name:[
{validator:validateName = (rule,value,callback) => {
if(value === ''){
callback(new Error('请输入姓名'))
}else if (/[^\u4e00-\u9fa5]/g.test(value)){
callback(new Error('只能输入汉字'))
}else{
callback()
}
},trigger:'blur'}
],
sex:[
{required:true,message:'请选择性别',trigger:'blur'}
],
age:[
{required:true,message:'请输入年龄',trigger:'blur'}
],
isCompetition:[
{required:true,message:'请选择是否参加过编程比赛',trigger:'blur'}
],
isEntrepreneurship:[
{required:true,message:'请选择是否有过创业经历',trigger:'blur'}
]
})
五、找回连接的奇幻之旅
1、知识点
(1)arguments
基本概念:arguments对象包含了函数调用时传入的所有参数,其索引从0开始,可以通过索引来访问每个参数。不过argument并不是真正的数组,他没有数组的方法(如map、filter),但是具备length属性,用于表示传入参数的数量。
虽然arguments并不是真正的数组,但是我们可以通过方法将其转化为真正的数组
- Array.from()方法
- 扩展运算符
...
:可以将多余的参数(传递的参数在函数内部未被使用)收集到一个真正的数组中。
2、题解
function resetableOnce(fn) {
// TODO: 待补充代码
let done = false
let result
function runOnce() {
if(!done){
result = fn(...arguments)
done=!done
}
return result
}
function reset() {
done = false
}
// TODO: END
return { runOnce, reset};
}
六、tree命令助手
1、知识点
(1)map方法
map()
是数组的一个高阶函数,它用于对数组中的每个元素执行一个给定的函数,并返回一个新的数组,新数组中的元素是原数组元素经过函数处理后的结果。
map方法的特点:
- 不改变原数组:map()方法不会改变原始数组,而是返回一个新的数组。
- 按顺序执行:map()方法按照数组元素的顺序依次调用回调函数,并且新数组中的元素顺序与原数组一致。
- 对稀疏数组的处理:map()方法会跳过数组中缺少的元素(即稀疏数组中的空位),不会为这些空位调用回调函数。
2、题解
// 生成文件树
function generateTree(dirPath) {
// TODO:待补充代码
const items = fs.readdirSync(dirPath)
return items.map((item)=>{
console.log('dirPath是:',dirPath);
console.log('item是:',item);
const itemPath =path.join(dirPath,item)
console.log('itemPath是:',itemPath);
if(fs.statSync(itemPath).isDirectory()){
return {
name:item,
children:generateTree(itemPath)
}
}else{
return {
name:item
}
}
})
}
七、Github明星项目统计
1、知识点
(1)filter方法
filter()
方法是数组的一个常用高阶函数,用于创建一个新数组,其中包含通过特定条件筛选出来的原数组中的元素。
filter方法的特点:
- 不改变原数组:filter()方法不会改变原始数组,而是返回一个新的数组,新数组中的元素是根据条件筛选出来的原数组中的部分元素。
- 按顺序执行:filter()方法按照数组元素的顺序依次调用回调函数,并且新数组中的元素顺序与原数组中满足条件的元素顺序一致。
- 对稀疏数组的处理:filter()方法会跳过稀疏数组中的空位,不会为这些空位调用回调函数,也不会将其包含在新数组中。
(2)slice方法
slice()
方法是数组和字符串都具有的方法,用于提取原数组或字符串的一部分,并返回一个新的数组或字符串,而不改变原始数组或字符串。
语法:
array.slice(begin,end)
遵循左闭右开原则
(3)箭头函数
在箭头函数中如果使用花括号包裹函数体则需要return返回,不适用花括号包裹函数体则不需要return返回
(4)Vue.ref()
- ref用于创建一个包含响应式数据的引用对象,当引用对象的值改变时vue会自动追踪值的变化并更新与之绑定的dom元素。
- 访问和修改ref的值需要使用
.value
属性,在 Vue 3 的<script setup>
语法糖中,在模板里使用 ref 对象时可以直接引用,无需添加.value
,Vue 会自动处理。但在 JavaScript 代码里,仍然需要使用.value
来访问和修改值。
2、题解
//任务1
<div>
筛选语言
<!-- TODO: 待补充代码 -->
<select name="language" id="language" @change="changeHandle" v-model="language">
<option v-for='lang in languages' :value="lang">{{lang}}</option>
</select>
</div>
//任务2
// 语言筛选改变时或页面数字输入框数字改变时的处理函数
const changeHandle = () => {
// TODO:待补充代码
let newData = chartData.value.filter((item)=>item.language === language.value)//响应式数据对象需要.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();
};
八、小蓝驿站
1、知识点
(1)push方法
push
方法是 JavaScript 中数组的一个常用方法,用于在数组的末尾添加一个或多个元素,并返回新数组的长度。
2、题解
//任务1
<!-- 联系人列表 -->
<ul class="contacts-list">
<!-- TODO:待补充代码 目标 1 -->
<!-- 以 A 为例 start -->
<li class="contacts-group" v-for='(item,index) in contacts'> <!-- 字母分组渲染 DOM 结构-->
<div class="contacts-group-title">{{item.letter}}</div> <!-- 分组的 字母名称 -->
<ul>
<li class="contact-item" v-for='i in item.contacts'> <!-- contact-item 人名渲染 dom 结构-->
<span class="contact-name">{{i.name}}</span>
<button class="del-contact-button">删除</button>
</li>
</ul>
</li>
</ul>
//任务2
// 定义添加联系人的方法
const addContact = () => {
// TODO:待补充代码 目标 2
let inp = document.querySelector('.add-contact-input')
let inpFirst = inp.value[0].toUpperCase()
let index = contacts.value.map((item)=>item.letter).indexOf(inpFirst)
if(index>=0){
return contacts.value[index].contacts.push({
"name":inp.value
})
}else{
return contacts.value.push({
"letter":inpFirst,
"contacts":[{"name":inp.value}]
})
}
// TODO:END
// 添加完成清空联系人输入框
newContact.value = "";
};