小程序开发零基础小白学习知识点详解【基础版】

✅ 超详细拆解+通俗案例+完整代码,零基础可直接复刻
✅ 技术适配:基于微信小程序最新开发规范,覆盖核心基础能力
✅ 条理清晰:从“认知→环境→语法→实战→调试”全流程,无冗余内容
✅ 核心目标:掌握小程序开发全流程,能独立制作带基础交互的完整小程序


一、前置准备:彻底搞懂小程序

1. 小程序的核心特征

  • 无需安装:不用像App那样下载安装,微信内搜索/扫码就能打开,比如打开“微信读书”小程序,用完直接退出,不占手机内存;
  • 轻量高效:体积限制(主包≤2MB),加载速度比网页快,体验接近原生App;
  • 功能闭环:能实现大部分App的核心功能(购物、支付、聊天、打卡等),但不能后台运行;
  • 多端兼容:一套代码可适配微信、支付宝、抖音等平台(新手先聚焦微信小程序)。

2. 环境搭建(一步一步教你做)

(1)注册小程序账号(获取AppID)
  1. 打开「微信公众平台」(https://mp.weixin.qq.com/),点击“立即注册”→选择“小程序”;
  2. 按提示填写邮箱、验证码、密码,完成账号激活;
  3. 登录后,在“开发→开发管理→开发设置”中找到「AppID(小程序ID)」,复制保存(开发必需)。
(2)安装微信开发者工具
  1. 官网下载对应系统版本(https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html);
  2. 安装完成后打开,选择“小程序→公众号网页→小游戏”分类,点击“微信开发者工具”;
  3. 首次打开需用微信扫码登录,绑定你的小程序账号。
(3)创建第一个项目
  1. 登录后点击“+新小程序项目”,弹出配置框:
    • 项目名称:填“我的第一个小程序”(自定义);
    • 项目目录:点击“选择”,新建一个空文件夹(如桌面的“miniprogram-demo”);
    • AppID:粘贴刚才复制的个人AppID(若无,选“测试号”,但测试号部分功能受限);
    • 勾选“不使用云服务”(新手先不学云开发);
    • 模板选择“基础模板”;
  2. 点击“创建”,等待工具加载完成,自动生成默认项目结构。
(4)开发者工具界面说明
  • 左侧模拟器:实时预览小程序效果,可切换手机型号(如iPhone 15、华为P60);
  • 中间编辑器:编写代码的区域,支持语法高亮、自动补全;
  • 右侧调试器:调试代码(Console看报错、Network看网络请求、AppData看数据);
  • 顶部菜单栏
    • 编译:保存代码并刷新模拟器;
    • 预览:生成二维码,用微信扫码看真机效果;
    • 上传:将代码提交到微信公众平台(发布用)。

二、核心基础:小程序项目结构与语法(超详细)

1. 完整项目结构解析

默认生成的项目结构如下,用“开奶茶店”的例子类比:

miniprogram-demo/          # 项目根目录
├─ pages/                  # 所有页面存放目录(奶茶店的各个包间)
│  ├─ index/               # 首页(大堂)
│  │  ├─ index.js          # 首页逻辑(大堂的服务规则)
│  │  ├─ index.json        # 首页配置(大堂的装修规则)
│  │  ├─ index.wxml        # 首页结构(大堂的桌椅摆放)
│  │  └─ index.wxss        # 首页样式(大堂的装修风格)
│  └─ logs/                # 日志页(仓库)
│     ├─ logs.js
│     ├─ logs.json
│     ├─ logs.wxml
│     └─ logs.wxss
├─ app.js                  # 全局逻辑(奶茶店的整体规则)
├─ app.json                # 全局配置(奶茶店的整体布局)
├─ app.wxss                # 全局样式(奶茶店的统一装修风格)
└─ project.config.json     # 项目配置(开发者工具的设置,不用改)
(1)全局文件
文件核心作用(通俗解释)关键配置举例
app.json小程序的“总章程”1. pages:声明所有页面路径(必须把首页放第一个);
2. window:设置顶部导航栏样式;
3. tabBar:底部导航栏(如首页/我的)
app.wxss全局样式(所有页面都能用)定义全局字体、颜色,比如 page { background-color: #f5f5f5; }(所有页面背景灰色)
app.js全局逻辑(小程序启动/销毁触发)1. onLaunch:小程序启动时执行(如初始化用户信息);
2. globalData:存储全局数据(如用户ID)
app.json完整示例:
{
  "pages": [
    "pages/index/index",  // 首页(启动页)
    "pages/logs/logs",    // 日志页
    "pages/detail/detail" // 新增的详情页(后续实战用)
  ],
  "window": {
    "navigationBarBackgroundColor": "#ffffff", // 顶部导航栏背景色(白色)
    "navigationBarTextStyle": "black",         // 导航栏文字颜色(黑色)
    "navigationBarTitleText": "我的奶茶店",     // 导航栏标题
    "backgroundColor": "#f5f5f5",             // 页面下拉后的背景色
    "enablePullDownRefresh": false             // 是否允许下拉刷新(关闭)
  },
  "tabBar": { // 底部导航栏(可选,比如首页/订单/我的)
    "color": "#666666",          // 未选中文字颜色
    "selectedColor": "#07C160",  // 选中文字颜色(微信绿)
    "backgroundColor": "#ffffff",// 底部背景色
    "list": [
      {
        "pagePath": "pages/index/index", // 对应页面路径
        "text": "首页",                 // 文字
        "iconPath": "images/home.png",  // 未选中图标
        "selectedIconPath": "images/home-active.png" // 选中图标
      },
      {
        "pagePath": "pages/logs/logs",
        "text": "日志",
        "iconPath": "images/log.png",
        "selectedIconPath": "images/log-active.png"
      }
    ]
  },
  "sitemapLocation": "sitemap.json" // 搜索引擎收录配置(新手不用改)
}
(2)页面文件

每个页面必须有.wxml(结构)和.js(逻辑),.json(页面配置)和.wxss(页面样式)可选。
页面配置(如index.json)会覆盖app.json的全局配置,比如:

{
  "navigationBarTitleText": "奶茶店首页", // 仅首页的导航栏标题改为这个
  "enablePullDownRefresh": true          // 仅首页允许下拉刷新
}

2. 核心语法

(1)WXML:页面结构(类似HTML,但有专属标签)

WXML是小程序的“结构语言”,负责描述页面有什么,核心规则:

  • 标签名更简洁:用view代替HTML的divtext代替p/spanimage代替img
  • 属性名用连字符:如bindtap(绑定点击事件)、wx:for(循环);
  • 数据绑定用{{ }}:把JS里的数据显示到页面。
常用WXML标签:
标签作用(通俗解释)示例代码
view容器(包裹其他元素)<view class="box">我是一个容器</view>
text文字(仅能放文字,可复制)<text selectable="true">可复制的文字</text>(selectable允许复制)
image图片(支持本地/网络图片)<image src="/images/milk-tea.png" mode="widthFix"></image>(widthFix:宽度自适应,高度等比)
button按钮(支持点击事件)<button bindtap="buyMilkTea" type="primary">购买奶茶</button>(type=primary:绿色主按钮)
input输入框(用户输入内容)<input placeholder="请输入奶茶甜度" bindinput="inputChange"></input>
form表单(包裹输入框/按钮)<form bindsubmit="formSubmit"><button form-type="submit">提交</button></form>
scroll-view滚动视图(内容超出可滚动)<scroll-view scroll-y="true" style="height: 300rpx;">长列表内容</scroll-view>
WXML核心语法:数据绑定
<!-- index.wxml -->
<view>
  <!-- 1. 绑定普通数据 -->
  <text>奶茶名称:{{milkTeaName}}</text>
  <!-- 2. 绑定属性(注意:属性也要用{{}}) -->
  <image src="{{teaImage}}" mode="widthFix"></image>
  <!-- 3. 绑定布尔值(控制显示/隐藏) -->
  <view wx:if="{{isHot}}">热销款</view>
  <!-- 4. 绑定样式(两种方式) -->
  <view style="color: {{fontColor}};">价格:{{price}}元</view>
  <view class="{{isDiscount ? 'discount' : 'normal'}}">限时折扣</view>
</view>
// index.js
Page({
  data: {
    milkTeaName: "珍珠奶茶",
    teaImage: "/images/pearl-tea.png",
    isHot: true,
    fontColor: "#ff0000",
    price: 15,
    isDiscount: true
  }
})
/* index.wxss */
.discount { color: #ff0000; font-weight: bold; }
.normal { color: #666666; }
  • 效果:页面显示“奶茶名称:珍珠奶茶”,图片显示珍珠奶茶,有“热销款”标签,价格红色15元,“限时折扣”红色加粗。
WXML核心语法:列表渲染(wx:for)

用于批量展示多条数据(如奶茶列表),必须加wx:key(唯一标识,避免渲染错误):

<!-- index.wxml -->
<view class="tea-list">
  <view wx:for="{{teaList}}" wx:key="id" class="tea-item">
    <image src="{{item.image}}" mode="widthFix"></image>
    <view class="info">
      <text class="name">{{item.name}}</text>
      <text class="price">¥{{item.price}}</text>
      <text wx:if="{{item.stock > 0}}">有货</text>
      <text wx:else>售罄</text>
    </view>
    <button bindtap="addToCart" data-id="{{item.id}}">加入购物车</button>
  </view>
</view>
// index.js
Page({
  data: {
    teaList: [
      { id: 1, name: "珍珠奶茶", price: 15, image: "/images/pearl-tea.png", stock: 100 },
      { id: 2, name: "芋泥奶茶", price: 18, image: "/images/taro-tea.png", stock: 50 },
      { id: 3, name: "抹茶奶茶", price: 20, image: "/images/matcha-tea.png", stock: 0 }
    ]
  },
  // 加入购物车事件(获取点击的奶茶ID)
  addToCart(e) {
    const teaId = e.currentTarget.dataset.id; // 获取data-id的值
    wx.showToast({
      title: `已加入购物车(ID:${teaId}`,
      icon: "success"
    })
  }
})
/* index.wxss */
.tea-list { padding: 20rpx; }
.tea-item {
  display: flex;
  align-items: center;
  padding: 20rpx;
  border-bottom: 1rpx solid #eee;
}
.tea-item image { width: 100rpx; height: 100rpx; margin-right: 20rpx; }
.tea-item .info { flex: 1; }
.tea-item .name { font-size: 32rpx; display: block; margin-bottom: 10rpx; }
.tea-item .price { color: #ff0000; margin-right: 20rpx; }
  • 效果:页面显示3款奶茶,每款包含图片、名称、价格、库存状态,点击“加入购物车”弹出对应ID的提示。
WXML核心语法:条件渲染(wx:if/wx:else)

控制元素是否显示,比如根据库存显示“有货/售罄”,上面的例子已包含,补充多条件:

<view wx:if="{{score >= 90}}">爆款</view>
<view wx:elif="{{score >= 80}}">热销</view>
<view wx:elif="{{score >= 70}}">推荐</view>
<view wx:else>普通</view>
(2)WXSS:页面样式(类似CSS,新增特性)

WXSS是小程序的“样式语言”,兼容大部分CSS语法,新增2个核心特性:

  • rpx单位:自适应单位,1rpx = 屏幕宽度/750,比如750rpx就是满屏宽度,不用手动计算适配不同手机;
    • 例子:width: 375rpx; 在iPhone 15(宽度390px)上是195px,在华为P60(宽度360px)上是180px,自动适配;
  • 样式导入:用@import导入外部样式文件,比如:
    @import "/styles/common.wxss"; // 导入全局通用样式
    
WXSS常用技巧:
  1. 布局用Flex:小程序推荐用Flex布局,比如让元素居中:
    .container {
      display: flex;
      justify-content: center; /* 水平居中 */
      align-items: center;     /* 垂直居中 */
      height: 100vh;           /* 占满屏幕高度 */
    }
    
  2. 样式优先级:页面样式(.wxss)> 全局样式(app.wxss),标签内style属性优先级最高;
  3. 隐藏元素:display: none;(不占空间)或visibility: hidden;(占空间)。
(3)JS:页面逻辑(小程序核心)

页面JS的核心是Page()函数,里面包含页面生命周期、数据、事件处理函数,完整示例:

// index.js
Page({
  // 1. 页面初始数据(必须用data包裹)
  data: {
    count: 0,
    teaList: []
  },

  // 2. 页面生命周期函数(自动触发)
  // 页面加载时执行(只执行1次)
  onLoad(options) {
    console.log("页面加载了");
    // 初始化数据
    this.setData({
      teaList: [
        { id: 1, name: "珍珠奶茶", price: 15 }
      ]
    });
    // 获取跳转传参(比如从详情页带过来的id)
    console.log("跳转传参:", options.id);
  },
  // 页面显示时执行(每次切回页面都执行)
  onShow() {
    console.log("页面显示了");
  },
  // 页面初次渲染完成(可以操作DOM,新手少用)
  onReady() {
    console.log("页面渲染完成了");
  },
  // 页面隐藏时执行(跳转到其他页面)
  onHide() {
    console.log("页面隐藏了");
  },
  // 页面卸载时执行(返回上一页且无法返回)
  onUnload() {
    console.log("页面卸载了");
  },
  // 下拉刷新时执行(需在json中开启enablePullDownRefresh)
  onPullDownRefresh() {
    console.log("下拉刷新了");
    // 刷新完成后停止加载动画
    wx.stopPullDownRefresh();
  },
  // 上拉触底时执行(加载更多)
  onReachBottom() {
    console.log("上拉触底了");
    // 加载更多数据
    this.loadMoreData();
  },

  // 3. 自定义事件处理函数
  // 点击按钮增加计数
  addCount() {
    // 注意:修改data必须用setData,不能直接this.data.count++
    this.setData({
      count: this.data.count + 1
    });
  },
  // 加载更多数据
  loadMoreData() {
    const newData = [
      { id: 4, name: "草莓奶茶", price: 22 }
    ];
    // 合并原有数据和新数据
    this.setData({
      teaList: [...this.data.teaList, ...newData]
    });
  },
  // 跳转页面
  goToDetail(e) {
    const teaId = e.currentTarget.dataset.id;
    // 方式1:保留当前页面,可返回(最多跳10层)
    wx.navigateTo({
      url: `/pages/detail/detail?id=${teaId}` // 传参:id=1
    });
    // 方式2:关闭当前页面,不可返回(适合tabBar页面)
    // wx.redirectTo({
    //   url: `/pages/detail/detail?id=${teaId}`
    // });
    // 方式3:跳转到tabBar页面(只能跳tabBar配置的页面)
    // wx.switchTab({
    //   url: "/pages/index/index"
    // });
  }
});
JS核心知识点:
  1. 修改数据:必须用this.setData({ key: value }),因为小程序的data是响应式的,直接修改不会触发页面更新;
  2. 事件绑定:
    • 绑定点击事件:bindtap="函数名"(冒泡)或catchtap="函数名"(不冒泡);
    • 传参:通过data-*属性传参,比如data-id="{{item.id}}",在事件中用e.currentTarget.dataset.id获取;
  3. 小程序API:用wx.xxx()调用,比如wx.showToast()(提示框)、wx.navigateTo()(跳转)、wx.request()(网络请求),后续实战会详细讲。

三、基础实战:完整制作一个奶茶店小程序

实战目标:制作一个包含“首页(奶茶列表)→详情页(奶茶信息)”的小程序

步骤1:准备素材

在项目根目录新建images文件夹,放入3张图片:

  • pearl-tea.png(珍珠奶茶图片)
  • taro-tea.png(芋泥奶茶图片)
  • matcha-tea.png(抹茶奶茶图片)
步骤2:配置页面路由

app.jsonpages数组中添加详情页:

"pages": [
  "pages/index/index",
  "pages/logs/logs",
  "pages/detail/detail"
]
步骤3:开发首页(index)
index.wxml(结构):
<view class="container">
  <!-- 顶部搜索 -->
  <view class="search-bar">
    <input placeholder="搜索奶茶" class="search-input"></input>
    <button type="default" size="mini">搜索</button>
  </view>
  <!-- 奶茶列表 -->
  <view class="tea-list">
    <view wx:for="{{teaList}}" wx:key="id" class="tea-item" bindtap="goToDetail" data-id="{{item.id}}">
      <image src="{{item.image}}" mode="widthFix" class="tea-img"></image>
      <view class="tea-info">
        <text class="tea-name">{{item.name}}</text>
        <text class="tea-price">¥{{item.price}}</text>
        <text class="tea-stock" wx:if="{{item.stock > 0}}">有货</text>
        <text class="tea-stock out" wx:else>售罄</text>
      </view>
    </view>
  </view>
</view>
index.wxss(样式):
.container {
  padding: 20rpx;
  background-color: #f5f5f5;
  min-height: 100vh;
}
.search-bar {
  display: flex;
  align-items: center;
  background-color: #fff;
  padding: 10rpx;
  border-radius: 10rpx;
  margin-bottom: 20rpx;
}
.search-input {
  flex: 1;
  height: 60rpx;
  padding: 0 10rpx;
  font-size: 28rpx;
}
.tea-list {
  background-color: #fff;
  border-radius: 10rpx;
  padding: 10rpx;
}
.tea-item {
  display: flex;
  align-items: center;
  padding: 20rpx 10rpx;
  border-bottom: 1rpx solid #eee;
}
.tea-item:last-child {
  border-bottom: none;
}
.tea-img {
  width: 120rpx;
  height: 120rpx;
  border-radius: 10rpx;
  margin-right: 20rpx;
}
.tea-info {
  flex: 1;
}
.tea-name {
  font-size: 32rpx;
  display: block;
  margin-bottom: 10rpx;
}
.tea-price {
  color: #ff4400;
  font-size: 30rpx;
  margin-right: 20rpx;
}
.tea-stock {
  font-size: 26rpx;
  color: #07C160;
}
.tea-stock.out {
  color: #999;
}
index.js(逻辑):
Page({
  data: {
    teaList: [
      { id: 1, name: "珍珠奶茶", price: 15, image: "/images/pearl-tea.png", stock: 100 },
      { id: 2, name: "芋泥奶茶", price: 18, image: "/images/taro-tea.png", stock: 50 },
      { id: 3, name: "抹茶奶茶", price: 20, image: "/images/matcha-tea.png", stock: 0 }
    ]
  },
  // 跳转到详情页
  goToDetail(e) {
    const teaId = e.currentTarget.dataset.id;
    // 传参跳转
    wx.navigateTo({
      url: `/pages/detail/detail?id=${teaId}`
    });
  }
});
步骤4:开发详情页(detail)
detail.wxml(结构):
<view class="detail-container">
  <!-- 奶茶图片 -->
  <image src="{{teaInfo.image}}" mode="widthFix" class="detail-img"></image>
  <!-- 奶茶信息 -->
  <view class="detail-info">
    <text class="detail-name">{{teaInfo.name}}</text>
    <text class="detail-price">¥{{teaInfo.price}}</text>
    <text class="detail-desc">{{teaInfo.desc}}</text>
    <view class="detail-stock">库存:{{teaInfo.stock}}杯</view>
    <button bindtap="addToCart" class="buy-btn" wx:if="{{teaInfo.stock > 0}}">加入购物车</button>
    <button class="buy-btn disabled" wx:else disabled>已售罄</button>
    <button bindtap="goBack" class="back-btn">返回首页</button>
  </view>
</view>
detail.wxss(样式):
.detail-container {
  padding: 20rpx;
  background-color: #f5f5f5;
  min-height: 100vh;
}
.detail-img {
  width: 100%;
  height: auto;
  border-radius: 10rpx;
  margin-bottom: 20rpx;
}
.detail-info {
  background-color: #fff;
  padding: 20rpx;
  border-radius: 10rpx;
}
.detail-name {
  font-size: 36rpx;
  font-weight: bold;
  display: block;
  margin-bottom: 10rpx;
}
.detail-price {
  color: #ff4400;
  font-size: 32rpx;
  display: block;
  margin-bottom: 20rpx;
}
.detail-desc {
  font-size: 28rpx;
  color: #666;
  line-height: 1.5;
  margin-bottom: 20rpx;
  display: block;
}
.detail-stock {
  font-size: 28rpx;
  margin-bottom: 30rpx;
}
.buy-btn {
  width: 100%;
  height: 80rpx;
  line-height: 80rpx;
  background-color: #07C160;
  color: #fff;
  border-radius: 10rpx;
  font-size: 32rpx;
  margin-bottom: 20rpx;
}
.buy-btn.disabled {
  background-color: #999;
}
.back-btn {
  width: 100%;
  height: 80rpx;
  line-height: 80rpx;
  background-color: #fff;
  color: #333;
  border: 1rpx solid #eee;
  border-radius: 10rpx;
  font-size: 32rpx;
}
detail.js(逻辑):
Page({
  data: {
    teaInfo: {}
  },
  onLoad(options) {
    // 获取首页传过来的id
    const teaId = options.id;
    // 模拟根据id获取详情数据
    const teaList = [
      { id: 1, name: "珍珠奶茶", price: 15, image: "/images/pearl-tea.png", stock: 100, desc: "经典珍珠奶茶,Q弹珍珠,奶香浓郁" },
      { id: 2, name: "芋泥奶茶", price: 18, image: "/images/taro-tea.png", stock: 50, desc: "手工芋泥,绵密香甜,口感丰富" },
      { id: 3, name: "抹茶奶茶", price: 20, image: "/images/matcha-tea.png", stock: 0, desc: "日式抹茶,微苦回甘,茶香醇厚" }
    ];
    // 找到对应奶茶
    const teaInfo = teaList.find(item => item.id == teaId);
    // 更新数据
    this.setData({ teaInfo });
  },
  // 加入购物车
  addToCart() {
    wx.showToast({
      title: "加入购物车成功",
      icon: "success"
    });
  },
  // 返回首页
  goBack() {
    wx.navigateBack();
  }
});
步骤5:测试运行
  1. 点击开发者工具顶部的“编译”按钮,模拟器会显示首页;
  2. 点击某款奶茶,跳转到详情页,查看是否传参成功;
  3. 点击“加入购物车”,弹出提示;
  4. 点击“返回首页”,回到列表页。

四、核心避坑清单(高频错误)

  1. ❌ 页面路径写错:跳转路径必须以/开头(如/pages/detail/detail),且必须在app.jsonpages数组中;
  2. ❌ 直接修改data:比如this.data.count++,页面不会更新,必须用this.setData({ count: this.data.count + 1 })
  3. ❌ 传参获取错误:事件中传参用e.currentTarget.dataset.xxx,不是e.target.dataset.xxx(target是触发元素,currentTarget是绑定元素);
  4. ❌ 图片路径错误:本地图片路径必须以/开头(如/images/pearl-tea.png),不能写相对路径(../images/pearl-tea.png);
  5. ❌ rpx/px混用:优先用rpx,避免用px导致适配问题;
  6. ❌ 事件名写错:bindtap写成bindTap(小程序是小写),函数名和绑定的不一致;
  7. ❌ wx:key缺失:列表渲染必须加wx:key,推荐用数据的唯一id(如wx:key="id"),不要用index(性能差);
  8. ❌ 忘记开启下拉刷新:在json中设置enablePullDownRefresh: true,否则onPullDownRefresh不触发。

五、调试技巧

  1. Console面板:打印日志找问题,用console.log()输出数据,比如在onLoad中打印options,看是否拿到传参;
  2. AppData面板:查看当前页面的data数据,确认数据是否更新成功;
  3. Network面板:后续学网络请求时,查看请求是否成功、返回数据是否正确;
  4. 真机调试:点击“预览”,生成二维码,用微信扫码,看真机效果(模拟器和真机可能有差异);
  5. 错误提示:编辑器底部会显示语法错误,红色提示是致命错误,黄色是警告,按提示修改。

六、总结

  1. 小程序开发核心是「结构(WXML)+ 样式(WXSS)+ 逻辑(JS)+ 配置(JSON)」,四者配合完成页面开发;
  2. 基础语法重点掌握:数据绑定{{ }}、列表渲染wx:for、事件绑定bindtap、页面跳转wx.navigateTo
  3. 实战关键:先搭结构,再写样式,最后加逻辑,一步一步调试,避免一次性写大量代码;
  4. 新手避坑:重点检查路径、数据修改方式、事件绑定,这三类错误占新手问题的80%;
  5. 进阶方向:后续可学习网络请求(wx.request)、本地存储(wx.setStorage)、支付功能、云开发等。

推荐学习:小程序开发零基础衔接进阶知识点详解【进阶版】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT=>小脑虎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值