10.组课神器-第⼗四届蓝桥杯web应用开发--省赛

分析

类型:VUE
分数:25分
难度:很难

考点

  • 掌握使用 axios 发送 AJAX 请求
  • 掌握 localStorage 存储数据、取出数据的使用
  • 掌握 JSON 字符串转成 Object 对象
  • 掌握 模板字符串 中使用 if 语句,三元表达式、调用函数
  • async、await 的使用

第一题

解题思路

当 method === “get” 时,判断 localStorage 中是否存在 key 为 data 的数据,若存在,则
从 localStorage 中直接获取后处理为 json 格式并返回;若不存在则从 ./js/data.json (必须
使⽤该路径请求,否则可能会请求不到数据)中使⽤ ajax 获取并返回。
当 method === “post” 时,将通过参数 data 传递过来的数据转化为 json 格式的字符串,并保
存到 localStorage 中, key 命名为 data

难度

对 localStorage 的 API 使用

代码

修改 index.js 文件中的 ajax() 函数:

/**
 * @description 模拟 ajax 请求,拿到树型组件的数据 treeData
 * @param {string} url 请求地址
 * @param {string} method 请求方式,必填,默认为 get
 * @param {string} data 请求体数据,可选参数
 * @return {Array}
 * */
async function ajax({ url, method = "get", data }) {
  let result;
  // TODO:根据请求方式 method 不同,拿到树型组件的数据
  // 当method === "get" 时,localStorage 存在数据从 localStorage 中获取,不存在则从 /js/data.json 中获取
  // 当method === "post" 时,将数据保存到localStorage 中,key 命名为 data

  if(method === "get"){
    const data = localStorage.getItem("data")
    if(data){
      // 将json字符串转成json对象
      result = JSON.parse(data)
      // console.log("localStorage result:",result)
    }else{
      // async和await 搭配使用,简化写法,表示同步执行
      // axios.get("./js/data.json ").then()
      const ajaxResult = await axios.get("./js/data.json")
      result = ajaxResult.data.data
    }
  }else if(method === "post"){
    // console.log("data:",data)
    localStorage.setItem("data",JSON.stringify(data))
  }

  // console.log("result:",result)
  return result;
}

第二题

解题思路

在 模板字符串 ,⽣成指定 DOM 结构

技巧

在 模板字符串 中使用 if 语句,三元表达式、调用函数,⽣成指定 DOM 结构

代码

修改 index.js 文件的 treeMenusRender() 函数

/**
 * @description 根据 treeData 的数据生成树型组件的模板字符串,在包含 .tree-node 的元素节点需要加上 data-grade=${index}表示菜单的层级 data-index="${id}" 表示菜单的唯一id
 * @param {array} data treeData 数据
 * @param {number} grade 菜单的层级
 * @return 树型组件的模板字符串
 *
 * */
function treeMenusRender(data, grade = 0) {
  let treeTemplate = "";
  // TODO:根据传入的 treeData 的数据生成树型组件的模板字符串

  // console.log("data:",data)
  // console.log("grade:",grade)

  for( let item of data){
    treeTemplate += `
    <div class="tree-node" data-index="${item.id}" data-grade="${grade+1}">
      <!-- 每一章标题的 DOM 结构 start -->
      <div class="tree-node-content" style="margin-left: ${grade * 15}px">
        <div class="tree-node-content-left">
          <img src="./images/dragger.svg" alt="" class="point-svg" />
          <!-- 没有children时,就显示tag -->
          ${ 'children' in item ? '':`<span class="tree-node-tag">${item.tag}</span>` }
          <span class="tree-node-label">${item.label}</span>
          <!-- 如果是三级节点(判断方式:如果item不包含 children),就不显示齿轮图标 -->
          ${ 'children' in item ? `<img class="config-svg" src="./images/config.svg" alt="" />`:'' }

        </div>
        <!-- 如果是三级节点(判断方式:如果item不包含 children),才显示 右侧部分 -->
        ${ 'children' in item ? 
          '':
          `<div class="tree-node-content-right">
            <div class="students-count">
              <span class="number"> 0人完成</span>
              <span class="line">|</span>
              <span class="number">0人提交报告</span>
            </div>
            <div class="config">
              <img
                class="config-svg"
                src="./images/config.svg"
                alt=""
              />
              <button class="doc-link">编辑文档</button>
            </div>
          </div>`
        }

      </div>
      <!-- 如果item存在 children,那么就递归调用函数,否则返回空字符串 -->
      ${ 'children' in item ? 
        `<div class="tree-node-children">
          <!-- 递归调用函数 -->
          ${treeMenusRender(item.children,grade+1)}
        </div>`
        :
        ''
      }


    </div>
  `
  }
  return treeTemplate;
}

第三题

解题思路

使用双重循环,构建拖拽后的 treeData 数据

代码

修改 index.js 文件的 treeMenusRender() 函数

/**
 * @description 根据 dragElementId, dropElementId 重新生成拖拽完成后的树型组件的数据 treeData
 * @param {number} dragGrade 被拖拽的元素的等级,值为 dragElement data-grade属性对应的值
 * @param {number} dragElementId 被拖拽的元素的id,值为当前数据对应在 treeData 中的id
 * @param {number} dropGrade 放入的目标元素的等级,值为 dropElement data-grade属性对应的值
 * @param {number} dropElementId 放入的目标元素的id,值为当前数据对应在 treeData 中的id
 */
function treeDataRefresh(
{ dragGrade, dragElementId },
{ dropGrade, dropElementId }
) {
if (dragElementId === dropElementId) return;
// TODO:根据 `dragElementId, dropElementId` 重新生成拖拽完成后的树型组件的数据 `treeData`
// console.log("dragGrade:",{ dragGrade, dragElementId })
// console.log("dropGrade:",{ dropGrade, dropElementId })
// console.log("treeData:",treeData)


/*
使用 循环语句,一层一层的查找拖拽的节点,将其删除
*/

// 待处理的 arr
const arr = [treeData]
// 拖拽的节点
let dragEl = null

while(arr.length>0){
  // 取出并删除第一个元素
  const e = arr.shift()
  // console.log("e:",e)
  let index = 0
  for( let item of e){
    // console.log("item.id === dragElementId--------",item.id , dragElementId , typeof item.id , typeof dragElementId , item.id === dragElementId)
    if( item.id == dragElementId){
      dragEl = item
      // 根据索引删除元素
      e.splice(index , 1)
      // console.log("删除节点:",e,index)
      // 由于一次拖拽只能操作一个节点,所以一旦找到后,就退出循环
      arr.length = 0 // 清空元素
      break
    }else{
      // 如果该节点不是拖拽的节点,就将其 children 添加到待处理的 arr 中
      if( 'children' in item ){
        arr.push(item.children)
      }
    }


    index ++
  }

}

原文出处:/show_1GWMg7HCDgZ.html