24模拟赛2
1 相不相等¶
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 三行情书¶
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;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
3 电影院在线订票¶
/* 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 老虎机¶
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 星际通讯¶
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 蓝桥排位赛¶
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 拼出一个未来¶
// 定义拖放事件的处理函数
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 超能英雄联盟¶
//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
});
// 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
// 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 实时展示权限日志¶
if (req.method === "GET" && req.url === "/users") {
// TODO 处理获取文件内容的操作
let fileContent = "";
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 处理更改文件数据并将最新的文件数据响应给客户端
try {
let file = fs.readFileSync("data.json", "utf-8");
file = JSON.parse(file);
body = JSON.parse(body);
file.forEach((element) => {
if (element.id === body.params.id) {
element.power = !element.power;
}
});
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 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);
});
} catch (error) {
send(res, 404, "");
}
}
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
);
// TODO 处理发送请求修改当前用户的权限并更新一条日志记录
let res = await axios.put("/editUser", {
data: { power: person.power },
params: { id: person.id },
});
res = parseRes(res);
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携带参数:
axios.put("/editUser", {
data: { power: person.power },
params: { id: person.id },
});
-
node.js
读文件: -
同步:
let file = fs.readFileSync("data.json", "utf-8"); file = JSON.parse(file);
-
异步:
let file = fs.readFile("data.json", "utf-8", ()=>{ file = JSON.parse(file); });
-
写文件:
fs.writeFileSync("data.json", JSON.stringify(file));
10 账户验证¶
<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
创建:
const newStore = defineStore("store", () => {
const showName = ref("phone");
const changeShow = (target) => {
showName.value = target;
};
return {
showName,
changeShow,
};
});
-
使用:
-
state要使用
storeToRefs
才能不丢失响应式let { showName } = storeToRefs(newStore());
-
action
不必使用storeToRefs
const store = newStore(); store.changeShow("check");
-
分清数组/字符串方法**会不会修改原值**、返回什么值
// 把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
等方法
let inputsArray=Array.from(inputs)
if (inputsArray.every(elem=> elem.value.length===1))
input
事件:input
方法:focus
万能合成台¶
https://www.lanqiao.cn/problems/7851/learning/?contest_id=150
https://www.lanqiao.cn/problems/7851/learning/?problem_list_id=24&page=1&status=1
合成钻石锄
function checkRecipe(map) {
// TODO:待补充代码
const twoDe = (obj) => {
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
if (obj[j][i] != map[j][i]) return false;
// if (obj[i][j] != map[i][j]) return false;
}
}
return true;
};
const recp = window.recipes;
for (let key in recp) {
const value = recp[key];
for (let items of value) {
if (items.length == 1) items.push(["", "", ""], ["", "", ""]);
else if (items.length === 2) items.push(["", "", ""]);
if (items[0].length === 1)
items.forEach((element) => {
element.push("", "");
});
else if (items[0].length === 2)
items.forEach((element) => {
element.push("");
});
if (items.toString() === map.toString()) return key;
// if (twoDe(items)) return key;
}
}
return "";
}
另一种:
function checkRecipe(map) {
// 转置
const re_arr = (arr) => arr[0].map((item, i) => arr.map((items) => items[i]));
const filter_empty = (arr) =>
arr.filter((item) => !item.every((value) => value === ""));
return Object.keys(recipes).find((i) =>
recipes[i].some(
(item) =>
item.toString() ===
re_arr(filter_empty(re_arr(filter_empty(map)))).toString()
)
);
}