普通视图

发现新文章,点击刷新页面。
今天 — 2026年2月6日首页

速通-微信小程序 2Day

作者 慈様ya
2026年2月4日 14:32

速通-微信小程序 2Day

速通-微信小程序-CSDN博客 紧接前文,搭配有助于快速,巩固/学习!话不多说开始!

这一部分挺简单的,最起码对于做过前端Vue 开发,前后端的 me,so so easy!

WXML 模板语法

WXML(WeiXin Markup Language)是小程序的视图层模板语言

作用类似 HTML,但扩展了「数据绑定、逻辑渲染、事件绑定」等核心能力,

是小程序 数据驱动视图 核心能力:数据绑定、逻辑渲染(列表/条件)、事件绑定;

数据绑定:

Mustache 语法 ,把data中的数据绑定到页面中渲染:

WXML 通过双大括号 {{}}将 JS 逻辑层数据渲染到视图层,支持 内容绑定、属性绑定、表达式运算

  • {{}}内支持简单表达式(算术、三元、逻辑运算),但不支持复杂语句(如if/for循环)

  • 文本绑定中,{{}}会自动解析 \n 为换行符(对应之前text组件的换行场景)

  • ⚠️绑定的数据必须在页面 data 中定义,否则会显示为空;

内容绑定: <标签> {{ 绑定页面data中的变量,文本渲染 }} </标签>

属性绑定: 标签,属性值也用 {{}} 绑定,注意,属性名无需加引号(区别于 VUE 的v-bind

xxx.js

Page({
/** 页面的初始数据 */
    data: {
img: "https://i1.hdslb.com/bfs/face/6ac26f27a6d25da7865cab8e0806676c8f4cd62c.webp",
        username: "wsm",
        age: 25
    },
    /** 省略其他配置.... */
})

xxx.wxml

<view>
  <!-- 绑定页面data中的变量 -->
  <text>用户名:{{username +'\n'}}</text>
  <text>年龄:{{age + 1 +'\n'}}</text> <!-- 支持表达式运算 -->
  <text>成年:{{age >= 18 ? '是' : '否'}} \n</text> <!-- 三元运算 -->

  <!-- 动态绑定标签属性-data中的变量 -->
  <image src="{{img}}"  mode="widthFix"></image>
</view>

在这里插入图片描述

事件绑定:

小程序的事件绑定是视图层(WXML)与逻辑层(JS)通信的核心方式 也是实现用户交互的唯一入口;

由于小程序是双线程模型(渲染层 + 逻辑层),事件需通过微信客户端(Native)中转,

因此绑定规则、事件对象与普通网页的 DOM 事件有本质差异;

在这里插入图片描述

事件 中转通信

小程序的事件并非直接的 DOM 事件,而是通过 微信客户端作为中转桥接层

将视图层用户交互 点击、输入 转发到逻辑层 JS 函数处理,这种设计避免了直接 DOM 操作;

  • 核心限制 :禁止直接操作 DOM,所有交互必须通过 事件绑定 + 数据驱动 实现

  • 触发流程 :用户在视图层触发事件 → 微信客户端捕获事件并封装成事件对象

    → 转发到逻辑层对应的 JS 函数 → 逻辑层处理后通过 setData 更新视图;

事件绑定的两种核心方式:

小程序提供 bindcatch 两种绑定前缀,核心区别是是否允许事件冒泡

绑定方式 行为 适用场景
bind 绑定事件并允许冒泡(事件会向上传递给父元素) 需要父元素响应子元素事件的场景
如:事件委托)
catch 绑定事件并阻止冒泡(事件不会向上传递) 仅需当前元素响应事件的场景
如:按钮点击、表单提交)
<!-- 父元素绑定bindtap,子元素绑定bindtap -->
<view bindtap="parentTap" style="padding: 20rpx; background: #f0f0f0;">
    <button bindtap="childTap">点击子元素(允许冒泡)</button>
</view>

<!-- 父元素绑定bindtap,子元素绑定catchtap -->
<view bindtap="parentTap" 
style="padding: 20rpx; background: #f0f0f0; margin-top: 20rpx;">
    <button catchtap="childTap">点击子元素(阻止冒泡)</button>
</view>
/** 页面定义函数 */
parentTap() {
    console.log("父元素事件触发");
},
childTap() {
console.log("子元素事件触发");
}

在这里插入图片描述

  • 点击第一个按钮(bindtap):会先触发childTap,再触发parentTap(事件冒泡到父元素)

  • 点击第二个按钮(catchtap):仅触发childTap,不会触发parentTap(阻止冒泡)

事件对象(e):交互数据的 “载体”

事件触发时,逻辑层的 JS 函数会收到一个 事件对象e,包含事件的所有信息,核心属性如下:

属性 作用
e.type 事件类型(如 tapinput
区分不同事件类型,如同时绑定多种事件时判断触发源)
e.target 触发事件的源元素(实际点击的元素)
事件委托场景中,获取触发事件的具体子元素
e.currentTarget 绑定事件的当前元素(事件绑定的元素)
获取绑定事件的元素的自定义属性或统一处理父元素逻辑
e.detail 事件携带的额外信息(如表单输入值、滑动距离)
获取表单组件的输入内容(如 input 实时值)、滑动组件的位移量
e.dataset 元素的自定义属性(通过 data-* 定义)
事件传参的核心方式(如传递商品 ID、列表项索引)
<view bindtap="handleTap" data-id="parent">
  <button data-id="child">点击按钮</button>
</view>
handleTap(e) {
  console.log(e.target.dataset.id); // 输出:child(实际触发的元素是按钮)
  console.log(e.currentTarget.dataset.id); // 输出:parent(绑定事件的元素是view)
}

target 和 currentTarget 的区别

target:指向实际触发事件的元素(子元素)

currentTarget:指向绑定事件的元素(父元素)

在这里插入图片描述

小程序 常用事件

冒泡事件(支持bind/catch

事件名 触发场景 实战用途
tap 点击元素 (手指触摸后马上离开) 按钮点击、列表项跳转、提交操作
longpress 长按元素(触摸时间≥350ms) 弹出操作菜单、删除确认
touchstart 手指触摸开始 滑动交互、手势识别
touchend 手指触摸结束 滑动结束、手势确认
touchmove 手指触摸后移动 滑动拖拽、进度条控制

非冒泡事件(仅支持bindcatch无效)

事件名 触发场景 实战用途
submit 表单提交 提交表单数据到后端
scroll 页面 / 滚动容器滚动 监听滚动位置、实现上拉加载更多
change 表单组件值变化(如 switch、picker) 监听开关状态、选择器变化
input 输入框内容变化 实时获取用户输入(如搜索框、表单)

事件传参:data-* 自定义属性

小程序不支持直接在事件绑定中传参 如: bindtap="handleClick(123)"会报错

必须通过data-*自定义属性传递参数,再从事件对象的 e.currentTarget.dataset 中获取;

<!-- 事件传参: -->
<view>
<!-- 可以为组件提供data-*自定义属性传参,其中*代表的是参数的名字,示例代码如下: -->
    <button bindtap="handleTapparam" data-param1="123" data-param2="{{123}}" >事件传参 param1</button>
</view>
handleTapparam(e){
    //通过 event.target.dataset.参数名 即可获取到具体参数的值
    //通过dataset可以访问到具体参数的值
    console.log(e.target.dataset);            
    console.log(e.target.dataset.param1);     
    console.log(e.target.dataset.param2);
}

在这里插入图片描述表单事件的detail属性

实现文本框和 data 之间的数据同步

小程序文本框(input组件)与页面data数据双向同步

核心依托小程序 数据绑定 +input 组件 输入事件监听 🖥️🖥️🖥️

通过setData完成视图层(文本框)与逻辑层(data)的双向数据更新;

  • 文本框通过value="{{data中的变量}}"实现 data 到文本框的单向渲染(初始值回显);
  • 绑定input组件的输入事件(bindinput/bindblur),实时 / 按需获取文本框输入值;
  • 在事件处理函数中,通过this.setData({ 变量: 输入值 })完成 文本框到 data 的反向同步
  • 全程遵循小程序「数据驱动视图」原则, 禁止直接操作 DOM ,所有数据更新均通过setData实现;
  <input value="{{inpmas}}" bindinput="inpvalue"
  style="border: 1px solid black; margin: 5px; padding: 5px;" />
/** 页面的初始数据 */
data: {
    img: ".................",
inpmas: '兴趣爱好',
    username: "wsm",
age: 25,
},
//data 之间的数据同步
inpvalue(e){
//通过 e.detail.value 获取到文本框最新的值
this.setData({ inpmas: e.detail.value });
console.log(this.data.inpmas);
},

在这里插入图片描述

条件渲染:

WXML 的条件渲染是小程序根据逻辑层(JS)数据动态控制视图层元素显示 / 隐藏的核心能力,

完全遵循「数据驱动视图」原则,禁止直接操作 DOM 修改显示状态

wx:if

wx:if / wx:elif / wx:else(多分支条件,逻辑销毁 / 重建)

wx:if 是 WXML 原生支持的 多分支条件渲染语法 ,支持单条件、多条件分支、嵌套判断

底层通过 销毁 / 重建组件节点 实现显示 / 隐藏(条件不满足时节点从渲染树移除,满足时重新创建)

<view>
  <!-- 当isShow为true时显示,否则销毁该节点 -->
  <view wx:if="{{isShow}}">仅满足条件时显示</view>

  <!-- 多分支按顺序匹配,仅执行第一个满足条件的分支 -->
  <view wx:if="{{status === 0}}">待支付</view>
  <view wx:elif="{{status === 1}}">已支付/待发货</view>
  <view wx:elif="{{status === 2}}">已发货/待收货</view>
  <view wx:else>已完成/已取消</view>

  <!-- block包裹多节点,一次控制所有元素的显示/隐藏 -->
  <block wx:if="{{hasData}}">
    <view>商品名称:{{goods.name}}</view>
    <view>商品价格:{{goods.price}}元</view>
    <button>立即购买</button>
  </block>
  <!-- 空状态提示 -->
  <view wx:else>暂无商品数据</view>
</view>
Page({
  /** 页面的初始数据 */
  data: {
    status: 3,
    isShow: false,
    hasData: false,
    goods: { name:"AAA", price:12.00 },
  },
})

在这里插入图片描述

<block> 包裹多节点(不生成冗余 DOM)

若需要 同时控制多个元素的条件显示,直接给每个元素加wx:if会冗余,

可使用<block>标签包裹 ——<block>是 WXML 的无渲染容器

仅用于包裹节点,不生成实际 DOM 元素,不影响页面布局;

wx:hidden

hidden 是 WXML 元素的通用属性,仅支持单分支条件判断(隐藏 / 显示)

底层通过CSS 的 display: none 实现隐藏 —— 元素节点始终存在于渲染树中

仅通过样式控制不可见,适合 单条件、高频切换 的场景(如弹窗、下拉菜单、开关控制的内容

<view>
  <!-- 方式1:直接写布尔值(静态,无动态切换需求) -->
  <view hidden="{{true}}">静态隐藏的内容</view>
  <!-- 方式2:绑定data中的布尔变量(推荐,支持动态切换) -->
  <view hidden="{{isHidden}}">高频切换的内容(如弹窗)</view>
  <!-- 方式3:结合简单表达式(无需额外定义data变量) -->
  <view hidden="{{list.length === 0}}">列表有数据时显示</view>
</view>
Page({
  /** 页面的初始数据 */
  data: {
    // 控制hidden的核心变量
    isHidden: false, 
    list: [1,2]
  },
})

在这里插入图片描述

if 🆚 hidden

两者的核心差异在于 底层实现方式,直接决定了 切换性能开销适用场景

运行方式不同:

  • wx:if 以动态创建和移除元素的方式,控制元素的展示与隐藏
  • hidden 以切换样式的方式(display: none/block;),控制元素的显示与隐藏

使用建议: 频繁切换时,建议使用 hidden,控制条件复杂时,建议使用 wx:if、wx:elif、wx:else

wx:for 列表渲染

wx:for 是 WXML 原生核心的列表渲染指令,用于将数组 / 对象中的数据循环渲染为页面节点;

将逻辑层(JS)data中的数组 / 对象,在视图层(WXML)中循环生成相同结构的节点,

实现数据与视图的联动渲染,无需手动操作 DOM;

直接给元素绑定wx:for="{{数组名}}",即可循环渲染该元素;

小程序自动提供 2 个默认变量,无需手动定义:

  • item:当前循环的 数组项 每一个元素
  • index:当前循环的 索引 从 0 开始

wx:key是必填项 无合法wx:key会触发控制台性能警告,且列表重排时易出现渲染错误

<view>
  <!-- wx:for绑定数组,wx:key绑定唯一标识 -->
  <view wx:for="{{goodsList}}" wx:key="id" class="goods-item">
    <text>第{{index+1}}个商品:</text>
    <text>名称:{{item.name}},价格:{{item.price}}元</text>
  </view>
</view>
Page({
  /** 页面的初始数据 */
  data: {
    // 模拟后端返回的商品列表,id为唯一标识
    goodsList: [
      { id: 1, name: "小程序开发实战", price: 59 },
      { id: 2, name: "Java后端进阶", price: 79 },
      { id: 3, name: "全栈开发指南", price: 99 }
    ]
  },
})

在这里插入图片描述

WXSS 模板样式

WXSS(WeiXin Style Sheet)是小程序的专属样式语言,

类似于CSS样式,并,在 CSS 基础上扩展了 rpx 响应式尺寸单位 解决移动端多设备适配复用问题;

rpx 尺寸单位

什么是 rpx 尺寸单位

rpx(responsive pixel)是小程序独有的响应式尺寸单位

用于统一不同屏幕宽度设备的尺寸显示,替代 CSS 中的固定单位 px,无需手动计算适配比例;

实现原理: 小程序将所有设备的屏幕宽度统一映射为 750rpx 750rpx = 设备实际屏幕宽度

框架会根据设备屏幕宽度自动换算 rpx 对应的物理像素:

  • 在 iPhone X(屏幕宽度 375px)上:换算比例与 iPhone 6 一致
  • 在 iPhone 6(屏幕宽度 375px)上:750rpx = 375px1rpx = 0.5px
  • 在安卓设备(如屏幕宽度 414px)上:750rpx = 414px1rpx ≈ 0.552px

设计稿适配:主流设计稿宽度为 750px,设计稿上的 1px 可直接对应小程序的 1rpx

官方建议:开发微信小程序时,设计师可以用 iPhone6 作为视觉稿的标准

@import 样式导入

用于导入外部 WXSS 样式文件,实现 公共样式复用

如:全局主题、组件样式、工具类),避免重复编写样式,提升代码可维护性;

支持 相对路径 和 绝对路径 ,必须用双引号包裹路径,结尾加分号,可导入多个文件,按顺序合并样式;

在这里插入图片描述

app.json 全局配置

小程序根目录下的 app.json 文件是小程序的 全局配置文件 常用的配置项如下:

  • pages: 记录当前小程序所有页面的存放路径,必选,小程序启动的基础
  • tabBar: 设置小程序底部的 tabBar 效果
  • window: 全局设置小程序窗口的外观
  • style: 是否启用新版的组件样式

配置 window

属性名 默认值 说明
navigationBarTitleText 字符串 导航栏标题文字内容
navigationBarBackgroundColor #000000 导航栏背景颜色,如 #000000
navigationBarTextStyle white 导航栏标题颜色,仅支持 black/white
backgroundColor #ffffff 窗口的背景色
backgroundTextStyle dark 下拉 loading 的样式,仅支持 dark/light
enablePullDownRefresh false 是否全局开启下拉刷新
onReachBottomDistance 50 页面上拉触底事件触发,距页面底部距离,单位为px
navigationStyle default custom 为自定义导航栏,适合沉浸式页面

配置 tabBar

tabBar 是小程序的 全局底部导航组件,用于在多个核心页面(如首页、我的、订单)之间快速切换;

是多页面小程序的标配。它完全在 app.json 中配置,无需编写额外代码,以下完整配置指南🧭:

小程序中通常将其分为: 底部 tabBar顶部 tabBar

  • tabBar中只能:配置最少 2 个、最多 5 个 tab 页签

  • 渲染 顶部tabBar 时,不显示 icon,只显示文本

tabBarapp.json 的顶级配置项,分为必填项和可选项

配置项 必填 / 取值 / 说明
color 是,tab 未选中时的文字颜色(十六进制色值,如 #666666
selectedColor 是,tab 选中时的文字颜色(需与 color 区分,如品牌色 #ff4444
backgroundColor 是,tabBar 的背景色(十六进制色值,如 #ffffff
borderStyle 否,tabBar 上边框的样式,仅支持 black/white,默认 black
position 否,tabBar 的位置,默认 bottom(底部),可选 top(顶部)
⚠️ 注意:position: "top" 时,不显示 icon,仅显示文字
custom 否,是否使用自定义 tabBar(默认 false
开启后需在根目录创建 custom-tab-bar 自定义组件,适合复杂交互;
list 是,tab 项的数组,最少 2 个,最多 5 个,每个元素为一个 tab 配置对象;

每个 tab 项的配置(list 数组元素)

配置项 必填 / 取值 / 说明
pagePath 是,点击 tab 跳转的页面路径,
必须是 pages 数组中已注册的页面pages/index/index
text 是,tab 上显示的文字,如 首页 我的
iconPath 否,tab 未选中时的图标路径,建议用 81px:81px 的 2x 图,避免模糊
selectedIconPath 否,tab 选中时的图标路径,需与 iconPath 尺寸一致

以下是 <常见小程序> 的典型 tabBar 配置: 首页 / 消息 / 联系我们

{
  "pages": [
    "pages/home/home",
    "pages/contact/contact",
    "pages/message/message"
  ],
  "window": {
    "navigationBarTextStyle": "black",
    "navigationBarTitleText": "我的小程序",
    "navigationBarBackgroundColor": "#FFFFFF"
  },
  "style": "v2",
  "lazyCodeLoading": "requiredComponents",
  "componentFramework": "glass-easel",
  "sitemapLocation": "sitemap.json",
  
  "tabBar": {
    "color": "#666666",
    "selectedColor": "#ff4444",
    "backgroundColor": "#ffffff",
    "borderStyle": "black",
    "list": [
      {
        "text": "首页",
        "pagePath": "pages/home/home",
        "iconPath": "images/tab/home.png",
        "selectedIconPath": "images/tab/home-active.png"
      },
      {
        "text": "消息",
        "pagePath": "pages/message/message",
        "iconPath": "images/tab/message.png",
        "selectedIconPath": "images/tab/message-active.png"
      },
      {
        "text": "联系我们",
        "pagePath": "pages/contact/contact",
        "iconPath": "images/tab/contact.png",
        "selectedIconPath": "images/tab/contact-active.png"
      }
    ]
  }
}
  • ⚠️ tabBar —— list 最少两个最多5个,且必须在 Page中存在!!!

在这里插入图片描述

xxx.json 局部配置

小程序中,每个页面都有自己的 .json 配置文件,用来对当前页面的窗口外观、页面效果等进行配置

小程序中,app.json 中的 window 节点,可以全局配置小程序中每个页面的窗口表现;

  • 如果,某些小程序页面想要拥有特殊的窗口表现,

  • 此时,页面级别的 .json 就可以实现这种需求

根据就近原则,最终的效果以页面配置为准

网络数据请求

小程序中网络数据请求的限制:

为保障用户数据安全,小程序的网络请求有以下强制规则:

域名白名单

  • 上线请求的域名必须在,微信公众平台 开发管理→开发设置→服务器域名

    中配置白名单,仅支持 HTTPS 协议,域名必须经过 ICP 备案,可在小程序:项目配置中查看!

    在这里插入图片描述

  • 开发阶段可在开发者工具中开启 不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书

    豁免;上线前必须完成域名备案并配置白名单; 详情——本地配置——不校验合法域名

    在这里插入图片描述

    仅在开发阶段使用,上线必须合法域名HTTPS!!

协议要求

  • 上线: 仅支持 HTTPS/WSS 协议,禁止使用 HTTP
  • 开发阶段: 可暂时豁免,上线前必须切换为 HTTPS 域名;

请求频率

  • 单个小程序的并发请求数限制为 10 个,高频请求需做节流/合并
  • 避免短时间内发起大量请求,可通过防抖 / 合并请求优化

跨域限制

  • 仅需配置微信域名白名单,无需后端设置 CORS

  • 无需配置 CORS(由微信客户端中转请求,无浏览器同源限制)

相关测试接口:

GET: https://applet-base-api-t.itheima.net/slides 获取轮播图信息;

POST: https://applet-base-api-t.itheima.net/api/post 上传用户信息;

在这里插入图片描述

发生 GET 请求

home.wxml

<!-- 轮播图容器:适配小程序轮播组件 -->
<swiper  indicator-dots  autoplay interval="3000"  
circular  indicator-active-color="#ff4444" class="banner-swiper">
  <!-- 循环渲染轮播图项 -->
  <swiper-item wx:for="{{slides}}" wx:key="id">
    <image  src="{{item.image}}"  style="height: 100%; width: 100%;"  />
  </swiper-item>
</swiper>

home.js

Page({
  /*** 页面的初始数据 */
  data: {
    slides: [] // 轮播图数据列表,初始为空
  },
  /** 生命周期函数--监听页面加载 */
  onLoad(options) {
    // 调用GET请求渲染页面轮播图~
    this.getSlides();
  },
  //GET请求获取页面轮播图信息
  getSlides() {
    // 显示加载中提示,提升用户体验
    wx.showLoading({title: '加载中...', mask: true});
    wx.request({
      url: 'https://applet-base-api-t.itheima.net/slides',
      method: 'GET',
      success: (res) => {
        // 接口请求成功:判断状态码,更新数据
        if (res.statusCode === 200 && res.data) {
          this.setData({slides: res.data });
        }else{
           // 接口返回异常,提示用户
           wx.showToast({ title: '轮播图数据加载失败', icon: 'none',duration: 2000 })
        }
      },
      fail: (err) => {
        console.error('轮播图请求失败:', err);
        wx.showToast({ title: '轮播图数据加载失败', icon: 'none',duration: 2000 })
      },
      // 无论成功/失败,都关闭加载提示
      complete: () => {
        wx.hideLoading();
      }
    })
  }
})

在这里插入图片描述

发送 POST 请求

<!-- 分割线 -->
<view class="divider">\n</view>

<!-- 用户信息输入区域(新增) -->
<view>
  <view>
    <text>姓名:</text>
    <input type="text" placeholder="请输入姓名" 
value="{{name}}" bindinput="syncInput" data-key="name"/>
  </view>
  <view class="form-item">
    <text class="label">性别:</text>
    <input type="text" placeholder="请输入性别 男/女" 
value="{{gender}}" bindinput="syncInput" data-key="gender" />
  </view>
  <!-- 提交按钮 -->
  <button bindtap="postUserInfo" class="submit-btn">提交用户信息</button>
</view>

<!-- POST请求结果展示区域(新增) -->
<view wx:if="{{postResult}}">
  <text>提交结果:</text>
  <text>{{postResult}}</text>
</view>
Page({
  /*** 页面的初始数据 */
  data: {
    slides: [], // 轮播图数据列表,初始为空
    name: '',
    gender: '',
    postResult: ''
  },
  /** 生命周期函数--监听页面加载 */
  onLoad(options) {   },
  //GET请求页面轮播图信息
  getSlides() {  },

  // 新增:同步输入框数据到data(实时绑定)
  // 通过data-key区分是name还是gender输入框
  syncInput(e) {
    const key = e.currentTarget.dataset.key;
    this.setData({[key]: e.detail.value });
  },
  // 新增:POST请求提交用户信息
  postUserInfo() {
    // 非空校验
    const { name, gender } = this.data;
    if (!name || !gender) {
      wx.showToast({ title: '请完善姓名和性别', icon: 'none' });
      return;
    }
    // 显示加载提示
    wx.showLoading({ title: '提交中...', mask: true });
    // 发起POST请求
    wx.request({
      url: 'https://applet-base-api-t.itheima.net/api/post',
      method: 'POST',
      data: { name, gender },
      header: { 'content-type': 'application/json' },
      success: (res) => {
        // 将返回的JSON转为字符串,方便页面展示
        if (res.statusCode === 200 && res.data) {
          this.setData({postResult: JSON.stringify(res.data, null, 2)})
          wx.showToast({ title: '提交成功', icon: 'success' });
        }else {
          wx.showToast({ title: '提交失败', icon: 'none' });
        }
      },
      fail: (err) => {
        console.error('POST请求失败:', err);
        wx.showToast({ title: '网络异常,请稍后重试', icon: 'none' });
      },
      complete: () => { wx.hideLoading(); },
    })
  }
})

在这里插入图片描述

小程序网络请求进阶

小程序的网络请求能力远不止 GET/POST

完全支持 RESTful 风格的 PUT/DELETE 等方法,同时提供了专门的 API 处理表单和文件传输;

相关文档:

黑马—小程序简介_哔哩哔哩_bilibili 对应:Day2 天内容!

  • blog 中涉及接口案例,可能会失效,可以到官方评论区,会定期更新最新域名!
❌
❌