跳转至

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()
    )
  );
}