微信小程序常见知识点

  • 1、对微信小程序的理解
  • 2、小程序中wxss和css的异同
  • 3、小程序中的模板语法WXML(标签、数据、渲染)
    • 1. 标签的使用
    • 2. 数据绑定
    • 3. 数据渲染
    • 4. 逻辑渲染
    • 5. 列表渲染
    • 6. template(模板)
    • 7. 引用
  • 4、小程序中的生命周期函数有哪些?(APP、Page、Component)
    • 1. APP的生命周期
    • 2. Page的生命周期
    • 3. Component的生命周期
  • 5、小程序中事件定义与传参
    • 1. 事件定义:
    • 2. 事件传参
  • 6、小程序中常见的界面跳转的方式,以及区别?
  • 7、小程序中如何修改data上的数据?
  • 8、小程序中如何进行本地存储?
  • 9、小程序中界面跳转如何传递参数?如何获取这些参数?
  • 10、小程序中如何进行父子组件传参?
  • 11、对Behaviors的理解
  • 12、谈谈你关于组件封装的心得
    • 理解:
    • 优点:
  • 13、怎么封装小程序的数据请求
  • 14、如何提高小程序的加载速度?
  • 15、微信小程序常见的开放能力API有哪些?
  • 16、对WebSocket的理解
  • 17、瀑布流的实现


1、对微信小程序的理解

小程序是一种开放能力,开发者可以快速地开发一个小程序。小程序可以在微信内被便捷的获取和传播,同时具有出色的使用体验。

微信小程序的优势:

  1. 微信助理,容易推广。小程序拥有众多入口,这些入口有助于企业更好的获取流量,从而进行转化、变现。
  2. 使用便捷。用户在使用小程序时,只需要轻轻点一下就可以使用,更加符合用户对使用方便、快捷的需求,所以小程序的用户数量不断增加。
  3. 体验良好,有接近原生app的体验。。在微信生态里,小程序在功能和体验上是可以秒杀掉 H5 页面的,H5 页面经常出现卡顿、延时、加载慢、权限不足等原因,而这些问题在小程序里都不会出现。
  4. 成本更低。从开发成本到运营推广成本,小程序的花费仅为APP的十分之一,无论是对创业者还是传统商家来说都是一大优势。

微信小程序的劣势:

  1. 单个包大小限制为2M,这导致无法开发大型的应用,采用分包最大是20M(这个值一直在变化,以官网为准)。
  2. 需要像app一样审核上架,这点相对于H5的发布要麻烦一些。
  3. 处处受微信限制。例如不能直接分享到朋友圈,涉及到积分,或者虚拟交易的时候,小程序也是不允许的。

2、小程序中wxss和css的异同

WXSS和CSS类似,不过在CSS的基础上做了一些补充和修改

  1. 尺寸单位 rpx:rpx是响应式像素,可以根据屏幕宽度进行自适应。规定屏幕宽度为750rpx。在不同的手机型号下1rpx=屏幕宽度/750。(phone6下1rpx = 0.5px)
  2. 样式导入import:可以@import来导入其他的wxss
  3. 样式选择器:类选择器、id选择器、元素选择器、伪元素选择器
@import './test_0.wxss'

3、小程序中的模板语法WXML(标签、数据、渲染)

1. 标签的使用

在小程序中没有H5提供的那些标签了,这里我们需要使用小程序给我们提供的组件。常用的标签有

  1. view:相当于div;
  2. text:相当于span;
  3. image:相当于img

2. 数据绑定

  1. 数据定义:
  2. 引用数据:通过{{}}的方式可以引用数据。
    小程序中任何需要获取数据的地方都需要用{{}},包括标签内的属性。
data:{
	return {
		msg:"hello world",
		num: 18,
	}
  }

3. 数据渲染

  1. 渲染层和数据相关。
  2. 逻辑层负责产生、处理数据。
  3. 逻辑层通过 Page 实例的 setData 方法传递数据到渲染层。
<view>{{ msg }}</view>
Page({
  data:{
	return {
		msg:"hello world",
		num: 18,
	}
  }
  onLoad: function () {
    this.setData({ msg: 'Hello World2222' })
  }
})

4. 逻辑渲染

wx:if和hidden文章来源地址:https://www.yii666.com/blog/478275.html

  1. wx:if:WXML 中,使用 wx:if=“{{condition}}” 来判断是否需要渲染该代码块
    如果要一次性判断多个组件标签,可以使用一个 标签将多个组件包装起来,并在上边使用 wx:if 控制属性。
  2. hidden:通过hidden属性也可以进行条件渲染。
  3. wx:if和hidden的异同:
    同:都能控制元素的显示与隐藏
    异:wx:if在不满足条件的时候会删除掉对应的DOM,hidden属性则是通过display属性设置为none来进行条件渲染。
<view wx:if="{{length > 5}}"> 1 </view>
<view wx:elif="{{length > 2}}"> 2 </view>
<view wx:else> 3 </view>

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

<view hidden="{{condition}}">
隐藏
</view>

5. 列表渲染

wx:for :在组件上使用 wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item。
wx:for-index, wx:for-item 用来指定index和item的别名

wx:key:指定列表中项目的唯一的标识符。
要求:需要是列表中唯一的字符串或数字;保留关键字 this: 代表在 for 循环中的 item 本身,并且item本身是唯一的字符串或者数字
作用:能提高重排效率文章地址https://www.yii666.com/blog/478275.html

<!-- array 是一个数组 -->
<view wx:for="{{index in array}}" wx:key="{{index}}">
  {{index}}: {{item.name}}
</view>
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
  {{idx}}: {{itemName.name}}
</view>

对应的脚本文件:
Page({
  data: {
    array: [{
      name: '天亮教育',
    }, {
      name: '尚云科技'
    }]
  }
})

6. template(模板)

WXML提供模板(template),可以在模板中定义代码片段,然后在不同的地方调用。使用 name 属性,作为模板的名字。然后在 内定义代码片段。
使用 is 属性,声明需要的使用的模板,然后将模板所需要的 data 传入。

定义
<template name="msgItem">
  <view>
    <text> {{index}}: {{msg}} </text>
    <text> Time: {{time}} </text>
  </view>
</template>
调用
<!-- msgList:[
      {
        index: 0,
        msg: '这是一段模板',
        time: '2020-10-10'
      }
    ] -->
<view wx:for="{{msgList}}">
  <template is="msgItem" data="{{...item}}"></template>
</view>

7. 引用

WXML 提供两种文件引用方式import和include。

  1. import:可以在该文件中使用目标文件定义的 template
    需要注意的是 import 有作用域的概念,即只会 import 目标文件中定义的 template,而不会 import 目标文件中 import 的 template,简言之就是 import 不具有递归的特性。
在 item.wxml 中定义了一个叫 item的 template :
<!-- item.wxml -->
<template name="item">
  <text>{{text}}</text>
</template>
在 index.wxml 中引用了 item.wxml,就可以使用 item模板:
<import src="item.wxml"/>

<template is="item" data="{{text: '测试'}}"/>
  1. include:include 可以将目标文件中除了 <template/> <wxs/> 外的整个代码引入,相当于是拷贝到 include 位置。
index.wxml
<include src="header.wxml"/>
<view> body </view>
<include src="footer.wxml"/>

header.wxml
<view> header </view>

footer.wxml
<view> footer </view>

4、小程序中的生命周期函数有哪些?(APP、Page、Component)

1. APP的生命周期

  1. onLaunch()
    小程序初始化完成时触发,全局只触发一次。参数也可以使用wx.getLaunchOptionsSync 获取。
    一般在这个生命周期函数中执行 全局数据 的初始化操作
  2. onShow()
    小程序启动,或从后台进入前台显示时触发,可以触发多次
    也可以使用 wx.onAppShow 绑定监听。
  3. onHide()
    小程序从前台进入后台时触发,可以触发多次。也可以使用 wx.onAppHide 绑定监听。
  /*当小程序初始化时,触发(全局只触发一次)*/
  onLaunch: function () {},
  /*当小程序启动,或从后台进入前台显示时触发*/
  onShow:function(options){},
  /*当小程序从前台进入后台时触发*/
  onHide:function(){}

2. Page的生命周期

打开页面的加载顺序:onLoad,onShow,onReady
切换页面时只会加载onShow,onHide

  1. onLoad(options)
    页面加载时触发。只触发一次,可以在 options中获取到界面跳转的参数。
    一般在这个生命周期函数中执行当前页面中的data的初始化操作和判断所需的全局状态(如用户登录状态)等。
  2. onShow()
    页面显示时触发,可触发多次
  3. onReady()
    页面初次渲染完成时触发。只触发一次,代表页面已经准备妥当,可以和视图层进行交互
    注意:对界面内容进行设置的 API 如 wx.setNavigationBarTitle,请在onReady之后进行。
  4. onHide()
    页面隐藏时触发。 如 wx.navigateTo 或底部 tab 切换到其他页面,小程序切入后台等,可触发多次
  5. onUnload()
    页面卸载时触发。如 wx.redirectTo 或 wx.navigateBack 到其他页面时。 一般在这个生命周期函数中执行清除定时器、closeSocket等操作。
  /* 监听页面加载*/
  onLoad: function (options) {},
  /*监听页面初次渲染完成*/
  onReady: function () {},
  /*监听页面显示*/
  onShow: function () {},
  /*监听页面隐藏*/
  onHide: function () {},
  /*监听页面卸载*/
  onUnload: function () {},

3. Component的生命周期

微信小程序的组件中的生命周期函数有以下六种,其中最重要的是 created、attached、detached

  1. created:创建
  2. attached :在页面打开
  3. detached:在页面移除

在这里插入图片描述

  1. created()
    组件实例刚刚被创建好时, created 生命周期被触发,此时还不能调用 setData
    通常情况下,这个生命周期只应该用于给组件添加一些自定义属性字段。
  2. attached()
    在组件完全初始化完毕、进入页面节点树后, attached 生命周期被触发。此时, this.data已被初始化为组件的当前值。
    这个生命周期很有用,绝大多数初始化工作可以在这个时机进行。
  3. detached()
    在组件离开页面节点树后, detached 生命周期被触发。退出一个页面时,如果组件还在页面节点树中,则 detached 会被触发。(页面节点树即组成页面的所有元素的集合。)
Component({
  /*生命周期函数*/
  lifetimes: {
    created:function(){
      //组件被创建时执行
    },
    attached: function () {
      // 在组件实例进入页面节点树时执行
    },
    detached: function () {
      // 在组件实例被从页面节点树移除时执行
    },
  },
  // 以下是旧式的定义方式,可以保持对 <2.2.3 版本基础库的兼容
  created: function () {
    //组件被创建
  },
  attached: function () {
    // 在组件实例进入页面节点树时执行
  },
  detached: function () {
    // 在组件实例被从页面节点树移除时执行
  },
})

5、小程序中事件定义与传参

1. 事件定义:

  1. bind:加自定义事件,如:bind:tap=“执行函数”
    在小程序中绑定事件可以以bind开头然后跟上事件的类型,如bindtap绑定一个点击事件,对应的值是一个字符串,需要在page构造器中定义同名函数,每次触发事件之后就会执行对应函数的内容。
  2. catch:阻止事件冒泡
  3. capture-bind:事件捕获

2. 事件传参

事件传参:data-加自定义=‘自定义‘ 。 参数在在自定义事件中的参数e中获取
参数e中target和currentTarget的区别:currentTarget为当前事件所绑定的组件,而target则是触发该事件的源头组件。

<view bindtap="handleTap">点击事件</view>

<view catch:tap="handleTap">另一种写法</view>

<view capture-bind:tap="handleTap">另一种写法</view>

<!-- data-参数名=’参数值’ -->
<view bindtap="handleTap" data-msg="我是事件的参数">点击事件</view>
// pages/my/index.js
Page({
  handleTap(){
    console.log("执行了点击事件");
	// 通过currentTarget中的dataset属性可以获取时间参数
    console.log(e.currentTarget.dataset.msg);
  }
})

6、小程序中常见的界面跳转的方式,以及区别?


方式区别
<navigator >open-type属性决定跳转方式
wx.navigateTo保留当前页面,只能打开非 tabBar 页面。
wx.redirectTo关闭卸载当前页面,只能打开非 tabBar 页面。
wx.switchTab关闭所有非tabbar页面, 只能打开 tabBar 页面。
wx.reLaunch关闭卸载所有页面,可以打开任意页面。
wx.navigateBack返回前面的页面,可以指定返回多少页,如果用过redirectTo,那么被关
<navigator url=”页面地址” target=“self” open-type=“reLaunch”><navigator>
wx.navigateTo({
  url: 'test?id=1',
})
wx.redirectTo({
  url: 'test?id=1'
})
wx.switchTab({
  url: '/index'
})
wx.reLaunch({
  url: 'test?id=1'
})
wx.navigateBack({
  delta: 2  //返回的页面数,如果 delta 大于现有页面数,则返回到首页。
})

7、小程序中如何修改data上的数据?

在js文件中,this.data.变量修改,只可以修改逻辑层的数据,渲染层不会改变
用app实例的this.setData()方法修改data数据逻辑层和渲染层的数据都会更新

8、小程序中如何进行本地存储?

1. 异步:网址:yii666.com<

异步存储:wx.setStorage({
         key:“key”,
         data:‘value’
          })
异步获取:wx.getStorage({‘key’})文章来源地址https://www.yii666.com/blog/478275.html

2. 同步:

同步存储:wx.setStorageSync(‘key’,‘data’)
同步获取:wx.gettStorageSync(‘key’)

9、小程序中界面跳转如何传递参数?如何获取这些参数?

传参分为声明式和函数式
注意:wx.switchTab和wx.navigateBack不能传递参数
获取参数:通过跳转界面onLoad方法的options参数可以获取到路由传参

声明式:
<navigator url='url?id=1'></navigator>
<navigator url='url?id={{变量名}}'></navigator>
函数式:
toPath(){
  wx.navigateTo({
url:'url?id=123',
})
}
toPath(){
  wx.navigateTo({
url:'url?id={{变量名}}',
})
}

10、小程序中如何进行父子组件传参?

父传子:

在父页面中:
<son msg=’hello’></son>
<son></son>
       子组件接收:
       properties:{
       msg:{
          type:[String,Number],
          value:’hello world’,
       }
       }
子组件:
<view>{{msg}}</view>
 
打印结果:
hello
hello world

子传父:

父页面:
<son bind:fromson=’fromson’></son>
子组件:
<button bindtap=’tofather’>子传父</button>
子组件中触发:
methods:{
		tofather(){
			this.triggerEvent(‘fromson’,’111’)
		}
}
父组件接收子组件参数:
	fromson(res){
		console.log(res.detail)
		this.setData({
			“fromson”:res.detail
		})
	}

11、对Behaviors的理解

  • Behaviors是用于组件间代码共享的特性,类似于 “mixins”。
  • behavior 可以包含一组属性、数据、生命周期函数和方法
    属性:myBehaviorProperty
    数据字段:myBehaviorData
    方法:myBehaviorMethod
    生命周期函数:attached、created、ready
//注册一个 behavior,接受一个 Object 类型的参数
// 组件中的参数一样
module.exports = Behavior({
  data:{
    Behavior:"Behavior",
    msg:"behavior",
    obj:{
      msg:"behavior"
    }
  },
  created(){
    console.log('created-Behavior');
  },
 })
//  在son中用Behavior
//son.js
import Behavior from "../../behaviors/behavior"
Component({
  // 用Behavior
  behaviors:[Behavior],
  // 组件的属性或方法会覆盖 behavior 中的同名属性或方法;
  data: {
    // 有同名的数据字段,对象类型,会进行对象合并,其他会覆盖
    msg:"son",
    obj:{
      id:2,
      msg:'son'
    }
  },
  // 组件和Behavior的生命周期不会覆盖,会合并
  created(){
    console.log('created-son');
  },

12、谈谈你关于组件封装的心得

理解:

在开发项目的过程中经常遇到有些界面的UI元素是可以复用的,这个时候可以考虑把这些UI元素抽象成组件
在开发过程中也会发现有些界面比较复杂,写起来比较麻烦,而且,单个文件的代码量过多也不利于后期维护,这是就可以按照功能拆分之前的界面元素,每个组件单独维护这个组件的功能,将复杂的问题拆解成一个个小问题,提高了代码的可维护性。

优点:

高内聚低耦合;
避免了代码间的冲突;
容易维护;
提高开发效率,
方便重复利用,
提高可维护性;网址:yii666.com

13、怎么封装小程序的数据请求

小程序接口请求:wx.request
不会跨域,因为不是浏览器,没有同源策略

封装请求

  function request(options) {
  // 请求拦截器
  //  ...
  // 加一些统一的参数,或者配置
  if (!options.url.startsWith("https://") &&!options.url.startsWith("http://")) {
    options.url = "https://showme2.myhope365.com" + options.url
  }
    // 默认的请求头
  let header = {
    "cookie": wx.getStorageSync("cookie") || "",
    "content-type": "application/x-www-form-urlencoded",
  };
  if (options.header) {
    header = {
      ...header,
      ...options.header
    }
  }

  return new Promise((reslove, reject) => {
    // 调用接口
    wx.request({
      // 默认的配置
      // 加载传入的配置
      ...options,
      header,
      success(res) {
        // 响应拦截器,所有接口获取数据之前,都会先执行这里
        //  1. 统一的错误处理
        if (res.statusCode != 200) {
          wx.showToast({
            title: '服务器异常,请联系管理员',
          })
        }

        reslove(res)
      },
      fail(err) {
        reject(err)
      }
    })
  })
}
//封装get请求
export function get(url, options = {}) {
  return request({
    url,
    ...options
  })
}
//封装post请求
export function post(url, data, options = {}) {
  return request({
    url,
    data,
    method: "POST",
    ...options
  })
}

14、如何提高小程序的加载速度?

1、控制代码包的大小: (1)代码包的体积压缩可以通过勾选开发者工具中“上传代码时,压缩代码”选项(2)及时清理无用的代码和资源文件(3)减少资源包中的图片等资源的数量和大小
2、分包加载,预加载: 将用户访问率高的页面放在主包里,将访问率低的页面放入子包里,按需加载;采用子包预加载技术,并不需要等到用户点击到子包页面后在下载子包
3、预请求: 请求可以在页面onLoad就加载,不需要等页面ready后在异步请求数据;尽量减少不必要的https请求,可使用 getStorageSync() 及 setStorageSync() 方法将数据存储在本地
4、避免不当的使用setData:
不要过于频繁调用setData,应考虑将多次setData合并成一次setData调用 5、使用自定义组件:
对于一些独立的模块我们尽可能抽离出来,这是因为自定义组件的更新并不会影响页面上其他元素的更新;各个组件也将具有各自独立的逻辑空间。每个组件都分别拥有自己的独立的数据、setData调用

15、微信小程序常见的开放能力API有哪些?

API作用
wx.getNetworkType({})检查网络类型,例如:wifi,5g,4g,3g,2g等
wx.downloadFile({})从网络上下载文档
wx.scanCode({})扫一扫
wx.canIUse()判断小程序的API,回调,参数,组件等是否在当前版本可用。返回值为布尔类型。
wx.getUserProfile获取用户信息。每次请求都会弹出授权窗口,用户同意后返回 userInfo。
wx.getUserInfo获取用户信息。//已经停止使用

16、对WebSocket的理解

最典型的例子:聊天室

由于http只能是单向发起的,只能由客户端主动发起,服务端被动响应。服务端无法主动向客户端发送消息,如果想实现类似于聊天室这种即时通讯的功能,就需要使用消息轮询。轮询的效率低,比较消耗资源。
WebSocket最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。

而WebSocket协议具有以下特点:(可以更好的实现即时通讯)
1、 webSocket是一种在单个TCP连接上进行全双工通信的协议
2、websocket建立连接时,数据是通过http传输的,建立连接后就不需要http协议了。
3、websocket建立连接后就是全双工模式,也是基于tcp协议。
4、建立连接之后,不必在客户端发送request之后服务器才能返回信息到浏览器,这时候服务器有主动权,允许可以随时发消息给客户端
5、发送的信息中不必带有head部分信息了,相对于http来说,降低了服务器的压力,极大的减少了不必要的网络流量与延迟。
6、没有同源限制,客户端可以与任意服务器通信
7、协议标识符是ws(如果加密,则为wss),服务器网址就是 URL

17、瀑布流的实现

将数组拆分成左右两个数组
记录左右数组的高度,遍历总数组,将新的元素放在高度比较小的数组里

//wxml文件
 <template name="postList">
    <view class="box"  bindtap="toChat" data-postid="{{item.postsId}}">
      <view class="title">
        {{item.title}}
      </view>
      <view class="imgBox">
        <image src="{{item.coverImgUrl}}" mode="widthFix"></image>
      </view>
    </view>
  </template>
<view class="bigBox">
  <view  class="leftBox">
      <template is="postList" data="{{item}}" wx:for="{{leftList}}" wx:key="postsId">						  			        				</template>
  </view>
  <view class="leftBox">
      <template is="postList" data="{{item}}" wx:for="{{rightList}}" wx:key="postsId"></template>
  </view>
</view>
<view class="load">
  <van-loading type="spinner" wx:if="{{isLoading}}" />
</view>
<view wx:if="{{isEnd}}" class="tip">没有更多了...</view>
<view class="back" hidden="{{backShow}}" bindtap="backTap" >
  <van-icon name="back-top" />
</view>
//js文件
import { getlist } from "../../api/chat"

// pages/chat/chat.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    list:[],
    leftList:[],
    rightList:[],
    leftHeight:0,
    rightHeight:0,
    // 整个数据处理完成
    finish:false,
    pageNum:1,
    pageSize:10,
    total:0,
    isEnd:false,
    isLoading:true,
    // 返回顶部
    backShow:true,
  },
// 请求的函数封装
getPost(){
  getlist(this.data.pageNum,this.data.pageSize).then(res=>{
    if(res.data.code == 0){
      wx.stopPullDownRefresh();
      this.initList(res.data.rows);
      this.data.total = res.data.total;
    }
  })
},
// 处理数据的封装
initList(list){
  this.data.finish = false
  if(list.length == 0){
    this.data.finish = true;
    // 没数据了
    return
  }
  let item = list.shift();
  // 获取图片信息
   wx.getImageInfo({
    src:item.coverImgUrl,
    success:(res)=>{
      if(this.data.leftHeight <= this.data.rightHeight){
        // 加到左列表
        this.data.leftList.push(item);
        this.data.leftHeight += res.height / res.width
      }else{
        this.data.rightList.push(item);
        this.data.rightHeight += res.height / res.width
      }
      // 更改视图
      this.setData({
        leftList:this.data.leftList,
        rightList:this.data.rightList,
        isLoading:false
      })
    },
    complete:()=>{
      this.initList(list);
    }
  })
},
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    this.setData({
      isLoading:true
    })
    // 处理数据
    this.getPost();
  },
  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {
    this.setData({
      isEnd:false
    })
     // 下拉刷新
    if(this.data.finish){
      this.data.pageNum = 1
      this.setData({
        leftList:[],
        rightList:[],
        leftHeight:0,
        rightHeight:0
      })
      this.getPost();
    }else{
      return
    }
  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {
    this.setData({
      isLoading:true,
    })
    // 触底了
    if(this.data.finish){
      if(this.data.pageNum * this.data.pageSize >= this.data.total){
        this.setData({
          isEnd:true,
          isLoading:false,
        })
      }else{
        this.data.pageNum ++;
        this.getPost()
      }
    }
  },
})
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值