16届蓝桥杯模拟赛 1 期-大学组

226 阅读5分钟

题目链接:

www.lanqiao.cn/contests/we…

1.日历格绘

思路:

**本题主要考察CSS中的grid布局,题目中有提示
**总结:水题

题解:

/* TODO_1: 请补充代码 */
display: grid;
grid-template-columns: repeat(7, 1fr);
/* TODO_1: END */

/* TODO_2: 请补充代码 */
#days p:first-of-type{
    grid-column: 3;
}
/* TODO_2: END */

2.记词小能手

思路:

**待复习函数没什么好说的,就是循环展示,如果展示到了最后一个的话需要回到第一个
****完成复习函数, 首先使用删除函数splice删除当前展示的单词,然后展示
****但是需要注意的是,当删除到最后一个的时候当前index会大于words的长度,所以需要回到第一个,而正常删除时则会正常往下推一个,不用++,
****然后再是展示的问题,如果已经全部复习完,也就是words的长度是0,就展示题目给出的p标签,否则展示下一个单词
**总结:思维题,js的splice函数使用

题解:

/**
* @description 待完成单词复习,跳到下一个单词
*/
function waitReview() {
	// TODO: 请补充代码
	if (index >= words.length)
		index = 1;
	else
		index ++;
	renderData(index);
}

/**
* @description 完成单词复习,删除当前单词,跳到下一个单词
*/
function completeReview() {
	// TODO: 请补充代码
	words.splice(index-1, 1);
	if (index >= words.length)
		index = 1;

	if (words.length == 0)
		document.querySelector('#word').innerHTML = '<p class="success">今日复习已完成</p>'
	else{
		renderData(index);
	}
	// TODO: END
	waitTaskBox.innerText = `还需复习:${words.length}`;
}

3.小蓝餐厅

思路:

怎么说呢,写题目不能想当然,题目中提供了方法的话就用它给的,最好不要用自己的方法,如果题目中没提供的话就用自己的方法
****首先是比较简单的axios网络请求,没啥好说的,再者就是需要设置拦截器,axios官网上的拦截器的写法不适合这个题目(链接在最后),需要使用题目中提供的方法(
http://www.axios-js.com/zh-cn/docs/#%E6%8B%A6%E6%88%AA%E5%99%A8**)
****首先是config参数中的对象以及对象里函数的判断,因为题目中说这些都不是必须的,所以说在使用前要先判断,再是拦截器的使用,题目中已经提供了use的使用方法,但是拦截其中的use是有两个函数的如:
****use(成功函数,失败函数)
****然后题目中也展示了成功函数的使用,在模仿写出失败函数就行了,拦截器的写法在题目最后也提供了
**总结:审题,注意题目要求的写法,axios的基本使用

题解:

function useAxios(url, config) {
  const { ref } = Vue;

  // 网络请求返回的数据
  const data = ref(null);
  // 本次网络请求是否出错
  const error = ref(null);
  // TODO:待补充代码

  const instance = axios.create();
  if (config){
    if (config.interceptors && config.interceptors.request){
      instance.interceptors.request.use(
        config.interceptors.request.bind(undefined ,false),
        config.interceptors.request.bind(undefined, true));// 请求拦截器
    }
    if (config.interceptors && config.interceptors.response){
      instance.interceptors.response.use(
        config.interceptors.response.bind(undefined, false),
        config.interceptors.response.bind(undefined, true)); //响应拦截器
    }
  }
  
  instance.get(url).then(res => {
    data.value = res.data;
    error.value = null;
  }).catch(err => {
    data.value = null;
    error.value = err;
  })

  return {
    data,
    error
  }
};

4.世纪危机(人口增长推算)

思路:

**感觉像是在做阅读理解
****主要是Echarts图表内容的考查,API的使用,不过题目有问题,题目中说的是”万“,但是实际上是”百万“,还有就是JS中Math的使用,如果用普通数学方法做也是不能通过的
**总结:Echarts和JS函数

题解:

// 初始化 ECharts 实例
const chart = echarts.init(document.getElementById('main'));

/**人口数据增长推算函数
 * @param {number} initialPopulation 基础人口数,假设有 10 亿
 * @param {number} growthRate 年增长率,假设为 3%
 * @param {number} startYear 起始年份,假设为 200000
 */
function calculatePopulation(initialPopulation, growthRate, startYear){
  const years = [];
  const population = [];
  // TODO:待补充代码 目标 1 
  for(let i = 0; i <= 30; i++){
    years.push(startYear + i);
    population.push(initialPopulation*Math.pow(1+growthRate,i));
  }
  return {years,population};
}

const pData = calculatePopulation(1000000000, 0.03, 200000);

// 配置 ECharts 选项
const option = {
    title: {
        text: '未来30年人口增长趋势图',
        subtext: '假设年增长率为3%',
        left: 'center'
    },
    tooltip: {
        trigger: 'axis',
         // TODO:待补充代码 目标 3
        formatter: (params) => {
            let res = ''
            res += `<p>${params[0].name}<br/>人口:${Math.round(params[0].value / 1000000)}M</p>`
            // console.log(params.length,res);
            return res;
        }
    },
    xAxis: {
        type: 'category',
        // TODO:待修改代码 目标 2 
        // 年份
        data: pData.years,
        name: '年份',
        boundaryGap: false
    },
    yAxis: {
        type: 'value',
        name: '人口数',
        axisLabel: {
             // TODO:待补充代码 目标 4
             formatter: (value, index) => {
                return Math.round(value/1000000) + 'M';
             }
        }
    },
    series: [
        {
            name: '人口',
            type: 'line',
            // TODO:待修改代码 目标 2 
            // 人口数量
            data: pData.population,
            smooth: true,
            lineStyle: {
                color: '#3398DB'
            },
            itemStyle: {
                color: '#3398DB'
            }
        }
    ]
};

// 使用刚指定的配置项和数据显示图表
chart.setOption(option);

5.回忆画廊

思路:

**主要是vue3的v-for指令的使用,JS中Date()函数的使用,还有vue3与element-plus插槽的使用,这个不会的话没办法
**总结:vue3基础+element-plus插槽

题解:

const List = {
  template: `
    <div class="photo-list">
      <el-row :gutter="20">
      <!--TODO:待修改代码  每一个 el-col 存放一个单张照片  -->
        <el-col :span="6" v-for='item in photos' :key='item'>
          <el-card>
           <!-- TODO:待修改代码 目标 1  -->
            <el-image
              style="width: 100%; height: 200px"
              :src="item.url"
            >
            <!-- TODO:待补充代码 目标 2   -->
            <template #error>
              <photo-error/>
            <template>
            </el-image>
            <div style="padding: 14px;">
               <!--TODO:待修改代码 目标 1    -->
              <span class="title">{{item.title}}</span>
              <div class="bottom clearfix">
              <!--TODO:待修改代码 目标 1    -->
                <time class="time">{{getDate(item.date)}}</time>
              </div>
            </div>
          </el-card>
        </el-col>
      </el-row>
    </div>
  `,
  props:['photos'],
  setup(props) {
    let photos = props.photos
    const getDate = (date) => {
      const nowDate = new Date(date);
      const year = nowDate.getFullYear();
      let month = nowDate.getMonth()+1;
      let day = nowDate.getDate();
      if (month < 10)
        month = '0' + month;
      if (day < 10)
        day = '0' + day;
      return `${year}-${month}-${day}`;
    } 
    return {
      photos,
      getDate
    };
  },
};

6.文件切片上传

思路:

**node.js的考点,一点不会
****这题解抄的同学的
**总结:node.js

题解

/**
 * @description: 将图片文件切片列表通过文件流的方式合并成一个文件,文件合并完成后删除所有的切片。
 * @param {*} imgNameList 图片文件列表
 * @param {*} writeStream 写入流
 * @param {*} deleFileList 需要删除的图片文件列表
 * @return {*}
 */
function streamMergeRecursive(imgNameList, writeStream, deleFileList = []) {
    // TODO:待补充代码
    if (imgNameList.length === 0) {
        writeStream.end();
        deleFile(deleFileList);
        return;
    }

    // 获取并移除图片文件列表中的第一个文件名
    const imgName = imgNameList.shift();
    // 创建读取流
    const readStream = fs.createReadStream(path.resolve(baseDir, imgName));
    // 将读取流的数据写入写入流,但不结束写入流
    readStream.pipe(writeStream, { end: false });
    // 当读取流结束时,将当前文件名添加到删除列表,并递归处理下一个文件
    readStream.on('end', () => {
        deleFileList.push(imgName);
        streamMergeRecursive(imgNameList, writeStream, deleFileList);
    });
}

7.员工管理

思路:

这个题的目标一考察vue的基本语法的[**emit**](https://cn.vuejs.org/guide/components/events.html)**的使用,还有JS的函数使用,看知识点会不会不会就完蛋
**总结:vue + JS

题解:

const handleSubmit = () => {
    // TODO 目标1  待补充代码
   emit('submit-add')
};

const handleCancel = () => {
    // TODO 目标1 待补充代码
   emit('close-add')
};

// TODO:待补代码目标 2
worker.value[editIndex.value].name = form.name;
worker.value[editIndex.value].phone = form.phone

/**
* 批量删除
*/
const deleteItems = () => {
  // TODO:待补充代码 目标 3 
  worker.value = worker.value.filter(item => {
      if (item.checked === false)
          return item
  })
}

/**
* 删除单个员工 
* @param item 员工信息
*/
const deleteItem = item => {
  // TODO:待补充代码 目标 3
  worker.value.splice(worker.value.indexOf(item),1); 
}

          

8. 收藏书签栏

思路:

这个题目算是比较复杂的题目了,要转化数据对象的结构,然后还要改变数组对象内部的值->这个地方用到了引用赋值,这个算一个浅拷贝的特例,然后再是对象结构转化的地方用到了map()**函数
**总结:JS函数+数据拷贝

题解

const addBookmark = () => {
  const newBookmark = {
    name: bookmarkTitle.value,
    url: bookmarkUrl.value,
  };
  // TODO: 实现添加书签功能
  const pathList = selectedFolderPath.value.split('/');
  let nowNode = bookmarks.value;
  pathList.forEach(e => {
    let node = nowNode.find(item => e == item.tag);
    if (node){
      nowNode = node.children;
    }
  });
  nowNode.push(newBookmark);


  closeDialog();
  treeData.value = convertBookmarksToTreeData(bookmarks.value);
};

const convertBookmarksToTreeData = (bookmarks) => {
  // TODO: 实现书签数组转换为树形数据结构的逻辑
  return bookmarks.map(i => {
    return {
      'label': i.tag||i.name,
      'children': i.children?convertBookmarksToTreeData(i.children):[],
      'url': i.url,
    }
  })
};

const handleNodeDrop = (draggingNode, dropNode, dropType) => {
  console.log(draggingNode.data);
  // TODO: 实现拖放功能
  function convertTreeDataToBookmarks(treeData) {
    return treeData.map((node) => {
      if (node.url) {
        return {
          name: node.label,
          url: node.url,
        }
      }
      return {
        tag: node.label,
        children: convertTreeDataToBookmarks(node.children || []),
      }
    })
  };
  bookmarks.value = convertTreeDataToBookmarks(treeData.value);
};

9.订单状态更新

思路:

思维题,题目要求返回Promise对象先判断传入的数组是不是空的,然后返回空数组,如果不是空的,则需要将数组内的**Promise**对象解构,否则不变,如果**Promise**对象有**reject**的直接返回**reject **我一直在用算法的思维写,然后查资料发现**forEach****是同步执行,一直不显示结果
**总结:Promise对象和JS

题解:

/**
 * @param {Array} promises  传入的数组,可以包含 Promise 对象或普通值
 * @return {Promise}  返回一个 Promise,解析为结果数组
 */
function myPromiseAll(promises) {
  // TODO:待补充代码
  return new Promise((resolve,reject) => {
    if (promises.length == 0)
      resolve([]);
    else{
      let res = [],cnt = 0;      
      promises.forEach((item,index) => {
        if(Object.prototype.toString.call(item) != '[object Promise]'){
          res[index] = item;
          cnt ++;
          if (cnt == promises.length)
            return resolve(res);
        }
        else{
          item.then(p => {
            res[index] = p;
            cnt ++;
            if (cnt == promises.length)
              return resolve(res);
          }).catch(err => {
            return reject(err);
          })
        }
      })
    }
  })
}

10.需求管理

思路:

**有bug,目标四只需要取消单选框然后相应的数据消失,选择单选框后数据不回显也可以通过
****这个题
****这个题考的挺综合,反正我不会,看官方题解的,学到了挺多
****首先是子父组件之间的传值、监听事件(props,emits),计算属性computed,监听器watch,响应式数据,JS函数的使用
**总结:vue的综合使用

题解:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script src="./lib/vue.global.js"></script>
    <link rel="stylesheet" href="./css/style.css" />
    <title>需求管理</title>
  </head>
  <body>
    <div id="app" v-cloak>
      <header>
        <stats 
          :items-data="itemsList"
        ></stats>
        <filter-group 
          @update="updateGroup"
        ></filter-group>
      </header>
      <!-- TODO:待修改代码 目标 1  -->
      <demand-list
        :items-data="itemsList"
        @update-child="updateChild"
        @update-parent="updateParent"
        @toggle-item="toggleItem"
      ></demand-list>
    </div>
    <script src="./components/DemandList.js"></script>
    <script src="./components/FilterGroup.js"></script>
    <script src="./components/Stats.js"></script>
    <script>
      const { createApp, ref, computed, onMounted, watch } = Vue;
      let app = createApp({
        setup() {
          const MockUrl = `./mock/data.json`
          const items = ref([]);
          onMounted(async () => {
            // TODO:待修改代码目标 1
            let res = await fetch(MockUrl)
            items.value = await res.json()
            console.log(items.value)
          });
          
          // TODO:待补充代码 目标 4 
          const obj1 = ref({
            demand: true,
            bug: true,
            task: true
          })
          const itemsList = computed(() => {
            return items.value.filter(i => obj1.value[i.type]);
          })
          const updateGroup = (obj) => {
            obj1.value = obj
            console.log(obj1.value)
          }
          // TODO:END

          const toggleItem = (item) => {
            item.expanded = !item.expanded;
          };

          // 目标 2 点击完成的逻辑
          // 点击子项目
          const updateChild = (parent) => {
             // TODO:待补充代码 目标 2 
             parent.completed = !parent.children.find(i => !i.completed)
          };
          // 点击父项目
          const updateParent = (item) => {
             // TODO:待补充代码 目标 2 
             if (item.children){
              item.children.map(i => i.completed = item.completed);
             }
          };
          // 目标 2 END
       
          return {
            items,
            itemsList,
            updateGroup,
            toggleItem,
            updateChild,
            updateParent,
          };
        },
      });
      app.component("demand-list", DemandList);
      app.component("filter-group", FilterGroup);
      app.component("stats", Stats);
      let vm = app.mount("#app");
    </script>
  </body>
</html>


let DemandList = {
   // TODO:待补充代码 目标 1 
  props: ['itemsData'],
  emits: ['update-child', 'update-parent', 'toggle-item'],
  setup(props, { emit }) {
    const toggleItem = (item) => {
      emit('toggle-item', item);
    };

    const updateChild = (parent) => {
      emit('update-child', parent);
    };

    const updateParent = (item) => {
      emit('update-parent', item);
    };

    return {
      toggleItem,
      updateChild,
      updateParent,
    };
  },
  template: `
    <ul>
    <!-- TODO:待修改代码,目标 1 此处的空数组需要修改正确数据 -->
      <li
        v-for="item in itemsData"
        :key="item.id"
        :class="{ demand: item.type === 'demand', bug: item.type === 'bug', task: item.type === 'task' }"
      >

// TODO:待补充代码
const Stats = {
  props: ['itemsData'],
  setup(props) {
    const getCount = (type) => { 
      return props.itemsData.filter(i => i.type == type).length 
    }
    const getSelectedCount = (type) => {
      return props.itemsData.filter(i => i.type == type && i.completed).length 
    }

    const getDemandCount = computed(() => getCount('demand'))
    const getDemandSelectedCount = computed(() => getSelectedCount('demand'))
    const getBugCount = computed(() => getCount('bug'))
    const getBugSelectedCount = computed(() => getSelectedCount('bug'))
    const getTaskCount = computed(() => getCount('task'))
    const getTaskSelectedCount = computed(() => getSelectedCount('task'))
    return {
      getDemandCount,
      getDemandSelectedCount,
      getBugCount,
      getBugSelectedCount,
      getTaskCount,
      getTaskSelectedCount
    }
  },
  template: `
    <div class="stats">
      <div>
        需求:{{getDemandSelectedCount}}/{{getDemandCount}}
      </div>
      <div>
        缺陷:{{getBugSelectedCount}}/{{getBugCount}}
      </div>
      <div>
        任务:{{getTaskSelectedCount}}/{{getTaskCount}}
      </div>
    </div>
  `,
};

// TODO:待补充代码

const FilterGroup = {
  emits: ['update'],
  setup(props, { emit }) {
    const obj = ref({
      demand: true,
      bug: true,
      task: true
    })

    watch(obj, (newData) => {
      emit('update',newData)
      // console.log(newData)
    },{deep: true})

    return {
      obj,
    }
  },
  template: `
    <div class="filter-group">
      过滤:
      <label>
        <input type="checkbox" v-model='obj.demand'> 需求
      </label>
      <label>
        <input type="checkbox" v-model='obj.bug'> 缺陷
      </label>
      <label>
        <input type="checkbox" v-model='obj.task'> 任务
      </label>
    </div>
  `,
};