微信小程序开发--框架

一.小程序框架介绍

小程序框架包含小程序的配置、框架接口、场景值、WXML 和 WXS等。

二.小程序的配置

小程序的配置分为全局配置页面配置以及sitemap配置。

1.全局配置

小程序根目录下的 app.json文件用来对微信小程序进行全局配置。文件内容为一个JSON对象,有以下属性:

属性类型必填描述
entryPagePathstring小程序默认启动首页
pagesstring[]页面路径列表
windowObject全局的默认窗口表现

微信小程序开发框架之全局配置属性详情

1.entryPagePath

指定小程序的默认启动路径(首页)。如果不填,将默认为 pages列表的第一项

{
  "entryPagePath": "pages/index/index"
}
2.pages

包含了小程序所包含的全部页面以及路径。当我们需要新增加一个页面时,有以下几种方法:

  • 在pages列表中直接添加路径,系统会自动在pages文件夹下新建对应的页面文件。
  • 右键pages文件夹新建一个文件夹user,然后右键user选择新建page
"pages": [
    "pages/index/index",
    "pages/home/home",
    "pages/kind/kind",
    "pages/cart/cart",
    "pages/logs/logs"
],

小程序中新增/减少页面,都需要对 pages 数组进行修改。

注意,当需要改变首页时,直接在pages列表中按住Alt键通过上移下移键即可直接移动。

3.window

用于设置小程序的状态栏、导航条、标题、窗口背景色

对于pageOrientation屏幕样式这个属性:

默认值为portrait,即竖屏显示

auto:在屏幕旋转时,这个页面将随之旋转,显示区域尺寸也会随着屏幕旋转而变化

landscape固定为横屏显示

"window": {
    "navigationBarBackgroundColor": "#0094ff",
    "navigationBarTitleText": "嗨购",
    "navigationBarTextStyle": "white",
    "backgroundColor": "#efefef",
    "backgroundTextStyle": "dark",
    "enablePullDownRefresh": true,
    "onReachBottomDistance": 50,
    "pageOrientation": "auto"
},

注意,对于IOS手机,属性backgroundColor要替换成backgroundColorTopbackgroundColorBottom,因此在单独页面的配置文件中如果想要替换全局配置也要改成backgroundColorTop

4.tabBar

如果小程序是一个多tab应用(客户端窗口的底部或顶部有 tab 栏可以切换页面),可以通过tabBar配置项指定tab栏的表现,以及tab 切换时显示的对应页面。

注意,配置tabBar时尽量要做到首尾呼应(要和头部的颜色保持一致保证美观度)。另外,如果你想要将菜单栏放在顶部,那么可以添加"position":"top",但是这样的话图标就不会显示了。

tabBar中底部菜单栏的图标是图片格式,可以去阿里图标库下载,编写小程序下载png时大小选择81即可。

  "tabBar": {
    "color": "#000",
    "selectedColor": "#0094ff",
    "backgroundColor": "#efefef",
    "borderStyle": "white",
    "list": [
      {
        "pagePath": "pages/index/index",
        "text": "首页",
        "iconPath": "icons/shouye.png",
        "selectedIconPath": "icons/shouye_active.png"
      },
      {
        "pagePath": "pages/kind/kind",
        "text": "分类",
        "iconPath": "icons/fenlei.png",
        "selectedIconPath": "icons/fenlei_active.png"
      },
      {
        "pagePath": "pages/cart/cart",
        "text": "购物车",
        "iconPath": "icons/gouwuche.png",
        "selectedIconPath": "icons/gouwuche_active.png"
      },
      {
        "pagePath": "pages/user/user",
        "text": "我的",
        "iconPath": "icons/wode.png",
        "selectedIconPath": "icons/wode_active.png"
      }
    ],
    "style": "v2",
    "sitemapLocation": "sitemap.json"
  },
5.networkTimeout

各类网络请求的超时时间,单位均为毫秒。

6.debug

可以在开发者工具中开启 debug模式,在开发者工具的控制台面板,调试信息以 info的形式给出,其信息有Page的注册,页面路由,数据更新,事件触发等。可以帮助开发者快速定位一些常见的问题。

7.functionalPages

插件所有者小程序需要设置这一项来启用插件功能页

8.subpackages

启用分包加载时,声明项目分包结构。

9.workers

使用 Worker 处理多线程任务时,设置 Worker代码放置的目录。

10.requiredBackgroundModes

申明需要后台运行的能力,类型为数组。目前支持以下项目:

  • audio: 后台音乐播放
  • location: 后台定位
{
  "pages": ["pages/index/index"],
  "requiredBackgroundModes": ["audio", "location"]
}
11.plugins

声明小程序需要使用的插件

12.preloadRule

声明分包预下载的规则。

13.resizable

在 iPad 上运行的小程序可以设置支持屏幕旋转

在 PC 上运行的小程序,用户可以按照任意比例拖动窗口大小,也可以在小程序菜单中最大化窗口

14.usingComponents

在此处声明的自定义组件视为全局自定义组件,在小程序内的页面或自定义组件中可以直接使用而无需再声明。

15.permission

小程序接口权限相关设置。字段类型为 Object

  "permission": {
    "scope.userLocation": {
      "desc": "你的位置信息将用于小程序位置接口的效果展示" 
    }
  }
16.sitemapLocation

指明 sitemap.json 的位置;默认为 ‘sitemap.json’ 即在 app.json 同级目录下名字的 sitemap.json文件。文件内部大致规定了小程序能否被微信搜索以及哪些页面能够被搜索到。

17.style

微信客户端 7.0 开始,UI 界面进行了大改版。小程序也进行了基础组件的样式升级。app.json 中配置 "style": "v2"可表明启用新版的组件样式

18.useExtendedLib

指定需要引用的扩展库。目前支持以下项目:

指定后,相当于引入了对应扩展库相关的最新版本的 npm 包,同时也不占用小程序的包体积。rc工具版本支持分包引用。用法如下:

{
  "useExtendedLib": {
    "kbone": true,
    "weui": true
  }
}
19.entranceDeclare

聊天位置消息用打车类小程序打开。

"entranceDeclare": {
    "locationMessage": {
        "path": "pages/index/index",
        "query": "foo=bar"
    }
}
20.darkmode

可通过配置"darkmode": true表示当前小程序可适配DarkMode,所有基础组件均会根据系统主题展示不同的默认样式navigation bartab bar也会根据开发者的配置自动切换。

配置后,请根据DarkMode 适配指南自行完成基础样式以外的适配工作。

{
  "darkmode": true
}
21.themeLocation

自定义 theme.json 的路径,当配置"darkmode":true时,当前配置文件为必填项。

{
  "themeLocation": "/path/to/theme.json"
}
22.lazyCodeLoading

通常情况下,在小程序启动期间,所有页面及自定义组件的代码都会进行注入,当前页面没有使用到的自定义组件和页面在注入后其实并没有被使用。

自基础库版本 2.11.1 起,小程序支持有选择地注入必要的代码,以降低小程序的启动时间和运行时内存。

{
  "lazyCodeLoading": "requiredComponents"
}

当配置了这一项时,小程序仅注入当前页面需要的自定义组件和页面代码,在页面中必然不会用到的自定义组件不会被加载和初始化。

注意:添加这项配置后,未使用到的代码文件将不被执行。

23.singlePage

单页模式相关配置

24.navigateToMinProgramAppIdList

当小程序需要使用 wx.navigateToMiniProgram接口跳转到其他小程序时,需要先在配置文件中声明需要跳转的小程序appId列表,最多允许填写10个。

"navigateToMinProgramAppIdList" : [
	"...",
	"..."
]

2.页面配置

每一个小程序页面也可以使用 .json文件来对本页面的窗口表现进行配置。页面中配置项在当前页面会覆盖 app.jsonwindow中相同的配置项。文件内容为一个JSON对象。

页面配置其实和全局配置差不多,如果配置了和全局一样的属性那么就会覆盖全局属性,更换效果

小程序框架的页面配置

3.sitemap配置

小程序根目录下的 sitemap.json文件用于配置小程序及其页面是否允许被微信索引,文件内容为一个JSON对象,如果没有 sitemap.json,则默认为所有页面都允许被索引

小程序sitemap配置

{
  "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
  "rules": [{
  "action": "allow",
  "page": "*"
  }]
}

三.小程序框架接口

1.小程序APP

1.App(Object object)

注册小程序。接受一个Object参数,其指定小程序的生命周期回调等。

App() 用于注册小程序,必须在app.js中调用,必须调用且只能调用一次。不然会出现无法预期的后果。

//app.js
App({
  onLaunch: function () {
    // 展示本地存储能力
    var logs = wx.getStorageSync('logs') || []
    logs.unshift(Date.now())
    wx.setStorageSync('logs', logs)

    // 登录
    wx.login({
      success: res => {
        // 发送 res.code 到后台换取 openId, sessionKey, unionId
      }
    })
    // 获取用户信息
    wx.getSetting({
      success: res => {
        if (res.authSetting['scope.userInfo']) {
          // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
          wx.getUserInfo({
            success: res => {
              // 可以将 res 发送给后台解码出 unionId
              this.globalData.userInfo = res.userInfo

              // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
              // 所以此处加入 callback 以防止这种情况
              if (this.userInfoReadyCallback) {
                this.userInfoReadyCallback(res)
              }
            }
          })
        }
      }
    })
  },
  globalData: {
    userInfo: null
  }
})
2.AppObject getApp(Object object)

获取到小程序全局唯一的App实例,在页面的JS文件中获取。

//index.js
//获取应用实例
const app = getApp()
console.log(app)

2.页面

1.Page(Object object)

注册小程序中的一个页面。接受一个Object类型参数,其指定页面的初始数据、生命周期回调、事件处理函数等。

// pages/kind/kind.js
Page({

  /**
   * 页面的初始数据
   */
  data: {

  },

  /**
   * 生命周期函数--监听页面加载------请求数据
   */
  onLoad: function (options) {

  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  //页面相关事件处理函数---监听用户下拉刷新事件(重新请求了第一页的页面数据)
  onPullDownRefresh: function() {
    console.log("刷新了当前页面")
  },

    //上拉触底事件函数
  /**
   * 上拉加载---分页效果
   */
  onReachBottom: function() {
    console.log("对不起已经到底了")
  },

  /**
   * 用户点击右上角的分享按钮
   * 可以通过微信提供的api修改分享的内容
   */
  onShareAppMessage: function() {
    console.log("你准备好分享了吗")
  },
  /**
   * 页面滚动事件的处理函数 
   * 默认的参数就是滚动条距离顶部的距离  ---  可以写成options
   * 应用:滚动到某一个位置,返回顶部的按钮
   */
  onPageScroll (event) {
    console.log("页面正在滚动")
    console.log(event)
  },
   /**
   * 当前是 tab 页时,点击 tab 时触发
   * tab就是全局配置时的底部菜单栏
   */
  onTabItemTap () {
    console.log("首页")
  },
})

小程序加载时的执行顺序为:onLoad,onShiw,onReady

2.getCurrentPages()

PageObject[] getCurrentPages()

获取当前页面栈。数组中第一个元素为首页,最后一个元素为当前页面

注意:

  • 不要尝试修改页面栈,会导致路由以及页面状态错误。
  • 不要在 App.onLaunch的时候调用 getCurrentPages(),此时page还没有生成。

3.自定义组件

1.Component(Object object)

创建自定义组件,接受一个Object类型的参数。

步骤:新建一个文件夹components存放所有组件,然后再新建一个文件夹存放某个特定的组件(一般一个组件单独存放在一个文件夹中,便于管理),接着新建Components就会得到对应的四个文件(wxml,wxss,js,json),json文件中相比于页面多了一条语句:

"component": true,

这条语句就指明了当前文件是一个组件

接着在需要显示组件的页面的JSON文件中写入:

  "usingComponents": {
     //prolist一般就是组件名,后面跟上绝对路径
    "prolist": "/components/prolist/prolist"
  }

完事之后在可以在原页面使用标签的形式将组件给添加到页面中去:

<prolist></prolist>
// <prolist />  单标签的形式也可以

注意,如果在原页面有css样式的需要重新**剪切到组件对应的css样式文件(prolist.wxss)**中去。

组件其实就是包含了视图的模块

至此为止完成了自定义组件以及使用

4.模块化

建议使用es6的模块化方法,api中提供的是基于commonjs规范的exports以及require语法。

1.定义工具模块 utils/index.js

数据请求模块以及可消失的提示框模块 - 暴露。

const baseUrl = 'http://daxun.kuboy.top'
/**
 * 数据请求模块
 * 接口地址 http://daxun.kuboy.top/apidoc
 * 先显示加载框,然后请求结束加载框消失
 * 
 */
export function request (url, data) {
  // 显示加载中
  // 参考https://developers.weixin.qq.com/miniprogram/dev/api/ui/interaction/wx.showLoading.html
  wx.showLoading({
    title: '加载中',
  })
  // 使用promise 解决异步操作问题,此处还可以使用 async + await
  return new Promise((resolve, reject) => {
    // 微信小程序的数据请求方法
    // 必须配置小程序的安全域名,
    // 在开发阶段可以在“详情” - “本地设置” - 勾选中 不校验请求域名、web-view(业务域名)、TLS版本及HTTPS证书
    wx.request({
      url: baseUrl + url,
      data: data || {},
      success: (res) => {
        // 隐藏加载中
        wx.hideLoading();
        // 后续处理
        resolve(res.data)
      },
      // 异步操作执行失败的操作
      fail : (err) => {
        reject(err)
      }
    })
  })
}

/**
 * 可消失的提示框 - 默认只显示文字
 * str 提示内容
 * icon 是否需要图标,none 、 success(默认值) 、 loading
 */
export function Toast (str, icon) {
  // 微信提供的API接口
  // 参照 https://developers.weixin.qq.com/miniprogram/dev/api/ui/interaction/wx.showToast.html
  wx.showToast({
    title: str,
    icon: icon || 'none'
  })
}
2.在首页中测试

在首页的index.js中的onLoad函数中进行数据的请求:

// 请求数据
request({
	url : '/pro',
	data : {}
}).then((res) => { //then是请求成功后的处理方法
	console.log(res)
}).catch((err) => { //catch是请求失败后的处理方法
	console.log(err)
})

四.WXML语法

新建一个测试页面:pages/test/test,但是在tabBar中并没有路由链接到新的测试页面。

解决方法:在普通编译处选择添加编译模式,然后选择新建页面的路径pages/test/test,点击完成即可直接编译出新建的页面,省去了路由链接的环节。

1.数据绑定

1.简单绑定

WXML中的动态数据均来自对应Pagedata

Page({
  data: {
    message: 'Hello MINA!'
  }
})

对应的WXML中显示数据的语法为:{{}}

<view> {{ message }} </view>
2.组件属性

小程序对于组件标签的属性绑定其实就是将vuereact二者相结合。

<!-- vue 绑定属性 :class="message" -->
<!-- react 绑定属性 class={message} -->
<view class="{{message}}">
  组件属性
</view>
3.控制属性
data: {
    message: "hello world",
    flag: true
},
<!-- 控制属性 -->
<!-- vue v-if="flag" -->
<!-- wx:if  wx:elif  wx:else -->
<view wx:if="{{ flag }}">
  如果flag为真我就显示
</view>
4.boolean以及number数据类型

如果数据类型是booblean或者number类型的数据,需要使用```{{}}````包裹。

<checkbox checked="{{ flag }}"></checkbox> //被选中
<checkbox checked="true"></checkbox> //被选中
<checkbox checked="false"></checkbox> //被选中,说明false单独写在双引号中是没用的
<checkbox checked="{{ !flag }}"></checkbox> //未被选中
5.表达式

表达式运算 可以在{{}}内进行简单的运算,支持三元运算、算数运算、逻辑判断、字符串运算等。

  data: {
    message: "hello world",
    flag: true,
    number:30,
    a:1,
    b:10,
    c:100,
    len:15,
    name: "curry"
  },
<!-- 表达式 -->
<view>{{ 1 + 2 + 3 }}</view>
<!-- 下面的表达式未被解析,微信小程序不太支持js -->
<view>{{ message.split('').reverse().join('') }}</view>
<view test="{{flag ? true : false}}"> 属性 </view>
<view> {{a + b}} + {{c}} + d </view>
<view wx:if="{{len > 5}}">Steph Curry</view>
<view>{{"hello" + name}}</view>

2.列表渲染

1.单层循环
list:[
      "库里",
      "汤普森",
      "杜兰特",
      "格林",
      "伊戈达拉"
]

wx:for="{{ list }}"中仅需指明循环的数据来源即可,不需要声明元素名item以及索引值index

<!-- 一层循环 -->
<view wx:for="{{ list }}" wx:key="index">
  <text>{{ index }}</text>---<text>{{ item }}</text>
</view>
2.双层循环
carlist:[
    {
        brand: "宝马",
        typelist: ['x5','x6']
    },
    {
        brand: "奔驰",
        typelist: ['A4','Q7']
    }
]
<!-- 两层循环
wx:for-item="itm" ---  重新指定元素名
wx:for-item="idx" ---  重新指定索引值
-->
<view wx:for="{{ carlist }}">
  {{ brand }}
  //为了避免混淆两层循环中的元素名item,可以重新命名
  <view wx:for="{{item}}" wx:for-item="itm"  wx:for-index="idx" wx:key="idx"> 
    <view>{{ itm }}</view>
  </view>
</view>

注意,不管是单层循环还是双层循环,都不能忘记加上wx:key关键字,里面的值如果没有指定那就填索引值index。注意,之前wx:key关键字的写法是wx:key="{{ index }}",但是后面更新过一次,如果有报错信息那就去掉双括号:wx:key="index"

3.条件渲染

wx:if在框架中,使用wx:if=""来判断是否需要渲染该代码块

<view wx:if="{{flag}}"> True </view>

也可以用wx:elifwx:else来添加一个else块:

<view wx:if="{{len > 5}}"> 1 </view>
<view wx:elif="{{len > 2}}"> 2 </view>
<view wx:else> 3 </view>

因为wx:if是一个控制属性,需要将它添加到一个标签上。如果要一次性判断多个组件标签,可以使用一个<block/>标签将多个组件包装起来,并在上边使用wx:if控制属性:

<block wx:if="{{true}}">
  <view> view1 </view>
  <view> view2 </view>
</block>

注意:<block/>并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性

wx:if vs hidden — (对比vue中的v-if与v-show)

因为wx:if之中的模板也可能包含数据绑定,所以当wx:if的条件值切换时,框架有一个局部渲染的过程,因为它会确保条件块在切换时销毁或重新渲染。

同时wx:if也是惰性的,如果在初始渲染条件为 false,框架什么也不做,在条件第一次变成真的时候才开始局部渲染。

相比之下,hidden就简单的多,组件始终会被渲染,只是简单的控制显示与隐藏

一般来说wx:if有更高的切换消耗而 hidden 有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用 hidden 更好,如果在运行时条件不大可能改变wx:if较好。

四.WXS语法

**WXS(WeiXin Script)**是小程序的一套脚本语言,结合WXML,可以构建出页面的结构。

WXS 与 JavaScript 是不同的语言,有自己的语法,并不和JavaScript一致

熟悉js语法的可以很快速的接收并且掌握它。

五.WXSS语法

WXSS (WeiXin Style Sheets)是一套样式语言(CSS),用于描述WXML的组件样式。

WXSS 用来决定WXML的组件应该怎么显示。

为了适应广大的前端开发者,WXSS具有CSS大部分特性。同时为了更适合开发微信小程序,WXSS 对 CSS 进行了扩充以及修改

与 CSS 相比,WXSS 扩展的特性有:

  • 尺寸单位

  • 样式导入

1.尺寸单位

rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素

设备rpx换算px (屏幕宽度/750)px换算rpx (750/屏幕宽度)
iPhone51rpx = 0.42px1px = 2.34rpx
iPhone61rpx = 0.5px1px = 2rpx
iPhone6 Plus1rpx = 0.552px1px = 1.81rpx

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

注意: 在较小的屏幕上不可避免的会有一些毛刺,请在开发时尽量避免这种情况

2.样式导入

使用@import语句可以导入外联样式表@import后跟需要导入的外联样式表的相对路径,用;表示语句结束

3.全局样式与局部样式

WXSS具有CSS大部分特性。同时为了更适合开发微信小程序,WXSS 对 CSS 进行了扩充以及修改

与 CSS 相比,WXSS 扩展的特性有:

  • 尺寸单位

  • 样式导入

1.尺寸单位

rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素

设备rpx换算px (屏幕宽度/750)px换算rpx (750/屏幕宽度)
iPhone51rpx = 0.42px1px = 2.34rpx
iPhone61rpx = 0.5px1px = 2rpx
iPhone6 Plus1rpx = 0.552px1px = 1.81rpx

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

注意: 在较小的屏幕上不可避免的会有一些毛刺,请在开发时尽量避免这种情况

2.样式导入

使用@import语句可以导入外联样式表@import后跟需要导入的外联样式表的相对路径,用;表示语句结束

3.全局样式与局部样式

定义在app.wxss中的样式为全局样式,作用于每一个页面。在pagwxss文件中定义的*样式为局部样式,只作用在对应的页面,并会覆盖app.wxss中相同的选择器(局部样式会覆盖全局样式)。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
微信小程序是一种基于微信平台的应用的开发模式,可以快速的开发出符合用户需求的小程序。在小程序开发中,组件是一个非常重要的概念,通过组件可以实现复用性和模块化编程思想。 组件应用是小程序开发的基础。通过组件可以将某一模块化并封装起来,使得组件可以在不同的页面间得到复用,大大提升了开发效率并减少了代码冗余。微信小程序提供了丰富的自带组件,包括文本、图片、按钮、输入框等等,开发者也可以自己开发组件来满足自己的需求。实际开发中,通过组件可以快速搭建页面框架和业务逻辑。 Demo是一个演示小程序的示例程序。在小程序的实际开发过程中,一个好的Demo非常重要。通过Demo,开发人员可以更深入的了解小程序开发流程、组件的应用和实际的业务开发等等。在Demo中,通常会包括小程序的一些基础操作,如页面跳转、数据绑定、组件的使用等。而在实际开发中,Demo还会包括一些复杂的业务场景,如支付、登录、数据列表展示等等。Demo不仅为开发者提供了学习和实践的机会,也方便了使用者了解该小程序的功能和特点。 总之,微信小程序组件的应用和Demo的开发都是小程序开发过程中非常重要的两个部分。良好的组件应用和精心设计的Demo,可以在极短的时间内实现小程序开发

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

偶尔躲躲乌云_0

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

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

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

打赏作者

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

抵扣说明:

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

余额充值