第13届蓝桥杯 Web应用开发赛道题解

01水果拼盘(5分)

/* TODO:待补充代码 */
#pond {
  flex-flow: column wrap;
}

这一题真的挺有意思的,如果我们自己来写这个页面的话应该会按照下面的进行布局

第13届蓝桥杯 Web应用开发赛道题解_第1张图片

3个大div横向排列,然后每个div里面套5个水果,但是题目是15个水果直接并列的写法,蓝桥杯要求我们不能改变这个页面的结构。

我一开始也想了很久,我F12看了一下页面结构,发现背景的15个盘子也是15个div并列的结构,然后我就发现了代码里面的这行代码。

第13届蓝桥杯 Web应用开发赛道题解_第2张图片

哈哈,答案已经告诉我们了,直接套用盘子的样式就可以了,仔细分析一下就是15个元素进行并列的话,每一个的高度是页面高度的20% 就能做到一竖排固定5个的效果了。妙啊

02展开你的扇子(5分)

#box:hover #item1 {
  transform: rotate(-60deg);
}
#box:hover #item2 {
  transform: rotate(-50deg);
}
#box:hover #item3 {
  transform: rotate(-40deg);
}
#box:hover #item4 {
  transform: rotate(-30deg);
}
#box:hover #item5 {
  transform: rotate(-20deg);
}
#box:hover #item6 {
  transform: rotate(-10deg);
}
#box:hover #item7 {
  transform: rotate(10deg);
}
#box:hover #item8 {
  transform: rotate(20deg);
}
#box:hover #item9 {
  transform: rotate(30deg);
}
#box:hover #item10 {
  transform: rotate(40deg);
}
#box:hover #item11 {
  transform: rotate(50deg);
}
#box:hover #item12 {
  transform: rotate(60deg);
}

难度不大,注意一下最终的效果要和给的gif图一样就好了

03和手机相处的时光(10分)

var option = {
  title: {
    text: "一周的手机使用时长",
  },
  yAxis: {
    type: "value",
  },
  xAxis: {
    data: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"],
  },
  series: [
    {
      data: [2.5, 2, 2.6, 3.2, 4, 6, 5],
      type: "line",
    },
  ],
};

这个要用过Echarts才能写出来,难度不大,就是一些配置,虽然配置啥的不好记,但是题目一共就几行代码,一点点试都能试出来。

04灯的颜色变化(10分)

// TODO:完善此函数 显示红色颜色的灯
function red() {
  document.querySelector('#defaultlight').style.display = 'none';
  document.querySelector('#redlight').style.display = 'inline-block';
}

// TODO:完善此函数  显示绿色颜色的灯
function green() {
  document.querySelector('#redlight').style.display = 'none';
  document.querySelector('#greenlight').style.display = 'inline-block';
}

// TODO:完善此函数
function trafficlights() {
  setTimeout(red, 3000);
  setTimeout(green, 6000);
}

trafficlights();

简单的js修改css,难度也不大

05冬奥大抽奖(15分)

// TODO:请完善此函数
function rolling() {
  // 清除上一个效果
  if (time !== 0) {
    let lastIndex = ((time - 1) % 8) + 1;
    $(`.li${lastIndex}`).removeClass('active');
  }
  // 当前高亮效果
  let index = (time % 8) + 1;
  $(`.li${index}`).addClass('active');

  time++; // 转动次数加1
  clearTimeout(rollTime);
  rollTime = setTimeout(() => {
    window.requestAnimationFrame(rolling); // 进行递归动画
  }, speed);

  // time > times 转动停止
  if (time > times) {
    // 展示结果
    const ans = $('.active').text();
    $('#award').text(`恭喜您抽中了${ans}!!!`);
    clearInterval(rollTime);
    time = 0;
    return;
  }
}

发现每一个li都有一个class,就要想办法把当前转动了几次转换成现在是第几个,刚好符合模运算

06蓝桥知识网(15分)

入门的了 我就不写了 比较耗时间

07布局切换(20分)

<div id="app" v-cloak>
  
  <div class="bar">
    <a class="grid-icon" :class='[activeBar===0?"active":""]' @click="changeBar(0)">a>
    <a class="list-icon" :class='[activeBar===1?"active":""]' @click="changeBar(1)">a>
  div>
  
  <ul class="grid" v-if="activeBar===0">
    <li v-for="g in goodsList" :key="g.url">
      <a :href="g.url" target="_blank"><img :src="g.image.large" />a>
    li>
  ul>
  <ul class="list" v-else>
    <li v-for="g in goodsList" :key="g.url">
      <a :href="g.url" target="_blank"><img :src="g.image.large" />a>
      <p>{{g.title}}p>
    li>
  ul>
div>
var vm = new Vue({
  el: '#app',
  data: {
    goodsList: [],
    activeBar: 0,
  },
  mounted() {
    // TODO:补全代码实现需求
    this.initData();
  },
  methods: {
    initData() {
      axios.get('./goodsList.json').then((res) => {
        this.goodsList = res.data;
      });
    },
    changeBar(num) {
      this.activeBar = num;
    },
  },
});

要用一个标识来表示现在是 list展示 还是 grid 展示,剩下的就是vue基础了

不过这里用到了一个 v-cloak 指令 确实比较少见,可以百度了解一下

08购物车(20分)

<script>
  new Vue({
    el: '#app',
    data: {
      cartList: [],
      goodsList: []
    },
    mounted() {
      this.goodsList = GoodsArr;
    },
    methods: {
      addToCart(goods) {
        // TODO:修改当前函数,实现购物车加入商品需求
        const index = this.cartList.findIndex((item) => item.id === goods.id)
        if(index === -1){
          goods.num = 1;
          this.cartList.push(goods);
        }else{
          this.cartList[index].num += 1;
        }
        this.cartList = JSON.parse(JSON.stringify(this.cartList));
      },
      removeGoods(goods) {
        // TODO:补全代码实现需求
        const index = this.cartList.findIndex((item) => item.id === goods.id)
        this.cartList[index].num -= 1;
        if(!this.cartList[index].num){
          this.cartList.splice(index,1)
        }
        this.cartList = JSON.parse(JSON.stringify(this.cartList));
      }
    }
  });
</script>

原先页面效果的实现了 我们调整正确的js逻辑就行了

  • 添加购物车,已经在购物车的数量+1
  • 删除购物车,数量为0的时候删除这个商品

不知道你们会不会有一个疑惑

this.cartList = JSON.parse(JSON.stringify(this.cartList));

就是为什么要拷贝一下。

涉及到js的数据双向绑定了,其实这里重点不是拷贝,是赋值

vue中,数组的增删改 变化是可以监听到的,但是数组里面的对象属性变化的时候是监听不到的,就比如这里的 goods.num变化了,页面上是不会有效果的。

所以要重新赋值一下,让vue监听到整个数组变化了再去做双向绑定。

其实这样写很不好的,明明只是数组里面的某一个对象的某一个属性变化了,但是现在要把整个数组更新了。

官方有一个$set方法可以了解一下

改变一下写法就是

<script>
  new Vue({
    el: '#app',
    data: {
      cartList: [],
      goodsList: []
    },
    mounted() {
      this.goodsList = GoodsArr;
    },
    methods: {
      addToCart(goods) {
        // TODO:修改当前函数,实现购物车加入商品需求
        const index = this.cartList.findIndex((item) => item.id === goods.id)
        if(index === -1){
          goods.num = 1;
          this.cartList.push(goods);
        }else{
          let item = this.cartList[index]
          item.num += 1;
          this.$set(this.cartList,index,item)
        }
      },
      removeGoods(goods) {
        // TODO:补全代码实现需求
        const index = this.cartList.findIndex((item) => item.id === goods.id)

        let item = this.cartList[index]
        item.num -= 1;
        if(!item.num){
          this.cartList.splice(index,1)
        }else{
          this.$set(this.cartList,index,item)
        }
      }
    }
  });
</script>

09寻找小狼人(25分)

// 返回条件为真的新数组
Array.prototype.myarray = function (cb) {
  // TODO:待补充代码
  let res = [];
  this.forEach((item) => {
    if (cb(item)) res.push(item);
  });
  return res;
};

难度也不大,就是实现ES6的filter,学js的时候,没有学ES6要做数组的过滤,要是这样问你们应该都会写。

主要是这个cb回调函数的写法,一开始js还不健壮的时候 回调函数的方式是很常见的,其实不会写的时候可以 多 log出来看看这个东西是什么

10课程列表(25分)

这一题,不知道怎么说,就是一个很常见的 加载数据的题目。直接上代码了

let pageNum = 1; // 当前页码,默认页码1
let pageSize = 5;
let maxPage; // 最大页数
let carlist = [];

// TODO:待补充代码

// 点击上一页
let prev = document.getElementById('prev');
prev.onclick = function () {
  // TODO:待补充代码
  if (pageNum - 1 !== 0) {
    getListByPageNum(--pageNum);
  }
};
// 点击下一页
let next = document.getElementById('next');
next.onclick = function () {
  // TODO:待补充代码
  if (pageNum < maxPage) {
    getListByPageNum(++pageNum);
  }
};

// 根据页码获取数据并渲染数据
function getListByPageNum(pageNum) {
  const temp = JSON.parse(JSON.stringify(carlist));
  list = temp.splice((pageNum - 1) * pageSize, pageSize);
  render(list);
  changeBtnState(pageNum, maxPage);
}

// 渲染函数
function render(list) {
  let res = '';
  list.forEach((item) => {
    let groupStr = ``;
    res += groupStr;
  });
  document.getElementById('list').innerHTML = res;
}

// 根据页码改变按钮的状态
function changeBtnState(pageNum, maxPage) {
  const prevBtn = document.getElementById('prev');
  const nextBtn = document.getElementById('next');

  // 不管37 21 先把所有按钮的禁用取消
  prevBtn.classList.remove('disabled');
  nextBtn.classList.remove('disabled');

  // 第一页的时候不能上一页
  if (pageNum === 1) prevBtn.classList.add('disabled');
  // 最后一页的时候不能下一页
  if (pageNum === maxPage) nextBtn.classList.add('disabled');
}

// 初始化方法,主要是初始化一些数据(页码,列表数据)并且加载第一页内容
function init() {
  axios.get('./js/carlist.json').then((res) => {
    carlist = res.data;
    pageNum = 1;
    maxPage = Math.ceil(res.data.length / pageSize);
    getListByPageNum(pageNum);
  });
}
init();

代码从最后一行的init方法开始看

你可能感兴趣的:(前端,javascript,蓝桥杯)