[微信小程序] 入门笔记2-自定义一个显示组件
[微信小程序] 入门笔记2-自定义一个显示组件
0. 准备工程
- 新建一个工程,删除清空app的内容和其余文件夹.然后自己新建
pages
和components
创建1个空组件和1个空页面.
- 设定
view
组件的默认样式,使其自动居中靠上,符合习惯.在app.wxss
内定义,作用做个工程.
/**app.wxss**/
/* 所有 view 容器, 默认, 从左到右从上到下, 完完全全居中对齐 */
view {/* 弹性盒子布局 */display: flex;/* 决定主轴的方向 即项目的排列方向: 主轴为水平方向,起点在左端 */flex-direction: row;/* 定义项目是否换行以及如何换行: 换行,第一行在上方 */flex-wrap: wrap;/* 定义项目在主轴上的对齐方式: 居中 */justify-content: center;/* 定义项目在竖直方向上对齐方式: 交叉轴的中点对齐 */align-items: center;/* 定义多根轴线的对齐方式: 与交叉轴的中点对齐 */align-content: center;
}
1.调用组件
- 在
page1.json
文件中导入组件.
- 在
page1.wxml
中调用组件.
- 将内容放在
view
内,自动居中对齐,上一步修改view
样式起的作用.如果之后需要修改特定的view
样式,再加个类名限定即可.
2.设定组件内容和属性
- 组件脚本
js
的所有内容都需要写在component({...})
内, 然后属性需要写在其中的properties:{}
内. 值得注意的是,属性的定义必须标明类型!!!采样以下固定的形式,必须包含type
和value
2个内容.算是定义了一个对象,然后数据存在该对象的value
属性内容.
properties: {temp: {type: String,value: '666',},},
- 主要是定义一些样式, 还有需要显示的数据数组.
/*** 组件的属性列表*/properties: {/* 字体大小 rpx */css_font_size: {type: String,value: "30",},/* 单个数据框高度 vh */css_item_height: {type: String,value: "5",},/* 名称框的占比宽度 rpx */css_name_width: {type: String,value: "150",},/* 冒号的占比宽度 rpx */css_colon_width: {type: String,value: "40",},/* 数据的占比宽度 rpx */css_val_width: {type: String,value: "80",},/* 数据数组, 3个元素分别: 名称, 内容, 是否输入 */data_array: {type: Array,value: [{str_name: '只输出',str_data: '0',isOutputOnly: true,}, {str_name: '可输入',str_data: '0',isOutputOnly: false,}, ],},},
- 然后在
.wxml
文件内放置内容,wxml
内的{{}}
可以直接访问到js
脚本内的属性properties
和数据data
内容!!!data
内数据定义就无需非要指定类型.但是只有属性properties
能接收外部传入值,所以一般data
是处理内部数据使用. - 循环列表渲染,
wx:for
就不过多解释了.
<view class="showData-container" style="font-size:{{css_font_size}}rpx;"> <view class="showData-item" wx:for="{{data_array}}" wx:key="index"> <view style="height:{{css_item_height}}vh;width:{{css_name_width}}rpx;" >{{item.str_name}}</view> <view style="height:{{css_item_height}}vh;width:{{css_colon_width}}rpx;">{{":"}}</view> <view style="height:{{css_item_height}}vh;width:{{css_val_width}}rpx;">{{item.str_data}}</view> </view>
</view>
- 然后打开
可视化
功能,可以单独调试组件的内容.然后结合调试器
.轻松调试.可以看到组件实际渲染效果,rpx
单位会被自动转换成px
单位.更改屏幕大小可以发现等比例相对变化.
3.传入数组
- 在页面
page.js
创建数组;
/* 数据显示数组 */data_array: [{str_name: '读取',str_data: '5.89',isOutputOnly: true,}, {str_name: '写入',str_data: '0.985',isOutputOnly: false,}, ],
- 在
page1.wxml
内传入数组,同时可以修改一下样式,看看效果.不写的话就算保持组件内设定的默认值.
4.动态修改数组
- 在页面内修改了数组
data_array
,是可以同步影响到组件内的显示的. - 添加一个按钮,用于修改数据,可以在
可视化
界面内快速添加.长按拖拽, 或是先选择view
,然后双击添加. - 添加之后,拖拽组件可以修改位子,
ide
会自动 添加绝对位置的样式属性.不推荐这样设置.
- 为按钮添加属性
bind:tap
指定点击时的回调函数.
<button bind:tap="button0_tap">按钮</button>
4.5.bind
- 这是重中之重的要点!!! 第一次接触小程序,看到这个用法属实头蒙.
- 许多功能回调,或是特殊语法,都使用了
bind
前缀命名.在旧版语法中是没有冒号:
做分隔的.新版中支持使用冒号:
分隔,使得可读性提高.看例程时可能看到有些又冒号,有些没用,不要困惑,其实指的是同一个意思. - 然后
bind:tap
不是按钮的专属属性,是所有组件都可以添加的一个属性,意义是在点击时调用指定函数.所以将按钮改为view
或text
,是一样的效果.
<text bind:tap="button0_tap">pages/page1/page1.wxml\n</text>
- 然后在脚本
page1.js
内定义回调函数.
/* 按钮回调,修改显示数组 */button0_tap(e) { // button0_tap: (e) => { // 错误的,这样函数内的 this 可能就没有了console.log(e); // 定义看看传入的对象是什么, 可以在调试窗口查看console.log(this); // 定义在调试仓库查看, 如果使用箭头函数, 这里打印为未定义let temp_array = this.data.data_array; // 数据不能直接修改,先取出来,实际上对象是引用而非拷贝,所以只是换个短一点的名字temp_array[0].str_data = Number((Number(temp_array[0].str_data) + 0.5).toFixed(3)) // 修改数据temp_array[1].str_data = Number((Number(temp_array[1].str_data) - 0.5).toFixed(3))temp_array.push(temp_array[0]); // 添加temp_array.push(temp_array[1]); // this.setData({ // 直接修改 this.data 不会起效果,需要使用 setData 修改data_array: temp_array,})},
- 注意,数据中使用了字符串的形式,因为使用数字
num
形式在表示浮点数时会出现无尽小数的情况.为了避免这一问题,我直接采用字符串的形式. - 注意,不可以使用箭头函数定义,因为想要访问
this
内容,可以使用console
打印出来看看,可以详细查看对象内容.而不是控制台那种几个简单的字符.还能定位打印的位置,点击定位会跳转到sources
的page1.js?[sm]
文件窗口,这是一个调试界面,你可以在界面进行卡断点
,单步调试
,查看变量
等操作.非常方便.也可以使用快捷键Ctrl+P
查找指定的.js?[sm]
文件进行断点调试.
- 通过点击组件调用回调函数,修改了数组内容,自定义组件内的数据也同步变化了.也就是达到了从页面传入动态数据到组件了.组件的样式属性也可以类似的操作.
5.传出数据
- 为组件添加
input
组件,允许写入内容.替换原本的纯文本显示.注意到,回调函数使用bind:blur
指定,改属性代表失去焦点时调用.disabled
代表是否禁用.如果只输出显示数据就禁用.value
指定当前值,该数值也会传入回调函数中.另外还需要更多数据一同被传入回调函数,需要自己定义,使用data-名字="{{数据}}"
,的形式.
<view style="height:{{css_item_height}}vh;width:{{css_val_width}}rpx;"><input disabled="{{item.isOutputOnly}}" value="{{item.str_data}}" data-index="{{index}}" data-name="{{item.str_name}}" bind:blur="input0_blur" /></view>
- 然后在脚本
component1.js
中添加回调函数;记得组件的方法,需要写在methods:{...}
内. - 注意,
value
存放在e.detail
中,这是自带的返回数据,而自定义的数据index
和name
是存放在e.currentTarget.dataset
中,切记区分.最后通过this.triggerEvent
,将数据传给指定的回调函数. - 注意,不要使用箭头函数,不然this会丢失,无法指定回调函数.可以使用
input0_blur: function (e) {
的形式.
/*** 组件的方法列表*/methods: {/* 输入回调函数 */input0_blur(e) { // input0_blur: function (e) { // input0_blur: (e) => { console.log(e); // 定义看看传入的对象是什么, 可以在调试窗口查看console.log(this); // 定义在调试仓库查看, 如果使用箭头函数, 这里打印为未定义const value = e.detail.value; // input 只传入了这一个值const index = e.currentTarget.dataset.index; // 这2个是扩展的值const name = e.currentTarget.dataset.str_name; // 这2个是扩展的值this.triggerEvent('input1_blur', { // 调用外部回调函数, 指定函数名,与传出去的数据包value,index,name,});},}
- 这时点击模拟窗口,就可以看到效果.打印的
e
能看到数据存放的位置.e
是Event
的缩写.可以以此代表该函数是回调函数,提高代码阅读性.
- 修改
page1.wxml
,添加指定的回调函数.注意,使用了bind
关键字,另外,我故意使用不同的函数名,代表他们之间的引用关系.
<component1css_font_size="30"css_name_width="100"css_val_width="80"css_item_height="5"bind:input1_blur="input2_blur"data_array="{{data_array}}"> </component1>
- 在
page1.js
中添加回调函数;注意到,这次3个变量数据value
,index
,name
.都在e.detail
内,因为人为指定了3个.
/* 接收数据回调 */input2_blur(e) {console.log(e); // 定义看看传入的对象是什么, 可以在调试窗口查看console.log(this); // 定义在调试仓库查看, 如果使用箭头函数, 这里打印为未定义let temp_array = this.data.data_array; // 数据不能直接修改,先取出来,实际上对象是引用而非拷贝,所以只是换个短一点的名字const value = e.detail.value; // input 只传入了这一个值const index = e.detail.index; // 这2个是扩展的值const name = e.detail.name; // 这2个是扩展的值if (name == temp_array[index].str_name) // 保护措施, 使用索引寻找定位, 判断是否定位正确temp_array[index].str_data = value; // 符合就将数据修改了temp_array[0].str_data = temp_array[1].str_data; // 这里做点修改,体现在界面上方便才看this.setData({ // 直接修改 this.data 不会起效果,需要使用 setData 修改data_array: temp_array,})},
- 现在就可以模拟调试看看效果,我就不再截图了.
现在可能还有个问题,每写一个这种组件,如果要接收其返回的数据,都要定义一个回调函数.好像用qt时也差不多,就这样吧.
6.组件样式
- 最后一步是修改样式, 白底黑字太难看.没有框框也没有边界感,而且无法区分输入和输出的样式.
- 对于输入框,添加了样式判断,在
{{}}
中使用经典的三目运算符,选择不同字符串,也就是不同样式名.也可以使用wx:if
判断使用不同组件达到同样效果;
<!--components/component1/component1.wxml-->
<!-- 删去,有错误,修正后的放下面 -->
- 样式具体建议去看看美化网站提供的例子 https://uiverse.io
- 值得说明的是,虽然我在开始的
app.wxss
指定了view
组件的默认样式,但是我在自定义组件内又重新设定一遍,为了方便移植.
/* components/component1/component1.wxss */
/* 删去,有错误,修正后的放下面 */
- 至此算是基本具备一个基础组件的使用.
7.样式警告
- 我发现上面的写法会给出一个样式警告,如下.因此还是修改
app.wxss
的全局组件名样式,修改为类名样式(或直接删去).然后全部页面和组件都使用类名样式.
Some selectors are not allowed in component wxss, including tag name selectors, ID selectors, and attribute selectors.
组件wxs中不允许使用某些选择器,包括标记名选择器、ID选择器和属性选择器。
- 组件布局修改如下. 每个view都指定了类名样式. 同时使用组合类名样式
<!--components/component1/component1.wxml--><view class="showData-container" style="font-size:{{css_font_size}}rpx;"> <view class="showData-container showData-item" wx:for="{{data_array}}" wx:key="index"> <view class="showData-container" style="height:{{css_item_height}}vh;width:{{css_name_width}}rpx;" >{{item.str_name}}</view> <view class="showData-container" style="height:{{css_item_height}}vh;width:{{css_colon_width}}rpx;">{{":"}}</view> <view class="showData-container" style="height:{{css_item_height}}vh;width:{{css_val_width}}rpx;"><input class="showData-data {{item.isOutputOnly ? 'showData-output' : 'showData-input'}}" disabled="{{item.isOutputOnly}}" value="{{item.str_data}}" data-index="{{index}}" data-name="{{item.str_name}}" bind:blur="input0_blur" /></view> </view>
</view>
/* components/component1/component1.wxss *//* 定义该容器内所有 view 的样式 */
.showData-container{/* 弹性盒子布局 */display: flex;/* 决定主轴的方向 即项目的排列方向: 主轴为水平方向,起点在左端 */flex-direction: row;/* 定义项目是否换行以及如何换行: 换行,第一行在上方 */flex-wrap: wrap;/* 定义项目在主轴上的对齐方式: 居中 */justify-content: center;/* 定义项目在竖直方向上对齐方式: 交叉轴的中点对齐 */align-items: center;/* 定义多根轴线的对齐方式: 与交叉轴的中点对齐 */align-content: center;
}/* 单个框框加阴影边框 */
.showData-item {/* 边框样式 */border: 1rpx solid #ccc;/* 阴影效果 */box-shadow: 0px 0px 5rpx rgba(0, 0, 0, 0.5);/* 内外边距 */padding: 5rpx;margin: 5rpx;/* 设定圆角 */border-radius: 10rpx;/* 如何计算一个元素的总宽度和总高度: 防止溢出 */box-sizing: border-box;
}/* 输出框, 文字居中, 下划线 */
.showData-data {/* 规定填满父级 view */height: 100%;width: 100%;/* 背景颜色透明, */background-color: transparent;/* 文字居中 */text-align: center;/* 如何计算一个元素的总宽度和总高度: 防止溢出 */box-sizing: border-box;
}/* 输入框 下划线 */
.showData-input {/* 简写属性, 下边框的所有属性 */border-bottom: 2rpx solid rgb(61, 61, 61);
}/* 选中输入框, 外边框 */
.showData-input:focus,
.showData-input:hover {/* 简写属性, 外边框的所有属性 */outline: 2rpx solid rgb(61, 61, 61);
}
- 组件调用时修改一下, 添加宽度填满父级,避免布局混乱.
<component1 style="width: 100%;"css_font_size="32"css_name_width="100"css_val_width="120"css_item_height="5"bind:input1_blur="input2_blur"data_array="{{data_array}}"> </component1>
相关文章:

[微信小程序] 入门笔记2-自定义一个显示组件
[微信小程序] 入门笔记2-自定义一个显示组件 0. 准备工程 新建一个工程,删除清空app的内容和其余文件夹.然后自己新建pages和components创建1个空组件和1个空页面. 设定 view 组件的默认样式,使其自动居中靠上,符合习惯.在app.wxss内定义,作用做个工程. /**app.wxss**/ /* 所…...
YOLO代码复现
睿智的目标检测66——Pytorch搭建YoloV8目标检测平台_pytorch_quantization yolov8-CSDN博客 Mask rcnn代码实现_pytorch版_适用30系列显卡_mask rcnn 30显卡-CSDN博客 完整且详细的Yolov8复现训练自己的数据集-CSDN博客...

使用fitten code插件(vscode),替换通义千问,识别需求中的输入输出
今天我们介绍一个工具,具体介绍可以参考我的这篇文章的介绍,支持vs code 插件,Fitten Code是一款由非十科技开发的AI代码助手,旨在通过大模型驱动来提升编程效率和体验-免费神器-CSDN博客https://blog.csdn.net/lijigang100/article/details/137833223?spm=1001.2014.3001…...

vue使用pdfjs-dist在电脑上展示PDF文件
安装 安装的时候一定要带上版本号,这里采用的是2.0.943(因为这个版本对于我目前的项目比较合适可以正常使用,其他版本大概率会报错),当前项目使用的是vue2,vue的版本是2.5.10 npm install pdfjs-dist@2.0.943 查看版本发现这玩意版本非常之多 使用 在使用pdfjs-dist库…...

【网站项目】戒烟网站
🙊作者简介:拥有多年开发工作经验,分享技术代码帮助学生学习,独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。🌹赠送计算机毕业设计600个选题excel文件,帮助大学选题。赠送开题报告模板ÿ…...
慢性软组织疼痛如何使用DMS深层肌肉刺激仪进行治疗?
使用DMS深层肌肉刺激仪治疗慢性软组织疼痛,可以遵循以下步骤: 准备工作:首先,确保DMS设备已经充电或插上电源,并根据需要调整振动强度和频率。DMS深层肌肉刺激仪是通过快速连续的振动和打击来刺激深层肌肉的设备&#…...
自动化测试常用工具
自动化测试工具是非常重要的。自动化测试工具可以帮助程序员提高工作效率,减少重复劳动和人为错误,提高产品质量。下面我将介绍几个常用的自动化测试工具。 Selenium:Selenium是一个开源的自动化测试框架,用于Web应用程序的自动化…...
【Osek网络管理测试】[TG4_TC4]tWaitBusSleep
🙋♂️ 【Osek网络管理测试】系列💁♂️点击跳转 文章目录 1.环境搭建2.测试目的3.测试步骤4.预期结果5.测试结果1.环境搭建 硬件:VN1630 软件:CANoe 2.测试目的 验证DUT的tWBS时间参数是否符合NM标准 本处规定tWBS在[1350ms,1650ms]范围内符合要求 3.测试步骤…...

java08基础(值传递和引用传递 类和对象)
目录 一. 值传递和引用传递 1. 值传递 2. 引用传递 二. 面向对象思想 三. 类和对象 1. 类 2. 对象 2.1 使用 2.2 成员变量和局部变量区别 2.3 操作成员方法 2.4 this关键字(初识) 2.5 构造方法 (见java09) 一. 值传递和引用传递 1. 值传递 值传递是指在调用函数时将…...
高级数据结构与算法习题(9)
一、判断题 1、Let S be the set of activities in Activity Selection Problem. Then the earliest finish activity am must be included in all the maximum-size subset of mutually compatible activities of S. T F 解析:F。设S是活动选择问题中的一…...

Linux的vim下制作进度条
目录 前言: 回车和换行有区别吗? 回车和换行的区别展示(这个我在Linux下演示) 为什么会消失呢? 回车和换行的区别 为什么\r和\n产生的效果不同? 打印进度条: (1)打印字符串 …...
C++学习笔记2
T1 奇怪的教室 题目背景 LSU 的老师有个奇怪的教室,同学们会从左到右坐成一个横排,并且同一个位置可以坐多个同学。这天,入学考试的成绩下来了。同学们想根据入学考试的成绩,找出班里学霸扎堆的区域“学霸区”。 题目描述 共有…...

细数:智能物流装备界的并购案~
导语 大家好,我是智能仓储物流技术研习社的社长,老K。专注分享智能仓储物流技术、智能制造等内容。 新书《智能物流系统构成与技术实践》 近年来,随着智能仓储物流行业的快速发展,全球范围内的并购活动日益频繁,各大企…...
微信小程序播放编码为 video/mp4;codecs=vp8 opus 的视频没有声音
最近在做浏览器录屏功能,主要是录屏加上麦克风生成mp4视频,最终生成的是编码为 video/mp4;codecsvp8 opus 的视频,音频编码因为是 opus 是无法在小程序正常播放的,这样就导致了视频没有声音。后来就在服务端做了一层转换ÿ…...
Linux 指令lsblk 作用,以及查看cpu使用情况和磁盘IO iostat指令详解
lsblk 指令 在Linux系统中,lsblk(列表块设备)命令是一个非常实用的工具,用于显示所有可用的块设备信息,如硬盘、USB驱动器、SD卡以及它们的分区。这个命令以易于理解的树状结构展示这些信息,清晰地表明了设…...

Mybatis之Sqlsession、Connection和Transaction三者间的关系
前言 最近在看Mybatis的源码,搜到这篇文章Sqlsession、Connection和Transaction原理与三者间的关系,debug之后发现有不少疑惑,于是按照原文整理了一下,记录下debug中的一些困惑点。 对于我们开发来讲,不管跟任何关系…...

WRT1900ACS搭建openwrt服务器小记
参考链接 wrt1900acs openwrt wrt1900acs openwrt 刷机 wrt1900acs原生固件刷openwrt-23.05.3-mvebu-cortexa9-linksys_wrt1900acs-squashfs-factory.img wrt1900acs openwrt更新刷openwrt-23.05.3-mvebu-cortexa9-linksys_wrt1900acs-squashfs-sysupgrade.bin 通过WEB UI来…...

Spring AOP(3)
目录 Spring AOP原理 代理模式 代理模式中的主要角色 静态代理 动态代理 总结:面试题 什么是AOP? Spring AOP实现的方式有哪些? Spring AOP实现原理 Spring使用的是哪种代理方式? JDK和CGLIB动态代理的区别? Spring AOP原理 代理模式 代理模式, 也叫委托模式. …...

推荐5个免费的国内平替版GPT
提起AI,大家第一个想到的就是GPT。 虽然它确实很厉害,但奈何于我们水土不服,使用门槛有些高。 不过随着GPT的爆火,现在AI智能工具已经遍布到各行各业了,随着时间的推移,国内的AI工具也已经“百花盛放”了…...

弹性云服务器是什么,为何如此受欢迎
云计算作为当下炙手可热的技术领域,已然成为现代企业不可或缺的核心能力。云服务器作为云计算的基石之一,在这个数字化时代发挥着至关重要的作用。而弹性云服务器,作为云服务器的一种演进形式,更是备受瞩目。 弹性云服务器&#…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...

AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...