第十三届蓝桥杯国赛 Web 前端组(大学组) 真题练习及答案解析

【真题练习】分一分

考点:数组方法
思路:利用splice()方法

/**
 * @param {Object} oldArr
 * @param {Object} num
 * */
const splitArray = (oldArr, num) => {
  // TODO:请补充代码实现功能
  let arr = []
  while (oldArr.length > 0) {
    arr.push(oldArr.splice(0,num))
  }
  return arr
};
module.exports = splitArray; // 检测需要,请勿删除


【真题练习】新鲜的蔬菜

考点:flex布局
思路:照着写就行

/* TODO:待补充代码 */
.box{
  display: flex;
}
#box1{
  justify-content: center;
  align-items: center;
}
#box2{
  justify-content: space-between;
}
#box2 .item:last-child{
  align-self: flex-end;
}
#box3 {
   justify-content: space-between;  /* 不加这个不能pass,有点玄学*/
} 
#box3 .item:nth-child(2){
  align-self: center;
}
#box3 .item:nth-child(3){
  align-self: flex-end;
}

【真题练习】水果消消乐

考点: DOM操作
思路:1 先做需求:隐藏开始按钮,方格上的图片显示后又隐藏。 2 再做第一次点击图片翻转效果。 3 做第二次点击的逻辑判断,若水果相同则,进行消除,加分操作,水果不同,进行隐藏,减分操作。

// TODO:请补充代码
const startBtn = document.querySelector("#start")
const imgList = document.querySelectorAll(".img-box img")
const boxList = document.querySelectorAll(".img-box")
const scoreEle = document.querySelector("#score")

const changeDisplay = (element, status) => element.style.display = status
// 隐藏开始按钮,方格上的图片显示后又隐藏
function start(){
    changeDisplay(startBtn,"none")
    // imgList转成数组之后用forEach遍历
    Array.from(imgList).forEach(img=>{
        changeDisplay(img,"block")
    })
    setTimeout(function(){
        Array.from(imgList).forEach(img=>{
            changeDisplay(img,"none")
        })
    },1000)
}


// 正式开始游戏
let score = 0  // 记录分数
let num = 0  // 记录是第一次翻牌还是第二次翻牌
let preId = ""
let preText = ""
function game(){

}
function startGame() {
    start()
    // 给每个box绑定点击事件,不能给img元素绑定点击事件,因为img元素是display:none
    Array.from(boxList).forEach(box=>{
        box.addEventListener("click",function(e){
            num++
            if(num === 1){
                // 如果第一次点击
                preText = e.target.firstElementChild.alt 
                preId = e.target.id
                changeDisplay(e.target.firstElementChild,"block")
            }else{
                // 第二次点击
                let nowText = e.target.firstElementChild.alt 
                let nowId = e.target.id
                changeDisplay(e.target.firstElementChild,"block")
                console.log(nowText,preText,nowId,preId)
                if (nowText === preText){
                    //水果相同 进行消除,加分操作
                    score += 2
                    // 这里得用不可见,要不然位置顺序会变
                    // 不可见仍然触发点击事件
                    setTimeout(function(){
                        document.getElementById(preId).style.visibility = "hidden"
                        document.getElementById(nowId).style.visibility = "hidden"
                        scoreEle.innerText = score
                        // 清空
                        num = 0
                        preId = ""
                        preText = ""
                    },1000)
                } else {
                     //水果不相同 进行隐藏,减分操作
                     score -= 2
                     // 隐藏图像
                     setTimeout(function(){
                        document.getElementById(preId).firstElementChild.style.display = "none"
                        document.getElementById(nowId).firstElementChild.style.display = "none"
                        scoreEle.innerText = score
                        // 清空
                        num = 0
                        preId = ""
                        preText = ""
                     },1000)
                }
            }
        })
    })
}


【真题练习】用什么来做计算 A

考点:js操作和eval()方法
思路:监听每个按钮的点击事件,维护一个字符串str,如果是 resetsqrtequal这三个按钮的点击事件,进行相应的处理,其他按钮的点击事件,则直接拼接str字符串,并更新视图即可。

// TODO:请补充代码
const formulaEle = document.querySelector("#formula")
const resultEle = document.querySelector("#result")


const btnList = document.querySelectorAll(".calc-button")

let str = ""

Array.from(btnList).forEach(btn=>{
    btn.addEventListener("click",function(){
        const id = btn.id 
        const s = btn.innerText.replace("x","*").replace("÷","/")
        console.log("click ...",id)
        switch (id) {
            case "reset":
                str = ""
                formulaEle.value = ""
                resultEle.value = ""
                return 
            case "sqrt":
                resultEle.value = Math.sqrt(eval(str));
                return 
            case "equal":
                resultEle.value = eval(str);
                return 
            default:
                str += s
                formulaEle.value = str
                break;
        }
    })
})

【真题练习】权限管理

考点:DOM操作
思路:首先获取数据,然后根据数据驱动去更新DOM,每次点击事件都去会改变userList的值,然后根据userList的状态去更新页面的变化。

$(function () {
  // 使用 ajax 获取 userList.json 数据并渲染到页面
  getData();
  // 为按钮添加事件
  $("#add").click(function () {
    // TODO:补充代码,实现功能
    let changeList = Array.from(leftSelectEle.selectedOptions).map(e=>({name:e.value}))
    changeAccess(true,changeList)
  });
  $("#addAll").click(function () {
    // TODO:补充代码,实现功能
    changeAccess(true,userList)
  });
  $("#remove").click(function () {
    // TODO:补充代码,实现功能
    let changeList = Array.from(rightSelectEle.selectedOptions).map(e=>({name:e.value}))
    changeAccess(false,changeList)
  });
  $("#removeAll").click(function () {
    // TODO:补充代码,实现功能
    changeAccess(false,userList)
  });
});

const tableEle = document.querySelector("#userList")
const leftSelectEle = document.querySelector("#leftSelect")
const rightSelectEle = document.querySelector("#rightSelect")

function updateTable() {
  let html = `<tr>
    <td>用户名</td>
    <td>权限</td>
  </tr>`
  userList.forEach(user=>{
    let name = user.name
    let right = user.right ? "管理员" : "普通用户"
    html += `<tr>
    <td>${name}</td>
    <td>${right}</td>
  </tr>`
  })
  tableEle.innerHTML = html
}

function updateSelect() {
  let leftHtml = ``
  let rightHtml = ``
  userList.forEach(user=>{
    let tmpHtml = `<option value="${user.name}">${user.name}</option>` 
    if (user.right) {
      rightHtml += tmpHtml
    } else {
      leftHtml += tmpHtml
    }
  })
  leftSelectEle.innerHTML = leftHtml
  rightSelectEle.innerHTML = rightHtml
}
/**
 * 修改权限
 * @param {Object} right 要修改的权限
 * @param {Object} changeList 要修改权限的用户列表
 */
function changeAccess(right, changeList) {
  // TODO:补充代码,实现功能
  changeList.forEach(changeUser=>{
    let idx = userList.findIndex(user=>user.name===changeUser.name)
    userList[idx].right = right
  })
  updateTable()
  updateSelect()
}
var userList = []
// 异步获取数据
async function getData() {
  // TODO:补充代码,实现功能
  await $.ajax({
    url: "./js/userList.json",
    type: "GET",
    success: function(res){
      userList = res
    }
  })
  updateTable()
}


【真题练习】一起会议吧

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>一起会议吧</title>
    <link rel="stylesheet" type="text/css" href="./css/index.css" />
    <link rel="stylesheet" href="./css/iconfont/iconfont.css" />
  </head>
  <body>
    <div id="app">
      <!-- TODO:请在下面实现需求 -->
      <!-- 登录/注销窗口 -->
      <div class="login">
        <div class="left-tools">
          <a class="close-btn"></a>
          <a class="shrink-btn"></a>
        </div>
        <h3 v-if="!isLogin">登录</h3>
        <h3 v-else>注销</h3>
        <p v-if="!isLogin">
          选择用户:<select id="selectUser" v-model="selectId">
            <option :value="user.id" v-for="user in userList" :key=""user.id>{{user.name}}</option>
          </select>
        </p>
        <p v-else>当前用户为:Tom</p>

        <a class="login-btn" @click="login" v-if="!isLogin">登录</a>
        <a class="login-btn" @click="logout" v-else>注销</a>
      </div>

      <!-- 右侧显示用户列表窗口按钮 -->
      <button id="show" class="right-btn" @click="()=>isDisplay=true" v-if="!isDisplay">
        <span class="iconfont icon-left-arrow"></span>
      </button>

      <!-- 用户列表窗口 -->
      <div class="user-dialog" v-if="isLogin && isDisplay">
        <!-- 用户列表窗口上侧工具栏 -->
        <ul class="tools">
          <li class="tools-left">
            <button :class="{active:activeIndex === 0}" @click="toolChange('none',0)">
              <span class="iconfont icon-close"></span>
            </button>
            <button :class="{active:activeIndex === 1}" @click="toolChange('one',1)">
              <span class="iconfont icon-dialog"></span>
            </button>
            <button :class="{active:activeIndex === 2}" @click="toolChange('all',2)">
              <span class="iconfont icon-list"></span>
            </button>
          </li>
          <li class="tools-right" @click="()=>isDisplay=false">
            <button class="show-list">
              <span class="iconfont icon-retract"></span>
            </button>
          </li>
        </ul>

        <!-- 用户列表 -->
        <ul class="say-list">
          <li>
            <span class="iconfont icon-microphone"></span>
          </li>
          <li class="line"></li>
          <li>正在讲话:Tom;</li>
        </ul>
        <ul class="user-list">
          <li v-for="user in meetUserList" :key=""user.id>
            <img class="header" :src="user.imgPath" />
            <div class="user-name">
              <span class="iconfont icon-user header-icon" v-if="user.isHost"></span>
              <span class="iconfont icon-microphone"></span>
              {{user.name}}
            </div>
          </li>
          <!-- <li>
            <img class="header" src="./images/header2.png" />
            <div class="user-name">
              <span class="iconfont icon-microphone"></span>
              Lily
            </div>
          </li> -->
        </ul>
      </div>
    </div>
    <script type="text/javascript" src="./js/vue.js"></script>
    <script type="text/javascript" src="./js/axios.min.js"></script>
    <script type="text/javascript">
      // TODO:请在下面实现需求
      new Vue({
        el: "#app",
        data(){
          return {
            userList: [],
            isLogin: false,
            selectId: "1",
            isDisplay: true,
            mode: "all",
            activeIndex: 2,
          }
        },
        methods: {
            login(){
              this.isLogin = true
            },
            logout(){
              this.isLogin = false
            },
            toolChange(mode,idx){
              this.activeIndex = idx 
              this.mode = mode
            }
        },
        computed:{
          meetUserList:function(){
            if(this.mode === 'all'){
              return this.userList.filter(user=>user.id === this.selectId).concat(this.userList.filter(user=>user.id !== this.selectId)) 
            }else if(this.mode === 'one'){
              console.log(this.selectId,this.userList,this.userList.filter(user=>user.id === this.selectId))
              return this.userList.filter(user=>user.id === this.selectId)
            }else if(this.mode === 'none'){
              return []
            }
          }
        },
        mounted(){
          axios.get("./js/userList.json").then(res => this.userList = res.data)
        }
      });
    </script>
  </body>
</html>


【真题练习】商城管理系统

考点:递归操作和深度优先遍历
思路:利用递归生成 menus,利用深度优先遍历生成auths

// menuList 仅为示例数据,非实际使用数据,实际使用数据层级不确定(可能是四级五级六级等),数据结构与 menuList 一致
// 1. `parentId` 如果为 `-1`,则表示此条数据为顶级数据。
// 2. `parentId` 为该条数据的父级数据的 `id`。

let menuList = [
  { parentId: -1, name: "添加管理员", id: 10, auth: "admin" },
  { parentId: 10, name: "管理员权限分配", id: 11, auth: "admin-auth" },
  { parentId: -1, name: "商品管理", id: 1, auth: "product" },
  { parentId: 1, name: "商品列表", id: 4, auth: "productList" },
  { parentId: 4, name: "商品分类", id: 5, auth: "category" },
  { parentId: 5, name: "添加分类", id: 8, auth: "addClassification" },
  { parentId: 4, name: "商品上架", id: 6, auth: "product" },
  { parentId: -1, name: "评论管理", id: 2, auth: "comments" },
  { parentId: -1, name: "个人中心", id: 3, auth: "profile" },
];

/**
 * @param {*} menuList 传入的数据
 * @return {*} menus 转化后的树形结构数据,auths 转化后的权限列表数组
 */
// 递归插入
const insertMenu = (menus,menu) => {
  if( !menus || menus.length < 1) return ;
  for (let index = 0; index < menus.length; index++) {
    const element = menus[index];
    if (element.id === menu.parentId) {
      element.children.push(menu)
      return 
    }
    insertMenu(element.children,menu)
  }
}
// 深度优先
const deepSearch = (menus) => {
  let auths = []
  menus.forEach(menu=>{
    auths.push(menu.auth)
    if (menu.children.length > 0) {
      auths = auths.concat(deepSearch(menu.children))
    }
  })
  return auths
}

const getMenuListAndAuth = (menuList) => {
  // TODO:待补充代码
  let menus = []
  let auths = []
  menuList.forEach(menu=>{
    let temp = {
      parentId: menu.parentId,
      name: menu.name,
      id: menu.id,
      auth: menu.auth,
      children: []
    }
    if(menu.parentId === -1){
      // 第一级
      menus.push(temp)
    }else{
      // 第n级插入
      insertMenu(menus,temp)
    }
  })
  auths = deepSearch(menus)
  return { menus, auths }; // menus 转化后的树形结构数据,auths 转化后的权限列表数组
};

// 请勿删除和修改以下代码
try {
  module.exports = { getMenuListAndAuth };
} catch (e) {}

  • 1
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值