fetchApi === 入门篇

devtools/2024/9/20 9:18:58/ 标签: okhttp

目录

fetch 基本认知

fetch 如何使用

Response对象(了解)

常见属性

常见方法

fetch 配置参数

fetch发送post请求

fetch 函数封装

fetch 实战 - 图书管理案例

渲染功能

添加功能

删除数据

完整代码


fetch 基本认知

思考: 以前开发中如何向服务器请求数据的?

  • 方法一:通过 Ajax 向服务器请求数据,而 Ajax 本质就是使用 XMLHttpRequest 对象实现的

    可以实现,但是代码写起来很麻烦
// 1、创建一个xhr对象
let xhr = new XMLHttpRequest()
// 2、设置请求方式和请求地址
xhr.open('get', 'http://ajax-base-api-t.itheima.net/api/getbooks?name=zs&age=18')
// 3、发送请求
xhr.send()
// 4.监听load事件获取响应结果
xhr.addEventListener('load', function () {console.log(JSON.parse(xhr.response))
})

  • 方法二:通过 axios 实现的代码精简不少,但是axios底层仍然是基于 XMLHttpRequest 对象实现的,本质不变,只是进行了 promise 封装

那么目前除了使用 XMLHttpRequest 发送请求之外,还有没有其他方式呢?

  • 有,就是fetch

什么是fetch?

  • Fetch 被称之为下一代 Ajax 技术,内部采用 Promise 方式来处理数据

    可以直接.then即可

  • API语法简洁明了,比 XMLHttpRequest 更加简单易用

  • 采用了模块化设计,API分散于多个对象中(如:Response对象、Request对象、Header对象)

  • 通过数据流(Stream对象)处理数据,可以分块读取,有利于提高网站性能,对于大文件或者网速慢的场景极为有用

兼容性:浏览器支持程度如何?

  • 最新统计(下图所示):fetch 可以支持到 96.83% 的用户端,除了IE,主流浏览器 都已兼容
  • 注意点:不兼容IE

fetch 如何使用

【博客文档推荐】

  • https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch
  • https://www.ruanyifeng.com/blog/2020/12/fetch-tutorial.html

使用fetch发送基本get请求

介绍:

  • 如果fetch() 只接收了一个 url字符串 参数,表示默认向该网址发送 get 请求,会返回一个Promise对象
  • 如果需要设置get的参数,直接拼接到 url 地址上即可

语法:

fetch(url).then(...).catch(...)

ヾ(๑╹◡╹)ノ" 01-fetch发送基本的get请求

// 接口地址:http://ajax-base-api-t.itheima.net/api/getbooks
// 请求方式:get
// 查询参数(可选):
//   1、id:需要查询的图书idfetch('http://ajax-base-api-t.itheima.net/api/getbooks').then(res => {// 得到的res,是一个Response对象,需要通过特定方法获取其中内容// console.log(res)// res.json() 是一个异步操作,表示取出所有的内容,将其转换成JSON对象console.log(res.json())return res.json()
}).then(json => {// 获取经过res.json() 处理过之后的数据——》正常通过ajax获取的数据console.log(json)
}).catch(err => {console.log(err)
})

 ヾ(๑╹◡╹)ノ" 02-fetch发送get请求-使用async-await改写

// 接口地址:http://ajax-base-api-t.itheima.net/api/getbooks
// 请求方式:get
// 查询参数(可选):
//   1、id:需要查询的图书id// 1、把代码封装成async异步函数
async function getData() {// 通过try...catch语法处理async-await成功和失败的情况try {// 先获取Response对象let res = await fetch('http://ajax-base-api-t.itheima.net/api/getbooks')console.log(res)// 通过res.json() 取出response对象中的数据let json = await res.json()console.log(json)} catch (err) {// 捕获错误信息console.log(err)}
}
getData()

ヾ(๑╹◡╹)ノ" 03-fetch发送get请求-使用async-await改写-添加查询参数

// 2、如果需要通过get请求设置查询参数如何实现?
//    可以通过地址栏拼接查询参数完成
async function getData1() {// 通过try...catch语法处理async-await成功和失败的情况try {// 先获取Response对象let res = await fetch('http://ajax-base-api-t.itheima.net/api/getbooks?id=1')console.log(res)// 通过res.json() 取出response对象中的数据let json = await res.json()console.log(json)} catch (err) {// 捕获错误信息console.log(err)}
}
getData1()

Response对象(了解)

fetch 请求成功以后,得到的是一个 Response 对象。它是对应服务器的 HTTP 响应。

const res = await fetch(url)
console.log(res)

常见属性

属性含义
res.ok返回一个布尔类型,表示请求是否成功
res.status返回一个数字,表示HTTP回应的状态码(例如:200,表示以请求成功)
res.statusText返回状态的文本信息(例如:请求成功之后,服务器返回ok)
res.url返回请求的url地址

 

常见方法

Response 对象根据服务器返回的不同类型的数据,提供了不同的读取方法。

其中最常用的就是 res.json()

方法含义
res.json()得到 JSON 对象
res.text()得到文本字符串
res.blob()得到二进制 Blob 对象
res.formData()得到 FormData 表单对象
res.arrayBuffer()得到二进制 ArrayBuffer 对象

fetch 配置参数

fetch的第一个参数是 url ,此外还可以接收第二个参数,作为配置对象,可以自定义发出的HTTP请求

比如:fetch(url,options)

其中:post、put、patch 用法类似,咱们这边以post为例演示

配置参数介绍:

fetch(url,{method:'请求方式,比如:post、delete、put',headers:{'Content-Type':'数据格式'},body:'post请求体数据'
})

fetch发送post请求

咱们这边以开发中用的较多的JSON格式的情况为例

**基本语法1:**json格式(常用)

// 测试接口(新增操作):
// 接口地址:http://ajax-base-api-t.itheima.net/api/addbook
// 请求方式:post
// 请求体参数:
//  1、书名:bookname
//  2、作者:author
//  3、出版社:publisher// post发送:json格式
async function add() {let obj = {bookname: '魔法书之如何快速学好前端',author: '茵蒂克丝',publisher: '格兰芬多'}let res = await fetch('http://ajax-base-api-t.itheima.net/api/addbook', {method: 'post',headers: {'Content-Type': 'application/json'},body: JSON.stringify(obj)})let json = await res.json()console.log(json)
}
add()

 基本语法2: x-www-form-urlencoded格式(了解)

async function add1() {let res = await fetch(url, {method: 'post',headers: {"Content-type": "application/x-www-form-urlencoded; charset=UTF-8",},body: 'foo=bar&lorem=ipsum',});let json = await res.json();console.log(json)
}
add1()

**基本语法3:**formData格式(了解)

let form = document.querySelector('form');async function add2() {let res = await fetch(url, {method: 'POST',body: new FormData(form)})let json = await res.json()console.log(json)
}
add2()

fetch 函数封装

原生fetch虽然已经支持 promise 了,相比 XMLHttpRequest 已然好用了很多,但是参数还是需要自己处理,比较麻烦

比如:

  • get delete 的请求参数,要在地址栏拼接
  • put patch post 的请求参数,要转 json 设置请求头

所以实际工作,我们还是会对 fetch 二次封装

目标效果:

// 发送get请求、delete请求
http({method:'xxx'url:'xxx',params:{......}})// 发送post请求、put请求、patch请求
http({method:'xxx'url:'xxx',data:{......}})

封装之后代码如下:

async function http(obj) {// 解构赋值let { method, url, params, data } = obj// 判断是否有params参数// 1、如果有params参数,则把params对象转换成 key=value&key=value的形式,并且拼接到url之后// 2、如果没有params参数,则不管if (params) {// 把对象转换成 key=value&key=value 的方法// 固定写法:new URLSearchParams(obj).toString()let str = new URLSearchParams(params).toString()// console.log(str)// 拼接到url上url += '?' + str}// 最终的结果let res// 判断是否有data参数,如果有,则需要设置给body,否则不需要设置console.log(data)if (data) {// 如果有data参数,此时直接设置res = await fetch(url, {method: method,headers: {'Content-Type': 'application/json'},body: JSON.stringify(data)})} else {res = await fetch(url)}return res.json()
}// 测试代码1:
// 请求方式:get
// 接口地址:http://ajax-base-api-t.itheima.net/api/getbooks
// 查询参数(可选):
//   1、id:需要查询的图书idasync function fn1() {let result1 = await http({method: 'get',url: 'http://ajax-base-api-t.itheima.net/api/getbooks',params: {id: 1}})console.log(result1)
}
fn1()// 测试代码2:
// 请求方式:post
// 接口地址:http://ajax-base-api-t.itheima.net/api/addbook
// 请求体参数:
//  1、书名:bookname
//  2、作者:author
//  3、出版社:publisher
async function fn2() {let result2 = await http({method: 'post',url: 'http://ajax-base-api-t.itheima.net/api/addbook',data: {bookname: '魔法书111',author: '嘻嘻',publisher: '哈哈哈'}})console.log(result2)
}
fn2()

fetch 实战 - 图书管理案例

获取所有图书:1、接口地址:http://ajax-base-api-t.itheima.net/api/getbooks2、请求方式:get添加图书:1、接口地址:http://ajax-base-api-t.itheima.net/api/addbook2、请求方式:post3、请求体参数:1、bookname:图书的名称2、author:作者3、publisher:出版社删除图书:1、接口地址:http://ajax-base-api-t.itheima.net/api/delbook2、请求方式:delete3、查询参数:1、id:需要删除图片的id

 

渲染功能

步骤:

  1. 把渲染的代码封装成函数
  2. 通过封装好的http函数,获取所有图书数据
  3. 遍历返回的图书数组,每遍历一项,就创建一个tr出来,拼接成完整字符串再一起添加到tbody中去
// 把渲染的代码封装成函数async function render() {// 获取数据let res = await http({method: 'get',url: 'http://ajax-base-api-t.itheima.net/api/getbooks',})console.log(res.data)let htmlStr = ''// 遍历数组,每遍历一项,就创建一个tr出来,拼接成完整字符串再一起添加到tbody中去res.data.forEach(item => {// console.log(item)htmlStr += `<tr><th scope="row">${item.id}</th><td>${item.bookname}</td><td>${item.author}</td><td>${item.publisher}</td><td><button type="button" class="btn btn-link btn-sm">删除</button></td></tr>`})// console.log(htmlStr)// 把拼接好的数据,设置到tbody中去tbody.innerHTML = htmlStr}
添加功能

步骤:

  1. 给form注册submit事件
  2. 阻止浏览器默认行为(提交的默认跳转功能)
  3. 通过serialize插件获取表单数据
  4. 通过封装好的http函数发送数据给服务器
  5. 判断res的status是否成功
    1. 如果成功,此时重新渲染,并且重置表单
    2. 如果不成功,弹框提示错误信息即可
// 表单提交功能
form.addEventListener('submit', async function (e) {//  阻止浏览器默认行为e.preventDefault()// 获取表单数据——》通过serialize插件获取let result = serialize(form, { hash: true })console.log(result)// 把获取的表单数据,发送给服务器let res = await http({method: 'post',url: 'http://ajax-base-api-t.itheima.net/api/addbook',data: result})console.log(res)// 通过res的status判断是否添加成功if (res.status === 201) {// 重新渲染render()// 重置表单form.reset()} else {// 如果不成功,弹框提示错误信息即可alert(res.msg)}})
删除数据

步骤:

  1. 利用事件委托,给tbody注册点击事件
  2. 判断e.target.tagName是不是按钮
  3. 如果是按钮,则通过封装好的http函数发送请求删除数据
  4. 此时需要知道删除的这一项的id,则再渲染button时就可以把id添加到dom结构上
  5. 判断是否删除成功,如果删除成功,则需要重新加载
// 删除功能——》利用事件委托
tbody.addEventListener('click', async function (e) {//  console.log(e.target.tagName)// 判断如果点击的是按钮,才进行删除if (e.target.tagName === 'BUTTON') {let res = await http({method: 'delete',url: 'http://ajax-base-api-t.itheima.net/api/delbook',params: {id: e.target.dataset.id}})// console.log(res)// 判断如果删除成功,此时需要重新加载if (res.status === 200) {render()}}
})
完整代码
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<style>/* 基本的页面样式 */body {font-family: 'Arial', sans-serif;padding: 20px;background-color: #f4f4f4;}/* 表格的样式 */#tbody {width: 100%;border-collapse: collapse;margin-top: 20px;}#tbody th,#tbody td {border: 1px solid #ddd;padding: 8px;text-align: left;}#tbody th {background-color: #4CAF50;color: white;}/* 鼠标悬停效果 */#tbody tr:hover {background-color: #f5f5f5;}/* 按钮样式 */.btn-link {color: #337ab7;text-decoration: none;padding: 5px 10px;border: none;background: none;outline: none;}.btn-link:hover {text-decoration: underline;}/* 小型按钮 */.btn-sm {font-size: 12px;}/* 删除按钮样式 */.delete-btn {color: #a94442;}.delete-btn:hover {color: #843534;}/* 响应式设计 */@media (max-width: 768px) {body {padding: 10px;}#tbody th,#tbody td {padding: 5px;}}/* 优化表格结构 */#thead,#tfoot {display: table-header-group;}#tfoot {font-weight: bold;}/* 动画效果 */.btn-link:hover {transition: color 0.3s ease;text-decoration: underline;}/* 按钮交互性 */.btn-link:focus,.btn-link:active {outline: none;box-shadow: 0 0 0 2px rgba(51, 122, 183, 0.5);}/* 辅助类 */.text-center {text-align: center;}.mt {margin-top: 20px;}/* 表格内边距调整 */#tbody th,#tbody td {padding: 15px;}/* 删除按钮样式增强 */.delete-btn {cursor: pointer;}.delete-btn:hover {transition: color 0.3s ease;}.book-form {max-width: 400px;margin: 20px auto;padding: 20px;background: #fff;border-radius: 8px;box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);}.book-form h2 {text-align: center;margin-bottom: 20px;}.form-group {margin-bottom: 15px;}.form-group label {display: block;margin-bottom: 5px;}.form-group input {width: 100%;padding: 10px;border: 1px solid #ddd;border-radius: 4px;box-sizing: border-box;/* 确保padding不会增加宽度 */}.btn-primary {background-color: #4CAF50;color: white;border: none;padding: 10px 20px;cursor: pointer;border-radius: 4px;transition: background-color 0.3s ease;}.btn-primary:hover {background-color: #45a049;}/* 响应式设计 */@media (max-width: 600px) {.book-form {width: 90%;padding: 10px;}}
</style><body><div class="Z"><table id="table" class="table"><thead id="thead"><tr><th>ID</th><th>书名</th><th>作者</th><th>出版社</th><th>操作</th></tr></thead><tbody id="tbody"><!-- 动态生成的表格行将放在这里 --></tbody><tfoot id="tfoot"><tr><td colspan="5">版权所有 © 2024 月之暗面科技有限公司</td></tr></tfoot></table><form id="form" class="book-form"><h2>新增书籍</h2><div class="form-group"><label for="bookName">书名:</label><input type="text" id="bookName" name="bookname" required></div><div class="form-group"><label for="author">作者:</label><input type="text" id="author" name="author" required></div><div class="form-group"><label for="publisher">出版社:</label><input type="text" id="publisher" name="publisher" required></div><button type="submit" class="btn btn-primary">提交</button></form></div>
</body></html>
<script src="./index.js"></script>
<script>async function http(obj) {// 解构赋值let { method, url, params, data } = obj// 判断是否有params参数// 1、如果有params参数,则把params对象转换成 key=value&key=value的形式,并且拼接到url之后// 2、如果没有params参数,则不管if (params) {// 把对象转换成 key=value&key=value 的方法// 固定写法:new URLSearchParams(obj).toString()let str = new URLSearchParams(params).toString()// console.log(str)// 拼接到url上url += '?' + str}// 最终的结果let res// 判断是否有data参数,如果有,则需要设置给body,否则不需要设置console.log(data)if (data) {// 如果有data参数,此时直接设置res = await fetch(url, {method: method,headers: {'Content-Type': 'application/json'},body: JSON.stringify(data)})} else {res = await fetch(url)}return res.json()}// 把渲染的代码封装成函数async function render() {// 获取数据let res = await http({method: 'get',url: 'http://ajax-base-api-t.itheima.net/api/getbooks',})console.log(res.data)let htmlStr = ''// 遍历数组,每遍历一项,就创建一个tr出来,拼接成完整字符串再一起添加到tbody中去res.data.forEach(item => {// console.log(item)htmlStr += `<tr><th scope="row">${item.id}</th><td>${item.bookname}</td><td>${item.author}</td><td>${item.publisher}</td><td><button type="button" class="btn btn-link btn-sm" data-id=${item.id}>删除</button></td></tr>`})// console.log(htmlStr)// 把拼接好的数据,设置到tbody中去tbody.innerHTML = htmlStr}render()// 表单提交功能form.addEventListener('submit', async function (e) {//  阻止浏览器默认行为e.preventDefault()// 获取表单数据——》通过serialize插件获取let result = serialize(form, { hash: true })console.log(result)// 把获取的表单数据,发送给服务器let res = await http({method: 'post',url: 'http://ajax-base-api-t.itheima.net/api/addbook',data: result})console.log(res)// 通过res的status判断是否添加成功if (res.status === 201) {// 重新渲染render()// 重置表单form.reset()} else {// 如果不成功,弹框提示错误信息即可alert(res.msg)}})// 删除功能——》利用事件委托tbody.addEventListener('click', async function (e) {//  console.log(e.target.tagName)// 判断如果点击的是按钮,才进行删除if (e.target.tagName === 'BUTTON') {try {let res = await http({method: 'delete',url: 'http://ajax-base-api-t.itheima.net/api/delbook',params: {id: e.target.dataset.id}})// console.log(res)// 判断如果删除成功,此时需要重新加载if (res.status === 200) {render()}} catch (error) {console.log(error);}}})</script>


http://www.ppmy.cn/devtools/84990.html

相关文章

【文化+科技,融合示范】探索数字媒体产业园区如何重塑行业格局,打造全球领先的数字内容生态圈

数字媒体产业园区作为数字经济的重要组成部分&#xff0c;正以其独特的魅力和创新力重塑行业格局&#xff0c;努力打造全球领先的数字内容生态圈。这一过程中&#xff0c;树莓集团正通过集聚优质资源、搭建创新平台、推动产业升级&#xff0c;为数字内容产业的发展提供了强有力…

将git默认的编辑器设置为vin

git默认编辑器现状 如下&#xff0c;很多linux发行版&#xff0c;未加修改的情况下&#xff0c;git的默认编辑器使用起来不太方便 Signed-off-by: root <rootxxx.COM># Please enter the commit message for your changes. Lines starting # with # will be ignored, a…

MongoDB教程(二十三):关于MongoDB自增机制

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; 文章目录 引言一、MongoD…

[前端]解决Iframe即使设置高度100%,但还是显示滚动条scrollbar的问题

前言 好烦,你看看这两个重复的滚动条. 一个是来自iframe,另一个来自父级的div(overflow: auto;) 我已经在css中设置了iframe的height: 100%;border: none;,但无论如何还是显示出了父级的scrollbar 解决 将iframe的display: block;即可. 或者vertical-align: bottom;

HarmonyOS和OpenHarmony区别联系

前言 相信我们在刚开始接触鸿蒙开发的时候经常看到HarmonyOS和OpenHarmony频繁的出现在文章和文档之中&#xff0c;那么这两个名词分别是什么意思&#xff0c;他们之间又有什么联系呢&#xff1f;本文将通过现有的文章和网站内容并与Google的AOSP和Android做对比&#xff0c;带…

【NoSQL数据库】Redis知识小册

一、缓存穿透 缓存穿透是先查Redis&#xff0c;发现缓存中没有数据&#xff0c;再查数据库。然而&#xff0c;如果查询的数据在数据库中也不存在&#xff0c;那么每次查询都会绕过缓存&#xff0c;直接落到数据库上。 解决方案一、缓存空数据 查询Redis缓存&#xff1a;首先查…

学习大数据DAY22 Linux 基 本 指 令 3与 在 Linux 系 统 中 配 置MySQL 和 Oracle

目录 网络配置类 ps 显示系统执行的进程 kill systemctl 服务管理 配置静态 ip 常见错误---虚拟机重启网卡失败或者网卡丢失 mysql 操作 上机练习 6---安装 mysql---参考《mysql 安装》文档 解锁 scott 重启后的步骤 上机练习 7---安装 oracle---参考《oracle 安装》…

Nexus3 批量上传 jar 包、pom文件

Nexus3 Maven 私服搭建及各种使用 详见**Maven私服搭建及各种使用汇总2020** Maven 配置 Nexus 私服 在 Maven 项目中配置 Nexus 私服&#xff0c;需要在项目的 pom.xml 或 maven 的 settings.xml 文件中添加 Nexus 仓库的配置。 示例&#xff1a; 以下是一个项目的 pom.xml…

基于微信小程序+SpringBoot+Vue的资料分享系统(带1w+文档)

基于微信小程序SpringBootVue的资料分享系统(带1w文档) 基于微信小程序SpringBootVue的资料分享系统(带1w文档) 校园资料分享微信小程序可以实现论坛管理&#xff0c;教师管理&#xff0c;公告信息管理&#xff0c;文件信息管理&#xff0c;文件收藏管理等功能。该系统采用了Sp…

Android笔试面试题AI答之控件Views(3)

答案仅供参考&#xff0c;来自文心一言 目录 1.如何在ListView间添加分割线?方法1&#xff1a;在XML布局文件中设置方法2&#xff1a;在Java代码中设置注意事项 2.如何实现ListView的逐行显示?1. 使用 Handler 和 postDelayed() 方法2. 监听滚动事件3. 自定义Adapter4. 使用…

vscode 搭建 golang 开发环境

介绍 在 vscode 搭建 go 的开发环境需要区分两个方向&#xff1a; go 1.19.0 及其更高版本go 1.19.0 之前的版本 为什么这么分&#xff0c;因为 vscode-go 插件自带的工具安装脚本全部都是装最新版的各类工具&#xff0c;这些工具中有部分要求 go 1.19.0 以上才能安装成功。…

机器学习 | 回归算法原理——最小二乘法

Hi&#xff0c;大家好&#xff0c;我是半亩花海。很早便想学习并总结一本很喜欢的机器学习图书——立石贤吾的《白话机器学习的数学》&#xff0c;可谓通俗易懂&#xff0c;清晰形象。那就在此分享并作为学习笔记来记录我的学习过程吧&#xff01;本章的回归算法原理基于《基于…

Linux stty echo 控制回显

在 Linux 系统中&#xff0c;可以通过 stty 命令修改终端的 ECHO 模式。ECHO 模式决定了终端是否回显用户的输入。以下是如何使用 stty 命令来修改 ECHO 模式的方法&#xff1a; 禁用 ECHO 模式 要禁用 ECHO 模式&#xff0c;可以使用以下命令&#xff1a; tty -echo 这条命…

spring —— IoC容器(二)

二、基于注解管理 bean &#xff08;一&#xff09;Autowired 自动装配 &#xff08;1&#xff09;属性上自动装配 package com.fourth.anno;import org.springframework.stereotype.Component;Component public class Dao {public void runDao(){System.out.println("…

Python基础学习笔记

Python是编译一行运行一行,每行结束后面不需要加";"表示结束 表示一个数的次方时用两个"**",比如2的平方: 2**2 用#开头表示单行注释, 用三引号""" """来表示多行注释 字符串可以被双引号或单引号包裹 用print打印时pr…

Http 和 Https 的区别(图文详解)

在现代网络通信中&#xff0c;保护数据的安全性和用户的隐私是至关重要的。HTTP&#xff08;Hypertext Transfer Protocol&#xff09;和 HTTPS&#xff08;Hypertext Transfer Protocol Secure&#xff09;是两种常见的网络通信协议&#xff0c;但它们在数据保护方面的能力存在…

linux集群架构--高可用--keepalived(13985字详解)

linux架构高可用 a.概述 高可用&#xff1a;HA HighAvailablity —>Keepalived生成VIP&#xff0c;DNS解析到这个IP地址即可 b.原理 keepalived 是基于VRRP协议实现高可用VRRP虚拟路由器冗余协议&#xff0c;最开始是给网络设备实现高可用&#xff0c;目前keepalive实现v…

JavaScript——对象、数组、函数、类、事件

文章目录 序言对象数组函数类事件鼠标点击鼠标双击菜单鼠标按下键盘表单窗口 结语 序言 『不是为了战斗而活着&#xff0c;而是为了活着而战斗。』—— 「《DARLING in the FRANXX》」 对象 数组&#xff0c;函数&#xff0c;类&#xff0c;都算是对象 let person {name: &…

SpringBoot中如何使用RabbitMq

一&#xff0c;RabbitMQ简介和基本概念 RabbitMQ 是一个开源的消息中间件&#xff0c;基于 AMQP&#xff08;高级消息队列协议&#xff09;实现。 它由 Erlang 语言开发&#xff0c;并且支持多种编程语言&#xff0c;包括 Java、Python、Ruby、PHP 和 C# 等&#xff0c; 下载…