惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
Stack Overflow Blog
Stack Overflow Blog
Hugging Face - Blog
Hugging Face - Blog
博客园_首页
T
The Blog of Author Tim Ferriss
博客园 - 叶小钗
N
Netflix TechBlog - Medium
腾讯CDC
C
Check Point Blog
P
Proofpoint News Feed
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI
S
SegmentFault 最新的问题
F
Fortinet All Blogs
美团技术团队
U
Unit 42
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 司徒正美
F
Full Disclosure
Recorded Future
Recorded Future
D
DataBreaches.Net
博客园 - 【当耐特】
Martin Fowler
Martin Fowler
J
Java Code Geeks
I
InfoQ
Y
Y Combinator Blog
A
About on SuperTechFans
AI
AI
爱范儿
爱范儿
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Forbes - Security
Forbes - Security
W
WeLiveSecurity
M
MIT News - Artificial intelligence
雷峰网
雷峰网
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Simon Willison's Weblog
Simon Willison's Weblog
Schneier on Security
Schneier on Security
The GitHub Blog
The GitHub Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
aimingoo的专栏
aimingoo的专栏
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
G
GRAHAM CLULEY
Know Your Adversary
Know Your Adversary
Latest news
Latest news
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
D
Docker
Recent Commits to openclaw:main
Recent Commits to openclaw:main
量子位
V2EX - 技术
V2EX - 技术
Project Zero
Project Zero

百里飞洋

【Art Design】一款精美的前端后台模板,出色的 Vite + TypeScript + Element Plus 的 Vue3 后台管理解决方案 坏消息,被DDoS攻击了;好消息,只被打了2分钟。 【开箱验机】只花 6277 拿下 i7-14650HX/RTX4060 笔记本?机械革命 耀世16Pro 安全下车! 我也中招了!大量简中博客站点被镜像,并翻译成了繁体中文 【GitHub】基于Actions和Pages实现项目的自动构建与部署 【Hexo博客】配置RSS插件,生成 Atom1.0 或 RSS2.0 摘要文件 【业务实践】探索 Excel 表数据的导入和导出功能的完整实现方案 【狄仁杰探案】修复Node.js后端图片上传接口漏洞 【浅谈】关于B站博主“食贫道”发布充电视频《迷失东京》后所引发的热议 【Hexo博客】添加友链朋友圈,纵览好友最新文章 【webpack】如何解决Vue打包项目在浏览器开发者工具中显示源代码 【阿里云】对象存储 OSS 产品评测 【前端】常用加解密技术与使用方法 【蓝桥杯】第14届 Web 应用开发省赛真题解析
【蓝桥杯】第13届 Web 应用开发省赛真题解析
百里飞洋 Barry-Flynn · 2023-04-09 · via 百里飞洋

视频讲解:点击观看

01 水果拼盘(5分)

查看样式可以看到,所有水果都放在了 #pond 元素中,由于只设置了 display: flex;,导致所有水果都处于一行。

因此,我们只需设置主轴方向为纵向 、并允许换行即可:

1
2
3
4
5

#pond {
flex-direction: column;
flex-wrap: wrap;
}

02 展开你的扇子(5分)

查看源码可以看到,页面有 12 个相同大小的 div 元素,要求前 6 个顺时针转动,后 6 个逆时针转动。

转动动画用到了 transform: rotate(10deg); 这个属性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

#box:hover #item6 {
transform: rotate(-10deg);
}
#box:hover #item5 {
transform: rotate(-20deg);
}
#box:hover #item4 {
transform: rotate(-30deg);
}
#box:hover #item3 {
transform: rotate(-40deg);
}
#box:hover #item2 {
transform: rotate(-50deg);
}
#box:hover #item1 {
transform: rotate(-60deg);
}
#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);
}

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

这是道代码修复题:由说明可知,文件里 var option = {} 中的内容是 ECharts 的配置项,该配置中存在 Bug,导致坐标轴显示不正确。

Echarts 官方示例 中的代码作比较,我们可以发现是由于 xAxisyAxis 配置项中的 type 值反了,导致两个轴的显示不正常。X 轴应该是 type: "category",,Y 轴应该是 type: "value",

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<script>
var chartDom = document.getElementById("main");
var myChart = echarts.init(chartDom);

var option = {
title: {
text: "一周的手机使用时长",
},
xAxis: {

type: "category",
data: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"],
},
yAxis: {

type: "value",
},
series: [
{
data: [2.5, 2, 2.6, 3.2, 4, 6, 5],
type: "line",
},
],
};
myChart.setOption(option);
</script>

04 灯的颜色变化(10 分)

通过查看源码我们可知,三个颜色的灯泡是已经在页面中给出了的,只是红灯和绿灯被 display: none; 掉了。

因此我们可以通过定时器来实现描述效果,一个等待 3 秒,一个等待 6 秒:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

function red() {
setTimeout(() => {

document.querySelector("#defaultlight").style.display = 'none'
document.querySelector("#redlight").style.display = 'inline-block'
}, 3000);
}


function green() {
setTimeout(() => {

document.querySelector("#redlight").style.display = 'none'
document.querySelector("#greenlight").style.display = 'inline-block'
}, 6000);
}


function trafficlights() {
red()
green()
}

trafficlights();

或者如果想用 Promise 实现异步任务,但注意此时都是等待 3 秒。因为当 red() 执行成功后,才会继续执行 green()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

function red() {
return new Promise((resolve, reject) => {
setTimeout(() => {

document.querySelector("#defaultlight").style.display = 'none'
document.querySelector("#redlight").style.display = 'inline-block'
resolve()
}, 3000);
})
}


function green() {
return new Promise((resolve, reject) => {
setTimeout(() => {

document.querySelector("#redlight").style.display = 'none'
document.querySelector("#greenlight").style.display = 'inline-block'
resolve()
}, 3000);
})
}


async function trafficlights() {
await red()
await green()
}

trafficlights();

05 东奥大抽奖(15 分)

阅读源码我们可知,每次点击按钮后会生成随机20-30次的转动次数,然后会调用 rolling() 函数转起来。

根据要求,我们要补全的代码需要实现:点击开始后,以 classli1 的元素为起点,黄色背景(.active 类)在奖项上顺时针转动。当转动停止后,将获奖提示显示到页面的 idaward 元素中。

  • 我们定义一个变量 num,用来表示高亮索引,也就是控制 li1 ~ li8 哪个奖品高亮。在递归函数中,随着转动次数的增加,索引值也是增加的。但是当索引值大小超过 8 的时候,我们要将其重置为 1:

    1
    2
    3
    4
    5
    6
    7
    time++; 

    num++;
    if(num > 8) {
    num = 1
    }

  • 然后用 jQuery 在递归函数中,选中类名为 li+num 的元素,给当前索引的奖品添加 active 类名:

    1
    $('.li' + num).addClass('active')
  • 同时移除它的同胞元素的 active 类名:

    1
    $('.li' + num).addClass('active').siblings().removeClass('active');

    其中 siblings() 是 jQuery 中的方法,用于查找当前元素的所有同胞元素,也就是有相同类名的同胞元素。

    注意 addClass()removeClass 都是 jQuery 中的方法,用于添加和移除 Dom 元素的指定类名。如果要用原生 JS 语法实现,可以使用 classList.add()classList.remove() 方法。例如,下面的代码可以实现上方 jQuery 代码相同的效果:

    1
    2
    3
    4
    5
    6
    document.querySelectorAll('.li' + num).forEach(function(el) {
    el.classList.add('active');
    el.parentNode.querySelectorAll(':scope > li:not(.li' + num + ')').forEach(function(sibling) {
    sibling.classList.remove('active');
    });
    });

    这里使用了 querySelectorAll() 方法来选中类名为 li+num 的元素,得到只有当前元素的 NodeList 节点数组,然后使用 forEach() 方法遍历该数组。在遍历过程中,使用 classList.add() 方法为当前元素添加类名,使用 parentNode 属性和 querySelectorAll() 方法查找当前元素的同胞元素,并使用 classList.remove() 方法移除它们的类名。

    显然,使用 jQuery 可以大大减少代码量。

  • 接下来要做的就是在转动停止后,将抽奖结果放到 idaward 元素中。

    1
    $('#award').text(`恭喜您抽中了${$('.li' + num).text()}!!!`);

    jQuery 的 .text() 方法相当于原生 JS 中的 .textText 属性,而不是 .innerHTML 属性。因为 .text() 方法和 .textText 属性只会显示文本内容,不会解析 HTML 标记。

  • 最后别忘了重置高亮索引,以便于下次抽奖时还是从第一个商品开始转动。

    1
    2
    3
    4
    5
    6
    7
    8

    if (time > times) {
    clearInterval(rollTime);
    $('#award').text(`恭喜您抽中了${$('.li' + num).text()}!!!`);
    time = 0;
    num = 0;
    return;
    }

至此,本题完成,完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
let rollTime; 
let time = 0;
let speed = 300;
let times;
let num = 0;


$("#start").on("click", function () {
$("#award").text("");
times = parseInt(Math.random() * (20 - 30 + 1) + 20, 10);
rolling();
});


function rolling() {
time++;

num++;
if (num > 8) {
num = 1
}


clearTimeout(rollTime);
rollTime = setTimeout(() => {
window.requestAnimationFrame(rolling);
}, speed);

$('.li' + num).addClass('active').siblings().removeClass('active');








if (time > times) {
clearInterval(rollTime);
$('#award').text(`恭喜您抽中了${$('.li' + num).text()}!!!`);
time = 0;
num = 0;
return;
}
}

06 蓝桥知识网(15 分)

这是道页面布局题,注意页面版心宽度为 1024px,要保证版心居中。

  • 首先清除一下默认样式,然后设置一个版心类:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    }

    li {
    list-style: none;
    }


    .wrap {
    width: 1024px;
    margin: 0 auto;
    }
  • 布局 header 部分:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23

    <header>
    <div class="wrap">
    <div class="nav">
    <h1>蓝桥知识网</h1>
    <ul>
    <li>首页</li>
    <li>热门技术</li>
    <li>使用手册</li>
    <li>知识库</li>
    <li>练习题</li>
    <li>联系我们</li>
    <li>更多</li>
    </ul>
    </div>
    <div class="container">
    <div class="title">蓝桥云课</div>
    <div class="text">随时随地丰富你的技术栈!</div>
    <div class="join">加入我们</div>
    </div>
    </div>
    </header>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58


    header {
    padding-top: 13px;
    background-color: #a6b1e1;
    }

    header .nav {
    height: 46px;
    display: flex;
    justify-content: space-between;
    }

    header .nav h1 {
    font-size: 18px;
    color: white;
    margin-right: 365px;
    }

    header .nav ul {
    display: flex;
    }

    header .nav ul li {
    margin-right: 16px;
    font-size: 16px;
    color: white;
    }

    header .container {
    height: 427px;
    text-align: center;
    }

    header .container .title {
    margin-top: 30px;
    font-size: 45px;
    color: black;
    }

    header .container .text {
    margin-top: 62px;
    color: white;
    font-size: 21px;
    font-weight: 200;
    }

    header .container .join {
    margin: 36px auto 0;
    color: #efbfbf;
    border-radius: 2px;
    font-size: 18px;
    box-shadow: inset 0 0 0 2px #efbfbf;

    width: 120px;
    height: 50px;
    line-height: 50px;
    }
  • 布局 main 部分:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24

    <main>
    <div class="wrap">
    <ul>
    <li>
    <div class="info-title">人工智能</div>
    <div class="info-content">人工智能亦称智械、机器智能,指由人制造出来的机器所表现出来的智能。通常人工智能是指通过普通计算机程序来呈现人类智能的技术。</div>
    </li>
    <li>
    <div class="info-title">前端开发</div>
    <div class="info-content">前端开发是创建 WEB 页面或 APP 等前端界面呈现给用户的过程,通过 HTML,CSS 及 JavaScript 以及衍生出来的各种技术、框架、解决方案,来实现互联网产品的用户界面交互。</div>
    </li>
    <li>
    <div class="info-title">后端开发</div>
    <div class="info-content">后端开发是实现页面的交互逻辑,通过使用后端语言来实现页面的操作功能,例如登录、注册等。</div>
    </li>
    <li>
    <div class="info-title">信息安全</div>
    <div class="info-content">ISO(国际标准化组织)的定义为:为数据处理系统建立和采用的技术、管理上的安全保护,为的是保护计算机硬件、软件、数据不因偶然和恶意的原因而遭到破坏、更改和泄露。</div>
    </li>
    </ul>
    </div>
    </main>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31

    main {
    margin-top: 74px;
    height: 302px;
    }

    main .wrap ul {
    display: flex;
    flex-wrap: wrap;
    }

    main .wrap ul li {
    width: 50%;
    height: 144px;
    padding-right: 20px;
    }

    main .wrap ul li .info-title {
    font-size: 30px;
    font-weight: 200;
    columns: black;
    }

    main .wrap ul li .info-content {
    font-size: 18px;
    color: #aaa;
    line-height: 1.4em;

    margin-top: 20px;
    margin-bottom: 20px;
    }
  • 布局 footer 部分:

    1
    2
    3
    4
    5
    6
    7
    8
    9

    <hr />
    <footer>
    <div class="wrap">
    <div class="footer-title">© 蓝桥云课 2022</div>
    <div class="footer-info">京公网安备 11010102005690 号 | 京 ICP 备 2021029920 号</div>
    </div>
    </footer>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    footer {
    height: 80px;
    text-align: center;
    font-size: 14px;
    color: #aaa;
    }

    footer .wrap .footer-title {
    margin-top: 30px;
    }

    footer .wrap .footer-info {
    margin-top: 10px;
    }

07 布局切换(20 分)

  • 在线环境 - 蓝桥杯题库2454

  • 考点:Vue 2.xaxios

  • 我们先根据要求实现按钮颜色的动态切换,即通过 active 类名的添加和移除来实现:

    1
    2
    3
    4
    5

    <div class="bar">
    <a class="grid-icon" :class="{'active': index === 0}" @click="index = 0"></a>
    <a class="list-icon" :class="{'active': index === 1}" @click="index = 1"></a>
    </div>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <script type="text/javascript">
    var vm = new Vue({
    el: "#app",
    data: {
    goodsList: [],
    index: 0,
    },
    mounted() {

    },
    });
    </script>
  • 首先完成数据请求(数据来源 goodsList.json

    1
    2
    3
    4
    5
    axios.get('./goodsList.json')
    .then(res => {

    this.goodsList = res.data
    })
  • 通过阅读源码我们可知 <ul class="grid"><ul class="list"> 是互斥事件,因此可以用 v-if 来动态渲染。在其中分别使用 v-for 渲染出请求回来的数据项。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <ul class="grid" v-if="index === 0">
    <li v-for="(item, index) in goodsList" :key="index">
    <a :href="item.url" target="_blank"> <img :src="item.image.large" /></a>
    </li>
    </ul>
    <ul class="list" v-if="index === 1">
    <li v-for="(item, index) in goodsList" :key="index">
    <a :href="item.url" target="_blank"> <img :src="item.image.small" /></a>
    <p>{{item.title}}</p>
    </li>
    </ul>

检测通过,本题完成,完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<title>布局切换</title>
<script type="text/javascript" src="./js/vue.js"></script>
<link rel="stylesheet" type="text/css" href="./css/index.css" />
<script src="./js/axios.min.js" type="text/javascript" charset="utf-8"></script>
</head>

<body>
<div id="app" v-cloak>

<div class="bar">
<a class="grid-icon" :class="{'active': index === 0}" @click="index = 0"></a>
<a class="list-icon" :class="{'active': index === 1}" @click="index = 1"></a>
</div>

<ul class="grid" v-if="index === 0">
<li v-for="(item, index) in goodsList" :key="index">
<a :href="item.url" target="_blank"> <img :src="item.image.large" /></a>
</li>
</ul>
<ul class="list" v-if="index === 1">
<li v-for="(item, index) in goodsList" :key="index">
<a :href="item.url" target="_blank"> <img :src="item.image.small" /></a>
<p>{{item.title}}</p>
</li>
</ul>
</div>
</body>

</html>
<script type="text/javascript">
var vm = new Vue({
el: "#app",
data: {
goodsList: [],
index: 0,
},
mounted() {

axios.get('./goodsList.json')
.then(res => {

this.goodsList = res.data
})
},
});
</script>

08 购物车(20 分)

  • 在线环境 - 蓝桥杯题库2455

  • 考点:Vue 2.xJS 数组 push/splice 方法

  • 可以看到,当前代码中 addToCartremoveGood 方法是不完美的。

    1
    2
    3
    4
    5
    6
    7
    addToCart(goods) {


    goods.num = 1;
    this.cartList.push(goods);
    this.cartList = JSON.parse(JSON.stringify(this.cartList));
    },

    addToCart 中,我们需要先判断购物车列表中有没有该商品,才能选择是 添加该商品 还是 在购物车该商品原数量上加1

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    addToCart(goods) {

    let hasGoods = false;

    this.cartList.forEach(item => {
    if(item.id === goods.id) {
    item.num++
    hasGoods = true;
    }
    });
    if (!hasGoods) {
    goods.num = 1;
    this.cartList.push(goods);
    }

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

    至此,“加入购物车”以及加号按钮功能正常。

  • 但是对于移除购物车函数 removeGoods 来说,就不用判断购物车列表是否有该商品了,因为既然你都可以点击减号按钮了,说明该商品已经在购物车了呀!

    1
    2
    3
    4
    5
    6
    7
    8
    9
    removeGoods(goods) {

    this.cartList.forEach(item => {

    if(item.id === goods.id) {
    item.num--
    }
    })
    }

    现在就实现了点击减号按钮,减少该商品在购物车中的数量了。

  • 但别忘了当数量减少到 0 的时候从购物车移除该商品:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    removeGoods(goods) {

    this.cartList.forEach((item, index) => {

    if(item.id === goods.id) {
    item.num--
    if(item.num <= 0) {
    this.cartList.splice(index, 1)
    }
    }
    })

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

    其中最后一句 this.cartList = JSON.parse(JSON.stringify(this.cartList)); 是对 cartList 进行一次深拷贝,防止干扰之后的一些操作。说实话我没太理解这一步操作,我感觉不进行这次拷贝也能正常工作,感觉这行代码是句废话。

    问了一下 NewBing 是这样回答我的:这行代码的意义是将 this.cartList 对象进行深拷贝,然后将拷贝后的对象重新赋值给 this.cartList 对象。这样做的目的是为了避免直接修改 this.cartList 对象时,对其他引用该对象的变量造成影响。如果不进行深拷贝,直接将 this.cartList 赋值给其他变量,那么修改其中一个变量的值会影响到其他变量的值。所以这行代码并不是多此一举,而是为了保证程序的正确性。

    但是…似乎…这道题中不拷贝也不会有啥影响吧……

完整的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
<!DOCTYPE html>
<html>

<head lang="en">
<meta charset="UTF-8">

<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>购物车</title>
<script src="./js/goods.js"></script>
<script type="text/javascript" src="./js/vue.js"></script>
<link href="./css/index.css" rel="stylesheet" type="text/css" />
</head>

<body>
<div id="app">

<h3>商品列表</h3>
<ul id="goodsList">
<template v-for="goods in goodsList">
<li class="goods-item" :key="goods.id">
<div><img :src="goods.imgUrl" /> </div>
<div>{{goods.name}}</div>
<div>¥ {{goods.price}} </div>
<button @click="addToCart(goods)">加入购物车</button>
</li>
</template>
</ul>

<template v-if="cartList.length>0">
<h3>购物车</h3>
<ul id="cartList">
<template v-for="goods in cartList">
<li class="goods-item" :key="goods.id">
<div><img :src="goods.imgUrl" /> </div>
<div>{{goods.name}}</div>
<div>¥ {{goods.price}} </div>
<div class="item-control">
<button @click="removeGoods(goods)">-</button>
<h4>{{goods.num}}</h4>
<button @click="addToCart(goods)">+</button>
</div>
</li>
</template>
</ul>
</template>
</div>
</body>

</html>

<script>
new Vue({
el: '#app',
data: {
cartList: [],
goodsList: []
},
mounted() {
this.goodsList = GoodsArr;
},
methods: {
addToCart(goods) {

let hasGoods = false;

this.cartList.forEach(item => {
if(item.id === goods.id) {
item.num++
hasGoods = true;
}
});
if (!hasGoods) {
goods.num = 1;
this.cartList.push(goods);
}

this.cartList = JSON.parse(JSON.stringify(this.cartList));
},
removeGoods(goods) {

this.cartList.forEach((item, index) => {

if(item.id === goods.id) {
item.num--
if(item.num <= 0) {
this.cartList.splice(index, 1)
}
}
})

this.cartList = JSON.parse(JSON.stringify(this.cartList));
}
}
});
</script>

09 寻找小狼人(25 分)

根据题目要求,我们需要实现类似数组的 filter 方法, 返回一个都是狼人的新数组:

1
cardList.filter((item) => item.category == "werewolf")

阅读源码我们可知要手写的这个 myarray 方法的调用方式是:

1
2
3
let newcardList = cardList.myarray(
(item) => item.category == "werewolf"
);

因此该方法需要挂载到数组的原型上,文件中已经给我们提供好了,只需完善即可:

1
2
3
4

Array.prototype.myarray = function (cb) {

};

我们需要知道的是,传入的 cb 回调函数的返回值是布尔值,我们需要使用这个函数来过滤数组。此外,还需要知道,在我们要手写的 myarray 这个函数中,this 的值就是调用此函数的那个数组。

本题完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14

Array.prototype.myarray = function (cb) {


let newArr = [];
let arr = this;
for (let i = 0; i < arr.length; i++) {
if (cb(arr[i])) {
newArr.push(arr[i]);
}
}

return newArr;
};

10 课程列表(25 分)

  • 在线环境 - 蓝桥杯题库2457

  • 考点:手写分页组件、axios.slice(0, 5).map().join().toFixed(2)

  • 我们首先实现数据请求,通过总数据计算出总页数,并把总页数和当前页数在前端页面显示出来:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    let pageNum = 1; 
    let maxPage;




    function showPagination(maxPage, pageNum) {
    document.querySelector('#pagination').innerHTML = `共${maxPage}页,当前${pageNum}页`
    }


    let data;
    let pageData;
    axios.get('./js/carlist.json')
    .then(res => {

    data = res.data
    maxPage = Math.ceil(data.length / 5)

    showPagination(maxPage, pageNum);
    })
  • 根据当前页数从总数据中获取当页数据,并渲染在页面上 :

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    let pageNum = 1; 
    let maxPage;




    function showPagination(maxPage, pageNum) {
    document.querySelector('#pagination').innerHTML = `共${maxPage}页,当前${pageNum}页`
    }


    function getPageData(data) {
    return data.slice((pageNum - 1) * 5, pageNum * 5)
    }


    function renderHTML(pageData) {
    document.querySelector('#list').innerHTML = pageData.map(item => `
    <div class="list-group">
    <a href="#" class="list-group-item list-group-item-action">
    <div class="d-flex w-100 justify-content-between">
    <h5 class="mb-1">${item.name}</h5>
    <small>${(item.price / 100).toFixed(2)}元</small>
    </div>
    <p class="mb-1">
    ${item.description}
    </p>
    </a>
    </div>
    `).join();
    }

    // 数据请求
    let data; // 总数据
    let pageData; // 每页数据
    axios.get('./js/carlist.json')
    .then(res => {
    // console.log(res)
    data = res.data
    maxPage = Math.ceil(data.length / 5)
    // 显示当前页码
    showPagination(maxPage, pageNum);
    // 获得每页数据
    pageData = getPageData(data);
    // 渲染每页数据
    renderHTML(pageData);
    })
  • 然后是实现翻页按钮功能,注意要做边界控制:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38

    let prev = document.getElementById("prev");
    prev.onclick = function () {

    next.classList.remove('disabled')
    pageNum--
    console.log(pageNum)
    if (pageNum <= 1) {
    this.classList.add('disabled')
    pageNum = 1
    }


    showPagination(maxPage, pageNum);

    pageData = getPageData(data);

    renderHTML(pageData);
    };

    let next = document.getElementById("next");
    next.onclick = function () {

    prev.classList.remove('disabled')
    pageNum++
    console.log(pageNum)
    if (pageNum >= maxPage) {
    this.classList.add('disabled')
    pageNum = maxPage
    }


    showPagination(maxPage, pageNum);

    pageData = getPageData(data);

    renderHTML(pageData);
    };