2024第十五届蓝桥杯第二次模拟赛web组题解

1 相不相等

1
2
3
4
5
6
7
8
9
10
11
12
13
var expectFn = function(val) {
// TODO
return {
toBe(val2){
if(val2===val) return true
return 'Not Equal'
},
notToBe(val2){
if(val2!==val) return true
return 'Equal'
}
}
};

2 三行情书

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
span {
font-size: 20px;
color: #837362;
/* TODO:补充下面的代码 */
/* 1. 宽度要固定,先强制一行内显示文本 */
white-space: nowrap;
display: block;
width: 100%;
/*2. 超出的部分隐藏*/
overflow: hidden;
/*3. 文字用省略号替代超出的部分*/
text-overflow: ellipsis;
}
p {
color: #837362;
/* TODO:补充下面的代码 */
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}

3 电影院在线订票

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/* TODO: 
1. 完成数据请求,生成电影名,价格以及座位情况
2. 绑定点击事件,实现订票功能
*/

// 获取座位区域节点
const seatAreaNode = document.getElementById("seat-area");
// 获取电影名节点
const movieNameNode = document.getElementById("movie-name");
// 获取电影票价节点
const moviePriceNode = document.getElementById("movie-price");
// 获取已订电影票数量节点
const count = document.getElementById("count");
// 获取已订电影票总价节点
const total = document.getElementById("total");

axios('./data.json').then((result) => {
movieNameNode.innerText = result.data.name
moviePriceNode.innerText = result.data.price
let rowHtml = ``
for (const row of result.data.seats) {
rowHtml += `<div class="row">`
for (const seat of row) {
if (seat) rowHtml += `<div class="seat occupied"></div>`
else rowHtml += `<div class="seat"></div>`
}
rowHtml += `</div>`
}
seatAreaNode.innerHTML = rowHtml

// 实现座位选择和总价计算的功能
let totalNum = 0
seatAreaNode.addEventListener('click', (e) => {
e.stopPropagation();
if (e.target.classList.contains('occupied')) return
if (e.target.classList.contains('selected')) {
e.target.classList.remove('selected')
totalNum--
} else {
e.target.classList.add('selected')
totalNum++
}
count.innerText = totalNum
total.innerText = totalNum * result.data.price
})
}).catch((err) => {
console.log(err);
});

4 老虎机

1
2
3
4
5
6
7
8
9
10
11
12
GetResult(r1, r2, r3) {
// TODO 待补充代码
let one = sevenFirst.querySelectorAll('li')[r1].dataset.point
let two = sevenSecond.querySelectorAll('li')[r2].dataset.point
let three = sevenThird.querySelectorAll('li')[r3].dataset.point
if (one === two && one === three) {
textPanel.innerHTML ='恭喜你,中奖了'
}
else {
textPanel.innerHTML ='很遗憾,未中奖'
}
}

5 星际通讯

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const translate = (alienMessage) => {
// TODO:待补充代码

let res = ''
for (let idx = 0; idx < alienMessage.length; idx += 3) {
let sp = alienMessage.slice(idx, idx + 3)
if (sp === 'XXI') break
if(sp in codonTable)
res += codonTable[sp]
else
return '无效密语'
}
return res
};

6 蓝桥排位赛

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
const app = createApp({
setup() {
const chartsData = ref([]);
onMounted(async () => {
// TODO:待补充代码 请求数据,并正确渲染柱形图和地图
await axios("./mock/map.json").then((res) => {
chartsData.value = res.data;
});
showChartBar();
showChinaMap();
});

// 展示柱状图
const showChartBar = () => {
const myChart = echarts.init(document.getElementById("chart"));
// console.log(chartsData.value);
let data = chartsData.value.map((item, index) => {
return item.school_power;
});


// 展示地图
const showChinaMap = () => {
const chinaMap = echarts.init(document.getElementById("chinaMap"));
let province=chartsData.value.map(element => {
return {
name:element.name,
value:element.school_power.reduce((a,b)=>a+b.power, 0),
school_count:element.school_power.length
}
});
console.log(province);
}

7 拼出一个未来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 定义拖放事件的处理函数
function drop(event) {
// 检查是否拖动的拼图块不是当前目标拼图块
// draggedPiece 被拖动的拼图块元素。this 目标位置的拼图块元素。
if (draggedPiece !== this) {
// TODO:待补充代码
[this.innerHTML, draggedPiece.innerHTML] = [
draggedPiece.innerHTML,
this.innerHTML,
];
// console.log([container]);
let count = 0;
container.querySelectorAll("img").forEach((item, index) => {
// data-id是字符串,所以要用==
if (item.dataset.id == index + 1) {
count++;
if (count === 9) {
successMessage.className = "show";
} else {
successMessage.className = "hide";
}
}
});
console.log(count);
}

// 重置正在拖动的拼图块
draggedPiece = null;
}
  • data-id是字符串,比较要使用==而不是===
  • className以字符串形式编辑dom对象的class

8 超能英雄联盟

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//store.js
const { defineStore } = Pinia;
const { ref } = Vue;

const useHeroStore = defineStore("hero", {
state: () => ({
heroes: [], //英雄列表
team: [], // 队伍列表
}),
// TODO:补全代码,实现目标效果
getters: {
strengthTotal(state){
return state.team.reduce((a,b)=>a+b.strength,0)
}
},
actions: {
teamAdd(item){
this.team.push(item)
},
teamRemove(item){
this.team.splice( this.team.indexOf(item), 1)
},
sortStrength(){
this.team.sort((a,b)=>b.strength-a.strength)
}
},
// TODOEnd
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// TODO:补全代码,实现目标效果
const { onMounted } = Vue;
const HeroList = {
template: `
<div class="hero-list">
<h2>可选英雄</h2>
<ul>

<li class="hero-item" v-for='element in list'>
<span>{{element.name}}</span>
<span>{{element.ability}}</span>
<span>{{element.strength}}</span>
<button @click="add(element)" :disabled="heroStore.team.includes(element)">
{{heroStore.team.includes(element)? "已添加":"添加至队伍"}}
</button>
</li>
</ul>
</div>
`,
setup() {
let heroStore = useHeroStore();
let list = ref([]);
// let btn=ref()
onMounted(() => {
axios("./js/heroes.json").then((res) => {
heroStore.heroes = res.data;
// 考虑到v-for,需要另开一个list
list.value=res.data
});
});

const add=(item)=>{
heroStore.teamAdd(item)
console.log(heroStore.team);
}
return {
list,add,heroStore
};
},
};
// TODOEnd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// TODO:补全代码,实现目标效果
const TeamList = {
template: `
<div class="team-list">
<h2>我的队伍</h2>
<ul>
<li class="team-item" v-for="element in heroStore.team">
<span>{{element.name}}</span>
<span>{{element.strength}}</span>
<button @click=heroStore.teamRemove(element)>移除</button>
</li>
</ul>
<button class="sort-button" @click=heroStore.sortStrength>按实力排序</button>
<p class="total-strength">当前队伍战斗力:{{heroStore.strengthTotal}} </p>
</div>
`,
setup() {
const heroStore = useHeroStore();
return{
heroStore
}
},
};
// TODOEnd

+

  • setup可以是async

9 实时展示权限日志

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
if (req.method === "GET" && req.url === "/users") {
// TODO 处理获取文件内容的操作
let fileContent = "";
// console.log(222);
try {
fileContent = fs.readFileSync("data.json", "utf-8");
send(res, 0, "", eval(fileContent));
} catch (error) {
send(res, 404, error.msg, "");
}
} else if (req.method === "PUT" && req.url === "/editUser") {
let body = "";
req.on("readable", () => {
let chunk = "";
if (null !== (chunk = req.read())) {
body += chunk;
}
});
req.on("end", () => {
if (body) {
// TODO 处理更改文件数据并将最新的文件数据响应给客户端
// console.log(body);
try {
let file = fs.readFileSync("data.json", "utf-8");
file = JSON.parse(file);
body = JSON.parse(body);
// console.log(body.params.id);
// let idx=file.indexOf(item=>item.id===body.params.id)
file.forEach((element) => {
if (element.id === body.params.id) {
element.power = !element.power;
// console.log(element);
}
});
// console.log(file);
fs.writeFileSync("data.json", JSON.stringify(file));
send(res, 0, "", file);
} catch (error) {
console.log("error");
send(res, 404, "");
}
}
});
} else if (req.method === "POST" && req.url === "/logger") {
let body = "";
req.on("readable", () => {
let chunk = "";
if (null !== (chunk = req.read())) {
body += chunk;
}
});
req.on("end", () => {
if (body) {
// TODO 处理新增日志
console.log(body);
try {
// let file=fs.readFileSync('data.json', 'utf-8')
// console.log(file);
let log = {
id: getLoggerId(),
msg: JSON.parse(body).data,
time: new Date().getTime().toString(),
};
console.log(log);
fs.appendFile("logger.json", JSON.stringify(log) + "\n", () => {
send(res, 0, "", log);
});
// let loggerJson = fs.readFileSync("logger.json", "utf-8");
// loggerJson = JSON.parse(loggerJson);
// loggerJson.push()
} catch (error) {
send(res, 404, "");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
onMounted(() => {
axios("./users").then((res) => {
data.userList = res.data.data;
});
});
const getPowerText = (power) => {
return power ? "可以登录" : "禁止登录";
};
const handleChange = async (e) => {
if (e.target.tagName !== "INPUT") {
return;
}

let person = data.userList.find(
(item) => e.target.dataset.id === item.id
);
// console.log(person);
// TODO 处理发送请求修改当前用户的权限并更新一条日志记录
let res = await axios.put("/editUser", {
data: { power: person.power },
params: { id: person.id },
});
res = parseRes(res);

// data.userList.forEach((element) => {
// let item = res.data.find((item) => item.id === element.id);
// element = Object.assign(item);
// // console.log(item.power === element.power);
// });
data.userList = res.data;

let res2 = await axios.post("/logger", {
data: `超级管理员将用户${person.name}设置为${getPowerText(
!person.power
)}权限`,
});

res2 = parseRes(res2);
let time = new Date(parseInt(res2.data.time))
let timeStr = `${time.getFullYear()}/${time.getMonth()+1}/${time.getDay()} ${time.getHours() <= 12 ? '上午' : '下午'}`
timeStr += `${time.getHours()}:${time.getMinutes()}:${time.getSeconds()}`
res2.data.time = timeStr
data.loggerList.unshift(res2.data)
console.log(res2);
  • axios携带参数:

    1
    2
    3
    4
    axios.put("/editUser", {
    data: { power: person.power },
    params: { id: person.id },
    });
  • node.js读文件:

    • 同步:

      1
      2
      let file = fs.readFileSync("data.json", "utf-8");
      file = JSON.parse(file);
    • 异步:

      1
      2
      3
      let file = fs.readFile("data.json", "utf-8", ()=>{
      file = JSON.parse(file);
      });
  • 写文件:

    1
    fs.writeFileSync("data.json", JSON.stringify(file));

10 账户验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
<script type="module">
import { createPinia, defineStore, storeToRefs } from "pinia";
const { createApp, reactive, toRefs, ref, computed, onMounted } = Vue;
const { ElNotification } = ElementPlus;

const newStore = defineStore("store", () => {
const showName = ref("phone");
const phoneNumber = ref(18839764702);
const checkNumber = ref(0);
const generateCheck = () => {
checkNumber.value = Math.floor(Math.random() * 1e6);
};
const changeShow = (target) => {
showName.value = target;
};
return {showName,changeShow,phoneNumber,generateCheck,checkNumber,
};
});

const app = createApp({
setup() {
let { showName } = storeToRefs(newStore());
// TODO:补全代码实现目标需求

return {
showName,
};
},
});
app.use(ElementPlus);
app.use(createPinia());

app.component("phone", {
template: "#phone",
setup() {
// TODO:补全代码实现目标需求
const store = newStore();
const { phoneNumber } = storeToRefs(store);
const checkValue = ref(true);
const check = () => {
let phoneReg = /^18[0-9]{9}$/;
let phonePass = phoneReg.test(phoneNumber.value);

if (phonePass && checkValue.value) {
store.generateCheck();
let { checkNumber } = storeToRefs(store);
console.log(checkNumber.value);
ElNotification({title: "发送成功",message: `您的验证码为${checkNumber.value}`,type: "success",
});
store.changeShow("check");
} else if (checkValue.value) {
ElNotification({title: "发送失败",message: `无效的手机号码`,type: "error",
});
} else {
ElNotification({title: "发送失败",message: `请先阅读并同意下方协议`,type: "error",
});
}
};

return { check, phoneNumber, checkValue };
},
});
app.component("check", {
template: "#check",
setup() {
// TODO:补全代码实现目标需求
const store = newStore();
let { phoneNumber, checkNumber } = storeToRefs(store);
let hidedNumber = computed(() => {
// let tmp = phoneNumber.value.toString().split('');
// tmp.splice(3, 6, "*", "*","*","*", "*", "*");
// return tmp.join('');
return phoneNumber.value
.toString()
.replace(/^(\d{3})\d{6}(\d{2})$/, "$1******$2");
});
onMounted(() => {
let inputs = document.querySelectorAll(".code");
inputs[0].focus();
inputs.forEach((item) => {
item.addEventListener("input", (e) => {
if (item.value.length && item.nextElementSibling) {
item.nextElementSibling.focus();
} else if (
item.value.length === 0 &&
item.previousElementSibling
) {
item.previousElementSibling.focus();
}
let inputsArray = Array.from(inputs);
if (inputsArray.every((elem) => elem.value.length === 1)) {
let ans = inputsArray.map((elem) => elem.value).join("");
ans = parseInt(ans);
if (ans === checkNumber.value) {
ElNotification({
title: "验证成功",
message: "欢迎回来",
type: "success",
});
store.changeShow("success");
} else {
ElNotification({
title: "验证失败",
message: "您输入的验证码有误",
type: "error",
});
// inputs.forEach(elem=>console.log(elem.value))
inputs.forEach((elem) => (elem.value = ""));
inputs[0].focus();
}
console.log(ans);
}
});
});
});
const reSend = () => {
store.generateCheck();
ElNotification({
title: "发送成功",
message: `您的验证码为${checkNumber.value}`,
type: "success",
});
};
return { phoneNumber, hidedNumber, reSend };
},
});
app.component("success", {
template: "#success",
});
app.mount("#app");
</script>
  • sotre创建:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    const newStore = defineStore("store", () => {
    const showName = ref("phone");
    const changeShow = (target) => {
    showName.value = target;
    };
    return {
    showName,
    changeShow,
    };
    });
  • 使用:

    • state要使用storeToRefs才能不丢失响应式

      1
      let { showName } = storeToRefs(newStore());
    • action不必使用storeToRefs

      1
      2
      const store = newStore();
      store.changeShow("check");
  • 分清数组/字符串方法会不会修改原值返回什么值

    1
    2
    3
    4
    5
    6
    7
    // 把tmp拆散为数组,这样不会修改原值
    let tmp = phoneNumber.value.toString().split('');
    // 由于splice修改了原数组,返回了删除部分,所以不能把join直接加载后面
    tmp.splice(3, 4, "*", "*", "*", "*");
    return tmp.join('');
    // 或者
    return phoneNumber.value.toString().replace(/^(\d{3})\d{4}(\d{4})$/, '$1****$2')
  • querySelectorAll返回的并不是Array,而是NodeList,需要使用Array.from()转换成数组才能使用map every等方法

    1
    2
    let inputsArray=Array.from(inputs)
    if (inputsArray.every(elem=> elem.value.length===1))
  • input事件:input

    方法:focus


2024第十五届蓝桥杯第二次模拟赛web组题解
https://asxjdb.github.io/2024/03/27/2024第十五届蓝桥杯第二次模拟赛web组题解/
作者
Asxjdb
发布于
2024年3月27日
许可协议