15届蓝桥省赛
发表于:2024-12-10
字数统计:4411 字
预计阅读15分钟
css
.cars {
position: absolute;
z-index: 2;
width: 600px;
height: 600px;
display: flex;
flex-direction: column; /* 排成列*/
/* TODO: 请为下方属性填空,不要更改其他选择器里的代码 */
flex-wrap: wrap;
align-content: space-between;
justify-content: space-between;
}js
// TODO:待补充代码
console.log(option);
layoutOptions.forEach(item => item.classList.remove('active'))
option.classList.add('active')
// TODO:ENDjs
/**
* @param {*} initialValue 初始值
* @param {Array} sequence 由普通函数或 Promise 函数组成的数组
* @return {Promise}
*/
const pipeline = (initialValue, sequence) => {
// TODO: 待补充代码
return sequence.reduce((acc, fn) => acc.then(fn), Promise.resolve(initialValue));
};js
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>多表单验证</title>
<link rel="stylesheet" href="./css/style.css">
<link rel="stylesheet" href="./css/element-plus.css">
<script src="./lib/vue.global.prod.js"></script>
<script src="./lib/index.full.js"></script>
</head>
<body>
<div id="app">
<div id="func">{{ submitForm }}</div>
<el-tabs type="border-card" v-model="activeName">
<el-tab-pane label="基本信息" name="user">
<el-form id="form1" label-width="120px" v-model:model="form" ref="form1Ref" :rules="rules">
<el-form-item label="姓名:" prop="name">
<el-input v-model="form.name" id="input1" />
</el-form-item>
<el-form-item label="性别:" prop="sex">
<el-radio-group v-model="form.sex" class="ml-4">
<el-radio label="男" size="large" @click.prevent.native="onClickRadio('sex','男')">男</el-radio>
<el-radio label="女" size="large" @click.prevent.native="onClickRadio('sex','女')">女</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="年龄:" prop="age">
<el-input v-model="form.age" id="input3" />
</el-form-item>
</el-form>
</el-tab-pane>
<el-tab-pane label="附加信息" name="place">
<el-form id="form2" label-width="200px" v-model:model="form" ref="form2Ref" :rules="rules">
<el-form-item label="是否参加过编程比赛:" prop="isCompetition">
<el-radio-group v-model="form.isCompetition" class="ml-4" id="input4">
<el-radio label="1" size="large" @click.prevent.native="onClickRadio('isCompetition','1')">是</el-radio>
<el-radio label="0" size="large" @click.prevent.native="onClickRadio('isCompetition','0')">否</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="是否有过创业经历:" prop="isEntrepreneurship">
<el-radio-group v-model="form.isEntrepreneurship" class="ml-4" id="input5">
<el-radio label="1" size="large"
@click.prevent.native="onClickRadio('isEntrepreneurship','1')">是</el-radio>
<el-radio label="0" size="large"
@click.prevent.native="onClickRadio('isEntrepreneurship','0')">否</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="补充说明:" prop="footnote">
<el-input type="textarea" style="width: 200px;" v-model="form.footnote" />
</el-form-item>
</el-form>
</el-tab-pane>
</el-tabs>
<el-row>
<el-button id="submit" type="primary" size="large" class="btn-submit" @click="submitForm">提交</el-button>
</el-row>
</div>
<script>
const { createApp, reactive, toRefs, ref, onMounted } = Vue;
const { ElMessage } = ElementPlus
const app = Vue.createApp({
setup() {
const activeName = ref('user')
const onClickRadio = (key, val) => {
form[key] = form[key] == val ? '' : val
}
const form = reactive({
name: '',
sex: '',
age: '',
isCompetition: '',
isEntrepreneurship: '',
footnote: ''
})
// TODO:待补充代码
const validateName = (rule, value, callback) => {
let testValue = value.replace(/[^\u4e00-\u9fa5]/g, '')
console.log(value);
if(testValue !== value) {
callback(new Error("只能输⼊汉字"));
}
else {
callback()
}
}
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'
}
]
})
const form1Ref = ref(null)
const form2Ref = ref(null)
var msg
const submitForm = async () => {
msg && msg.close()
let res1 = await form1Ref.value.validate();
let res2 = await form2Ref.value.validate()
// console.log(res1, res2);
if (res1 && res2) {
msg = ElMessage({
message: "提交成功",
type: "success",
});
}
}
return {
activeName,
form,
rules,
form1Ref,
form2Ref,
submitForm,
onClickRadio
}
}
});
app.use(ElementPlus).mount('#app');
</script>
</body>
</html>js
/**
* 定义一个可重置的一次性函数
* @param {func} fn 要作用的函数
* @returns {object} {runOnce:func, reset:func }
*/
let flag = false
let result = ''
let prevFunName = ''
function resetableOnce(fn) {
// TODO: 待补充代码
if (fn !== prevFunName) {
flag = false
}
function runOnce(...args) {
if (!flag) {
flag = true
result = fn(...args)
return result
} else {
return result
}
}
function reset() {
flag = false
result = ''
return
}
// TODO: END
return { runOnce, reset};
}js
const fs = require('fs');
const path = require('path');
// 生成文件树
function generateTree(dirPath) {
// TODO:待补充代码
if (!dirPath) {
return []
}
if (!isDir(dirPath)) {
return []
}
// is Dir
let result = []
const fileInDir = fs.readdirSync(dirPath)
// console.log(fileInDir);
// console.log(fs.readdirSync(path.resolve(dirPath, fileInDir[1])));
fileInDir.forEach((item, index) => {
// dfs loading
// not a dir
result.push(dfs(item, dirPath))
})
return result
}
function dfs(fileName, dirPath) {
if (!isDir(path.resolve(dirPath, fileName))) {
return { name: fileName }
} else {
// dfs
// dirPath + fileName is Dir, need a itearate
const childPath = path.resolve(dirPath, fileName)
const fileInDir = fs.readdirSync(childPath)
let result = {}
fileInDir.forEach((item, index) => {
result.name = fileName
result.children ? result.children.push(dfs(item, childPath)) : result.children = [dfs(item, childPath)]
})
console.log(result);
return result
}
}
function isDir(dirPath) {
return fs.statSync(dirPath).isDirectory()
}
// 根据数据生成 tree 命令
function generateDirectoryStructure(data, indent = "") {
let result = "";
if(!Array.isArray(data)) throw Error('返回的数据不是数组');
for (let i = 0; i < data.length; i++) {
const item = data[i];
const name = item.name;
const isLast = i === data.length - 1;
result += `${indent}${isLast ? "└──" : "├──"} ${name}\n`;
if (item.children) {
const childIndent = indent + (isLast ? " " : "│ ");
result += generateDirectoryStructure(item.children, childIndent);
}
}
return result;
}
// 读取指定文件夹,传递本题目文件夹
const directoryPath = __dirname;
const tree = generateTree(directoryPath);
const treem= generateDirectoryStructure(tree);
console.log(treem)
// 以下代码检测需要,请勿删除
module.exports = generateTree;js
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Github 明星项目统计</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="./lib/axios.js"></script>
<script src="lib/vue.global.js"></script>
<script src="lib/echarts.min.js"></script>
</head>
<body>
<div id="app">
<!-- 图表容器 -->
<div id="chart" style="width: 100%; height: 500px;"></div>
<div class="filters">
<div>
筛选语言
<!-- TODO: 待补充代码 -->
<select name="language" id="language" @change="changeHandle" v-model="language">
<!-- <option value="All">All</option> -->
<option :value="item" v-for="item in languages">{{ item }}</option>
</select>
</div>
<div>展示第<input id="first" type="text" v-model="pageStart" @input="changeHandle">到第<input id="second" type="text"
v-model="pageEnd" @input="changeHandle">位的项目</div>
</div>
</div>
</body>
<script>
var xData;
var yData;
const app = Vue.createApp({
setup() {
// 定义响应式数据
const chart = Vue.ref(null);
const chartOptions = Vue.ref(null);
const chartData = Vue.ref(null);
xData = Vue.ref(null);
yData = Vue.ref(null);
const languages = Vue.ref(['All', 'JavaScript', 'TypeScript', 'Python', 'Shell', 'C++', 'C#', 'Go', 'Rust', 'Java']);
const language = Vue.ref('All');
const pageStart = Vue.ref(1);
const pageEnd = Vue.ref(100);
// 语言筛选改变时或页面数字输入框数字改变时的处理函数
const changeHandle = () => {
// TODO:待补充代码
if (language.value === 'All') {
console.log('1');
}
else {
// JavaScript
console.log(language.value);
console.log(chartData.value);
const temXData = []
const temYData = []
chartData.value.filter(item => {
if (item.language === language.value) {
console.log(item.name);
temXData.push(item.name)
}
})
xData.value = temXData.slice(pageStart.value - 1, pageEnd.value)
chartData.value.filter(item => {
if (item.language === language.value) {
temYData.push(item.stars)
}
})
yData.value = temYData.slice(pageStart.value - 1, pageEnd.value)
}
console.log(xData.value);
console.log(yData.value);
initChart();
};
// 初始化图表
const initChart = () => {
chart.value = echarts.init(document.getElementById('chart'));
chartOptions.value = {
title: {
text: 'Github 明星项目统计',
x: 'center'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
label: {
show: true
}
}
},
xAxis: {
data: xData.value,
},
yAxis: {
type: 'value',
label: 'star数量'
},
series: [
{
data: yData.value,
type: 'bar',
}
],
};
chart.value.setOption(chartOptions.value);
};
// 组件挂载时获取数据
Vue.onMounted(() => {
axios.get('./js/data.json').then(res => {
chartData.value = res.data;
let newData = chartData.value.slice(pageStart.value - 1, pageEnd.value);
xData.value = chartData.value.map(item => item.name);
yData.value = chartData.value.map(item => item.stars);
console.log(xData.value);
initChart();
});
});
return {
chart,
chartOptions,
chartData,
xData,
yData,
languages,
language,
pageStart,
pageEnd,
initChart,
changeHandle,
};
},
});
var vm = app.mount('#app');
</script>
</html>js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>小蓝驿站</title>
<!-- 链接外部样式表 -->
<link rel="stylesheet" href="css/style.css" />
<!-- 引入 Vue.js 框架 -->
<script src="lib/vue.global.js"></script>
</head>
<body>
<div id="app">
<!-- 邮箱顶部标题和操作按钮 -->
<div class="email-header">
<!-- 邮箱标题 -->
<div class="email-header-logo">
<h1 class="email-header-title">小蓝驿站</h1>
</div>
<!-- 邮箱操作按钮,包括撰写邮件、设置和退出 -->
<div class="email-header-actions">
<button class="email-header-button">撰写邮件</button>
<button class="email-header-button">设置</button>
<button class="email-header-button">退出</button>
</div>
</div>
<div class="container">
<!-- 邮箱侧边栏 -->
<div class="email-sidebar">
<!-- 邮箱文件夹列表 -->
<ul class="folder-list">
<li class="folder-list-item">收件箱</li>
<li class="folder-list-item">草稿箱</li>
<li class="folder-list-item">已发送</li>
<li class="folder-list-item">已删除</li>
<li class="folder-list-item">垃圾邮件</li>
<li class="folder-list-item">广告邮件</li>
</ul>
</div>
<div>
<!-- 通讯录标题 -->
<div class="contacts-title">通讯录</div>
<!-- 添加联系人区块 -->
<div class="add-contacts">
<!-- 添加联系人标题 -->
<div class="contacts-group-title">添加联系人</div>
<!-- 添加联系人表单 -->
<div class="add-contact">
<!-- 联系人输入框,使用 Vue 的 v-model 进行双向数据绑定 -->
<input
class="add-contact-input"
v-model="newContact"
placeholder="新联系人名字"
/>
<!-- 添加按钮,点击后触发 addContact 方法 -->
<button class="add-contact-button" @click="addContact">
添加
</button>
</div>
</div>
<!-- 联系人列表 -->
<ul class="contacts-list">
<!-- TODO:待补充代码 目标 1 -->
<!-- 以 A 为例 start -->
<li class="contacts-group" v-for="item in sortedContacts" :key="item">
<!-- 字⺟分组渲染 DOM 结构-->
<div class="contacts-group-title">{{ item.letter }}</div>
<!-- 分组的 字⺟名称 -->
<ul>
<li class="contact-item" v-for="child in item.contacts" :key="child">
<!-- contact-item ⼈名渲染 dom 结构-->
<span class="contact-name">{{ child.name }}</span>
<button class="del-contact-button">删除</button>
</li>
</ul>
</li>
<!-- 以 A 为例 end -->
</ul>
</div>
</div>
</div>
<script>
// 从 Vue 对象中解构出 reactive、computed 和 ref 等方法
const { reactive, computed, ref, onMounted } = Vue;
// 定义 Vue 应用
const app = {
setup() {
// 定义并初始化联系人列表
let list = ref([]);
onMounted(async () => {
const res = await fetch("./data.json")
.then((res) => res.json())
.then((data) => data);
list.value = res;
});
// 定义并初始化新联系人名字
const newContact = ref("");
// 定义计算属性,对联系人列表进行排序
const sortedContacts = computed(() => {
return list.value.sort((a, b) => a.letter.localeCompare(b.letter));
});
// 定义添加联系人的方法
const addContact = () => {
// TODO:待补充代码 目标 2
console.log(sortedContacts.value);
console.log(newContact.value[0].toUpperCase());
console.log(sortedContacts.value.map(item => item.letter));
let firstWord = newContact.value[0].toUpperCase()
let position = sortedContacts.value.map(item => item.letter).indexOf(firstWord)
if (position !== -1) {
// 有,新增
console.log('yes');
sortedContacts.value[position].contacts.push({
name: newContact.value,
})
// sort一下
// sortedContacts.value[position].contacts.sort((a,b) => {
// console.log(a.name);
// console.log(b.name);
// a.name.localeCompare(b.name)
// })
} else {
// 没有,创建并新增
console.log('no');
sortedContacts.value.push({
letter: firstWord,
contacts: [
{
name: newContact.value
}
]
})
}
// TODO:END
// 添加完成清空联系人输入框
newContact.value = "";
};
// 返回应用所需的数据和方法
return {
list,
newContact,
sortedContacts,
addContact,
};
},
};
// 创建并挂载 Vue 应用
Vue.createApp(app).mount("#app");
</script>
</body>
</html>js
window.onload = async ()=> {
const MockUrl =`./js/data.json`;// 请求地址
let data=[];// 存储请求后的数据
// TODO:待补充代码,目标 1
const response = await axios.get(MockUrl)
data = response.data
console.log(data);
// TODO:END
// 请求完成后调用下面的代码
const newData = getData(data);
showData(newData);
};
/**
* 将同一天浏览的相同商品去重并作为数组返回
* @param {Array} defaultData json 文件中读取到的原始数据
* @returns 去重后的数据,数据结构与 defaultData 相同
*/
const removeDuplicates = defaultData => {
let newData = [];
// TODO:待补充代码,目标 2
const hashMap = {}
for(let item of defaultData) {
// 压根没出现
if (!hashMap[item.id]) {
hashMap[item.id] = item.viewed_on
newData.push(item)
} else {
// 出现过,判断是不是同一天,如果是同一天就不加进去
if (hashMap[item.id].slice(0,10) !== item.viewed_on.slice(0, 10)) {
newData.push(item)
}
}
}
console.log(newData);
return newData;
}
/**
* 将去重后的数据根据字段 viewed_on(格式化为 YYYY-MM-DD) 降序排序
* @param {*} defaultData 去重后的数据
* @returns 根据字段 viewed_on(格式化为 YYYY-MM-DD) 降序排序
*/
const sortByDate = defaultData => {
let newData = [];
// TODO:待补充代码,目标 3
const temDate = defaultData.map(item => item.viewed_on)
defaultData.forEach(item => {
item.viewed_on1 = item.viewed_on.replace(/^(\d\d\d\d)-(\d\d)-(\d\d)T.*$/, `$1$2$3`)
})
// sort
defaultData.sort((a, b) => {
console.log('2024-03-23' - '2024-03-22');
return parseInt(b.viewed_on1) - parseInt(a.viewed_on1)
})
defaultData.forEach(item => {
delete item.viewed_on1
})
console.log(defaultData);
newData = defaultData
return newData;
}
/**
* 将去重排序后的所有商品数据,作为一个对象存储并返回
* @param {Array} defaultData 重后的所有商品数据
* @returns
*/
const transformStructure = defaultData => {
let newData = {};
// TODO:待补充代码,目标 4
console.log(defaultData);
defaultData.forEach(item => {
const forMat = item.viewed_on.slice(0, 10)
console.log(forMat);
if (!newData[forMat]) {
newData[forMat] = []
newData[forMat].push(item)
} else {
newData[forMat].push(item)
}
})
console.log(newData);
return newData;
}
const getData = (defaultData) => {
let newData = removeDuplicates(defaultData);
let sortData = sortByDate(newData);
let objData = transformStructure(sortData);
return objData;
};
const showData = (data) => {
let str = ``;
for (let k in data) {
str += `<h3>${k}</h3>`;
data[k].forEach((goods) => {
str += `<div class="container">
<div class="image"></div>
<div class="details">
<h4>${goods.name}</h4>
<p>${goods.description}</p>
<p class="buy">
<span class="price">¥${goods.price}</span>
<img src="./images/cart.svg" alt="" srcset="">
</p>
</div>
</div>`;
});
}
document.querySelector("#goodsList").innerHTML = str;
};js
/**
* @param {iterable} iterable 可迭代对象
* @return {promise}
*/
function myRace(iterable) {
// TODO:待补充代码
return new Promise((resolve, reject) => {
// not a iterable
if (iterable == null || typeof iterable[Symbol.iterator] !== 'function') {
reject(new TypeError(`${typeof iterable} is not iterable`));
return;
} else {
// is a iterable
for (const item of iterable) {
Promise.resolve(item).then(resolve, reject);
}
}
})
}
// 测试⽤例 1
myRace([1,2]) //返回 Promise {<fulfilled>: 1}
// 测试⽤例 2
myRace('hello') // 返回 Promise {<fulfilled>: 'h'}
// 测试⽤例 3
let promise1 = new Promise((resolve, reject)=> {
reject(1)
})
let promise2 = new Promise((resolve, reject) =>{
setTimeout(()=>{
resolve(2)
},1000)
})
myRace([promise1, promise2]).then(res => {
console.log(res)
},reason=>{
console.log(reason) // 输出 1
})
// // 1 执⾏代码
// myRace(1)
// // 控制台报错输出
// // Uncaught (in promise) TypeError: number is not iterable
// 以下代码不需要修改
const random = Math.random();
const output = document.getElementById("output"); // 下载输出
const startButton = document.getElementById("startButton"); // 下载按钮
let isDownloading = false; //是否已经开始下载
// 定义不同下载源的下载任务,链接仅为函数模拟使用,不存在联网情况
const downloadTasks = [
()=> executeTask("quick", "https://quick.lanqiao.com/"),
()=>executeTask("learn", "https://learn.lanqiaoshiyan.com/"),
()=> executeTask("study", "https:/study.lanqiao.com/"),
];
// 下载进度
function simulateDownload(source, httpLink, result) {
output.textContent = `The current download source ${source},npm http fetch GET 200 ${httpLink}/\n`;
output.textContent += "Downloading packages...\n";
setTimeout(() => {
output.textContent += "Fetching package 1/5...\n";
});
setTimeout(() => {
output.textContent += "Fetching package 2/5...\n";
}, 500);
setTimeout(() => {
output.textContent += "Fetching package 3/5...\n";
}, 1000);
setTimeout(() => {
output.textContent += "Fetching package 4/5...\n";
},1500);
setTimeout(() => {
if (result == "complete") {
output.textContent += "Fetching package 5/5...\n";
output.textContent += `Download ${result}!\n`;
} else {
output.textContent += "Fetching package 4/5...\n";
output.textContent += `Download ${result}!\n`;
}
}, 2000);
}
// 点击开始匹配最快的下载源进行下载,并拿到下载成功失败的结果
startButton.addEventListener("click", () => {
startButton.style.display = 'none';
myRace(downloadTasks).then(
({ source, httpLink }) => {
isDownloading = true;
simulateDownload(source, httpLink, "complete");
},
({ source, httpLink }) => {
isDownloading = true;
simulateDownload(source, httpLink, "fail");
}
);
});
// 匹配最快的下载源进行下载
function executeTask(source, httpLink) {
return new Promise((resolve, reject) => {
//executionTime 定义不同下载源的下载速度
const executionTime = Math.random() * 300 ;
// 设置需要下载的进度 100%
let downloadPercentage = 100;
const decreaseAmount = 100 / executionTime;
if (random < 0.5) {
setTimeout(() => {
reject({ source, httpLink }); //下载失败
}, executionTime);
}
interval = setInterval(() => {
if (isDownloading) return clearInterval(interval);
downloadPercentage -= decreaseAmount;
if (downloadPercentage <= 0) {
clearInterval(interval);
resolve({ source, httpLink }) //下载成功
}
}, 10);
});
}