微信小程序

小程序简介

小程序与普通网页的区别

1.运行环境不同
网页运行在浏览器环境中,小程序运行在微信环境中
2.API不同
由于运行环境的不同,所以小程序中无法调用DOM和BOM的API.
但是,小程序中可以调用微信环境提供各种API,例如: 地理定位,扫码,支付
3.开发模式不同
网页的开发模式:浏览器+代码编辑器
小程序有自己的一套标准开发模式
申请小程序开发账号,安装小程序开发者工具,创建和配置小程序项目。

注册小程序账号&安装开发者工具

点击注册按钮

使用浏览器打开 [https://mp.weixin.qq.com/] 点击右上角的立即注册,即可进入到小程序开发账号 的注册流程,主要流程截图如下
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

了解微信开发者工具

微信开发者工具是官方推荐使用的小程序开发工具,它提供的主要功能如下:
1.快速创建小程序项目
2.代码的查看和编辑
3.对小程序功能进行调试
4.小程序的预览和发布

2.下载

推荐下载和安装最新的稳定版(Stable Build)的微信开发者工具,下载页面的链接如下:微信开发者工具

项目的基本目录结构

在这里插入图片描述
1.pages 用于存放所有小程序页面
2.utils 用来存放工具性质的模块(例如:格式化时间的自定义模块)
3.app.js 小程序项目的入口文件
4.app.json 小程序项目的全局性配置文件
5.app.wxss 小程序项目的全局样式样式文件
6.project.config.json 项目的配置文件
7.sitemap.json用于配置小程序及其页面是否允许被微信索引

小程序页面的组成部分

小程序官方建议把所有小程序的页面,都存放在pages目录中,以单独的文件夹存在,如图所示:
在这里插入图片描述
其中,每个页面由4个基本文件组成,他们分别是:

  1. .js文件(页面的脚本文件,存放页面的数据,事件处理函数等)
  2. .json文件(当前页面的配置文件,配置窗口的外观,表现等)
  3. .wxml 文件(页面的模板结构文件)
  4. .wxss文件(当前页面的样式表文件)
JSON配置文件的作用:

json是一种数据格式,在实际开发中,JSON总是以配置文件的形式出现,小程序项目中也不例外:通过不同的.json配置文件,可以对小程序项目进行不同级别的配置。
小程序项目中有4中json配置文件:分别是:
1.项目根目录中的app.json配置文件
2.项目根目录中的project.config.json配置文件
3.项目根目录中的sltemap.json配置文件
4.每个页面文件夹中的.json配置文件

app.json文件

app.json 是当前小程序的全局配置,包括了小程序的所有页面路径,窗口外观,界面表现,底部tab等.
Demo 项目里边的app.json配置内容如下:

{
  "pages":[
    "pages/index/index",
    "pages/logs/logs"
  ],
  "window":{
    "backgroundTextStyle":"light",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "Weixin",
    "navigationBarTextStyle":"black"
  },
  "style": "v2", //代表现在是最新的版本,删除 将使用旧版本
  "sitemapLocation": "sitemap.json"
}

这4个配置项的作用:
1.pages:用来记录当前小程序所有页面的路径
2.window:全局定义小程序所有页面的背景色,文字颜色等
3.style:全局定义小程序组件所有的样式版本
4.sitemapLocation:用来指明sitemap.json 的位置

project.config.json 文件

project.config.json 是项目配置文件,用来记录我们对小程序开发所做的个性化配置,例如:
1.setting 中保存了编译相关的配置
2.projectname 中保存的是项目名称
3.appid中保存的是小程序的账号ID

{
  "description": "项目配置文件,详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
  "packOptions": {
    "ignore": [],
    "include": []
  },
  "setting": {
    "bundle": false,
    "userConfirmedBundleSwitch": false,
    "urlCheck": true,
    "scopeDataCheck": false,
    "coverView": true,
    "es6": true,
    "postcss": true,
    "compileHotReLoad": false,
    "lazyloadPlaceholderEnable": false,
    "preloadBackgroundData": false,
    "minified": true,
    "autoAudits": false,
    "newFeature": false,
    "uglifyFileName": false,
    "uploadWithSourceMap": true,
    "useIsolateContext": true,
    "nodeModules": false,
    "enhance": true,
    "useMultiFrameRuntime": true,
    "useApiHook": true,
    "useApiHostProcess": true,
    "showShadowRootInWxmlPanel": true,
    "packNpmManually": false,
    "enableEngineNative": false,
    "packNpmRelationList": [],
    "minifyWXSS": true,
    "showES6CompileOption": false,
    "minifyWXML": true,
    "useStaticServer": true,
    "checkInvalidKey": true,
    "babelSetting": {
      "ignore": [],
      "disablePlugins": [],
      "outputPath": ""
    },
    "disableUseStrict": false,
    "useCompilerPlugins": false
  },
  "compileType": "miniprogram",
  "libVersion": "2.19.4",
  "appid": "wx6e2083f48dc0e650",
  "projectname": "miniprogram-92",
  "condition": {},
  "editorSetting": {
    "tabIndent": "insertSpaces",
    "tabSize": 2
  }
}

拿到别人项目,想在自己电脑上运行,需要将appid 改为自己的

sitemap.json 文件

微信现已开放小程序内搜索,效果类似于PC网页的SEO.sitemap.json文件用来配置小程序页面是否允许微信索引
当开发者允许微信索引时,微信会通过爬虫的形式,为小程序的页面内容简历索引.当用户的所搜关键字和页面的索引匹配成功的时候,小程序的页面可能展示在搜索结果中

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

rules 里面为搜索规则
page *所有的页面 action 允许被微信访问 如果不想被微信方位将值改为disallow
注意: .sitemap的索引提示是默认开启的,如需要关闭sitemap的索引提示,可在小程序项目配置文件 project.config.json的setting中配置字段checkSiteMap为false

页面的 .json 配置文件

小程序中的每一个页面,可以使用.json文件来对本页面的窗口外观进行配置,页面中的配置项会覆盖app.json的window 中相同的配置项.例如:
在这里插入图片描述
index.json 文件

{
  "usingComponents": {},
  "navigationBarBackgroundColor": "#00b26a"
}
新建小程序页面

只需要在app.json–>pages 中新增页面的存放路径,小程序开发者工具即可帮助我们自动创建对应的页面文件, 如图所示
在这里插入图片描述

  "pages":[
    "pages/index/index",
    "pages/logs/logs",
    "pages/list/list"
  ],
修改项目首页

只需要调整app.json->pages数组中页面的前后顺序,即可修改项目的首页.小程序会把排在第一位的页面,当作项目首页进行渲染,如图所示:

"pages":[
    "pages/list/list",
    "pages/index/index",
    "pages/logs/logs"
   
  ],
什么是WXML?

WXML(weixin Markup Language) 是小程序框架设计的一套标签语言,用来构建小程序页面的结构,作用类似于网页开发中的HTML.

WXML和HTML 的区别

1.标签的名称不同
HTML(div ,span,img ,a)
WXML(view, text,image, navigator)
2. 属性节点不同

<a href="#"> 超链接</a>
<navigator url="/pages/index/index">跳转至首页</navigator>
  1. 提供了类似于Vue中的模板语法
    数据绑定,列表渲染,条件渲染
什么是WXSS ?
WXSS和CSS的区别
  1. 新增了rpx尺寸单位
    CSS 中需要手动进行像素单位换算,例如rem
    WXSS在底层支持新的尺寸单位rpx,在不同大小的屏幕上小程序会自动进行换算
  2. 提供了全局的样式和局部样式
    项目根目录中的app.wxss 会作用于所有小程序页面
    局部页面的 .wxss样式仅对当前页面生效
  3. WXSS仅支持部分CSS选择器
  4. .class 和# id 2.element 3.并集选择器,后代选择器,4.::after 和::before 等伪类选择器。
小程序中的 .js文件

一个项目仅仅提供界面展示是不够的,在小程序中,我们通过 .js文件来处理用户的操作. 例如:响应用户的点击,获取用户的位置等等 .

小程序中 .js文件的分类

小程序中的js文件分为三大类,分别是:
1.app.js
是整个小程序项目的入口文件,通过调用App()函数来启动整个小程序
2.页面的 .js文件
是页面的入口文件,通过调用Page()函数来创建并运行页面
3.普通的 .js文件
是普通的功能模块文件,用来封装公共的函数或属性供页面使用

小程序的宿主环境-宿主环境简介:

1.什么是宿主环境?
宿主环境(host environment)指的是程序运行所必须的依赖环境.例如:
Android系统和IOS系统是两个不同的宿主环境.安卓版的微信App 是不能在IOS环境下运行的,所以,Android 是安卓软件的宿主环境,脱离了宿主环境的软件是没有任何意义的!

小程序的宿主环境

手机微信是小程序的宿主环境 ,小程序借助宿主环境提供的能力,可以完成许多普通网页无法完成的功能, 例如: 微信扫码,微信支付,微信登陆,地理定位,etc…

小程序宿主环境包含的内容

1、 通信模型
通信主体
小程序中通信的主体是渲染层和逻辑层,其中:
1.WXML 模板和WXSS 样式工作在渲染层
2. JS 脚本工作在逻辑层
小程序的通信模型
小程序中的通信模型分为两部分:
1.渲染层和逻辑层之间的通信 :由微信客户端进行转发
2.逻辑层和第三方服务器之间的通信 :由微信客户端进行转发
2,运行机制
小程序启动的过程
1.小程序的代码包下载到本地
2.解析app.json 全局配置文件
3.执行app.js 小程序入口文件,调用App()创建小程序实例
4. 渲染小程序首页
5. 小程序启动完成
页面渲染的过程:
1. 加载解析页面的 .json配置文件
2. 加载页面的 .wxml模板和 ,wxss 样式
3. 执行页面的 .js 文件,调用Page()创建页面实例
4. 页面渲染完成
3.组件
小程序组件的分类
小程序中的组件也是由宿主环境提供的,开发者可以基于组件快速搭建出漂亮的页面结构,官方把小程序的组件分为9大类,分别是:
1.视图容器
1. view
普通视图区域,类似于HTML中的div,是一个块级元素,长用来实现页面的布局效
2. scllo-view
可滚动的视图区域,常用来实现滚动列表效果
3. swiper 和swiper-item
轮播图容器组件和轮播图item组件

<view ></view>
<!-- 滚动标签 -->
<!-- scroll-y 属性,允许纵向滚动 -->
<!-- scroll-x 属性,允许横向滚动 -->
<scroll-view class="scroll-view2" scroll-y>
<view>1</view>
<view>2</view>
<view>3</view>
</scroll-view>
样式:
.scroll-view2{
height: 200px;
  width: 100px;
  padding: 5px;
  background-color: rgb(243, 186, 80);
}
.scroll-view2 view{
  height: 100px;
}
<!-- 轮播图 -->
<swiper class="swiper-container">
<!-- 第一项 -->
<swiper-item >
<view class="item"> 右侧1 </view>
</swiper-item>
<!-- 第二项 -->
<swiper-item>
<view class="item"> 右侧2 </view>
</swiper-item>
<!-- 第三项 -->
<swiper-item>
<view class="item"> 右侧3 </view>
</swiper-item>
</swiper>
样式:
/* 轮播图 */
.swiper-container{
height: 100px;
background-color: aqua;
} 
.item{
  width: 100%;
  height: 100%;
  text-align: center;
}
 swiper-item:nth-child(1){
  background-color: rgb(234, 247, 247);
}
 swiper-item:nth-child(2){
  background-color: rgb(116, 38, 240);
}
 swiper-item:nth-child(3){
  background-color: rgb(7, 53, 53);
}
swiper组件的常用属性

在这里插入图片描述
2.基础内容

常用的基础内容组件

1.text 文本组件 类似HTML中的span标签,是一个行内元素
通过text 组件的selectable属性,实现长按选中文本内容的效果: 只有text 标签有这个功能。

手机支持长按选中效果
<text selectable="true">1381234567</text>
  1. rich-text 富文本组件, 支持把HTML字符串渲染为WXML结构
    rich-text 组件的基本使用
    通过rich-text 组件的nodes 属性节点,把HTML字符串渲染为对应的UI结构:
<rich-text nodes="<h1 >标题1<h1>"></rich-text>
其他常用组件

button
按钮组件
功能比HTML中的button 按钮丰富
通过open-type 属性可以调用微信提供的各种功能(客服,转发,获取用户授权,获取用户信息等)

<!-- 通过type属性指定按钮颜色类型 -->
<button>普通按钮</button>
<button type="primary">主色调按钮</button>
<button type="warn">警告调按钮</button>
<!-- 通过size 指定按钮尺寸 -->
<button size="mini" type="primary"> 小尺寸</button>
<button size="default" type="primary">大尺寸</button>
<button size="main" plain="true"> 没有背景色,只有边框线</button>

image
图片组件
image 组件默认宽度约300px ,高度约240px

<!-- mode 设置图片的纵横比模式 -->
<image src="../../assets/001 (1).jpg" mode="widthFix"></image>

在这里插入图片描述

navigator
页面导航组件
类似于HTML中的a链接

3.表单组件
4.导航组件
5.媒体组件
6.map 地图组件
7.canvas 画布组件
8.开放能力
9. 无障碍访问
4.api

小程序API概述

小程序中的API 是有由宿主环境提供的,通过这些丰富的小程序API,开发者可以方便的调用微信提供的能力,
例如:获取用户信息,本地存储,支付功能等

小程序API的3大分类

小程序 官方把API分为了如下3大类

事件监听API

特点:以on 开头,用来监听某些事件的触发
距离:wx.onWindowResize(function callback) 监听窗口尺寸变化的事件

同步API

特点API
特点1:以Sync 结尾的API都是同步API
特点2:同步API的执行结果,可以通过函数返回值直接获取,如果执行出错会抛出异常
举例:wx.setStorageSync(‘key’,‘value’) 向本地存储中写入内容

异步API

特点:类似于Jquery中的$.ajax(options)函数,需要通过success,fail,complete接收调用的结果
举例:wx.request()发起网络数据请求,通过sucess回调函数接收数据

模板语法

数据绑定

在data中定义数据

在页面对应的.js文件中,把数据定义到data对象中即可:
  data: {
//字符串类型的数据
info:'init data',
// 数组类型的数据
msgList:[{msg:'hello'},{msg:'world'}]
  },
Mustache 语法的格式

把data中的数据绑定到页面上渲染,使用Mustache语法(双大括号)将变量包起来即可, .wxml 文件 语法格式为:

//定义数据
  data: {
    phoneNumber:123456789,
//字符串类型的数据
info:'init data',
// 数组类型的数据
msgList:[{msg:'hello'},{msg:'world'}]
  },
  渲染视图
  <text selectable="true">{{phoneNumber}}</text>

应用场景:

  1. 绑定内容
<text selectable="{{isText}}">{{phoneNumber}}</text>
phoneNumber 为内容值
  1. 绑定属性
<text selectable="{{isText}}">{{phoneNumber}}</text>
isText 为属性值
  1. 运算(三元运算,算数运算等)
<text selectable="{{isText}}">{{phoneNumber>=12?'输入正确':'输入错误'}}</text>

事件绑定

事件是渲染层到逻辑层的通讯方式. 通过事件可以将用户在渲染层产生的行为,反馈到逻辑层进行业务的处理.
在这里插入图片描述当事件回调触发的时候,会收到一个事件对象event,它的详细属性如下表所示:
在这里插入图片描述
4. target 和currentTarget 的区别
target 是触发该事件的源头组件,而currentTarget 则是当前事件所绑定的组件.举例如下:
在这里插入图片描述
迪纳基内部的按钮时,点击事件以冒泡的方式向外扩散,也会触发外层View 的tap 事件处理函数. 此时对于外层view 来说:
e.target 指向的是触发事件的源头组件,因此 e.target是内部的按钮组件
e.currentTarget 指向的是当前正在触发事件的那个组件,因此e.currentTarget 是当前的view组件

bindtap 的语法格式

在小程序中不存在HTML的onclick鼠标点击事件,而是通过tap事件来响应用户的触摸行为.
1.通过bindtap ,可以为组件绑定tap 触摸事件,语法如下:

<button type="primary" bindtap="outerHandle">点击按钮</button>

2.在页面的 .js 文件中定义对应的事件处理函数,事件参数通过形参event(一般简写成 e) 来接收:

Page({
  outerHandle(e){
    console.log(e);
  }}),
在事件处理函数中为data中的数据赋值

通过调用this.setData(dataObject) 方法,可以给页面data中的数据重新赋值 实例如下:

Page({
    /**
   * 页面的初始数据
   */
  data: {
    count:0,   
      },
  outerHandle(e){
    console.log(e);
    this.setData({
      count:this.data.count+=1
    })
  },})

页面结构
<view>
<button type="primary" bindtap="outerHandle">点击按钮</button>
<text>{{count}}</text>
</view>

注意:
小程序中的事件传参比较特殊,不能在绑定事件的同时为事件处理函数传递参数.例如:

<view>
<button type="primary" bindtap="outerHandle(11)">点击按钮</button>
<text>{{count}}</text>
</view>

因为小程序会把bindtap 的属性值,统一当作事件名称来处理,相当于调用了一个outerHandle(11)的事件处理函数。

事件传参

可以为组件提供data-自定义属性传参,其中代表的是参数的名称,示例如下:

<button type="primary" bindtap="outerHandle" data-info="{{2}}">点击按钮</button>

info 会被解析为参数的名字
数值2会被解析为参数的值
在事件处理函数中,通过event.target.dataset .参数名即可获取到具体参数的值,示例如下:

  outerHandle(e){
    //dataset 是一个对象,包含了所有通过data-*传递过来的参数项
    console.log(e.target.dataset);
    this.setData({
      count:this.data.count+=1
    })
  },

bindinput 的语法格式

在小程序中,通过input事件来响应文本框的输入事件,语法格式如下:
1.通过bindinput,可以为文本框绑定输入事件:

<input type="text" bindinput="outerHandle"/>

注意:input 响应数据 会没办法时时获取
解决方案:

<form action="">
  <input class="input" 	bindinput="inputHandler" />
</form>

2.在页面的.js 文件中定义事件处理函数

  /**
   * 页面的初始数据
   */
  inputHandler: function (options) {
    console.log(options.detail.value);
  },

实现文本框和data之间的数据同步
实现步骤:
1.定义数据

  data: {
    msg: '定义数据'
  },

2.渲染结构

<form action="">
  <input class="input" value="{{msg}}" 	bindinput="inputHandler" />
</form>

3.美化样式

input{
  border: 1px solid #334455;
  padding: 5px;
  margin: 5px;
  border-radius: 3px;
}

4.绑定input 事件处理函数 赋新值

  inputHandler: function (options) {
    //通过options.detail.value 是变化过后,文本框最新的值
    console.log(options.detail.value);
    this.setData({
      msg:options.detail.value
    })
  },

条件渲染

在小程序中,使用wx:if=“{{condition}}” 来判断是否需要渲染该代码:

<view wx:if="{{isTrue}}">你好</view>
利用isTrue 值为false和true 进行判断页面展示区域

也可以用wx:elif 和wx:else 来添加else判断

<view wx:if="{{isTrue==1}}">isTrue</view>
<view wx:elif="{{isTrue==2}}">false</view>
<view wx:else>保密</view>

结合使用 wx:if
如果要依次控制多个组件的展示和隐藏,可以使用一个标签将多个组件包装起来,并在标签上使用wx:if 控制属性,示例如下:

<block wx:if="{{isTrue==false}}">
  <view wx:if="{{isTrue==1}}">isTrue</view>
<view wx:elif="{{isTrue==2}}">false</view>
<view wx:else>保密</view>
</block>

注意并不是一个组件,它只是一个包裹性质的容器,不会在页面中做任何渲染。

hidden (没生效暂时没找到原因)

在小程序中,直接使用hidden=“{{condition}}” 也能控制元素的显示和隐藏:

<view hidden="{{condition}}">condition条件为true隐藏,条件为false 显示 </view>

wx:if 与hidden 的对比
1.运行方式不同
wx:if 以动态创建和移除元素的方式,控制元素的展示和隐藏
hidden 以切换样式的方式(display:none/block),控制元素的显示与隐藏
使用建议:
频繁切换时,建议使用hidden
控制条件复杂时,建议使用wx:if搭配wx:elif,wx:else进行展示与隐藏的切换。

wx:for

通过wx:for 可以根据指定的数组,循环渲染重复的组件结构,语法示例如下:

<view wx:for="{{condition}}">
索引是{{index}} 当前项是:{{item}}
</view>

默认情况下,当前循环项的索引是index表示,当前循环项用item 表示。

手动指定索引和当前项的变量名*

使用wx:for-index 可以指定当前循环项的索引的变量名
使用wx:for-item可以指定当前项的变量名
示例代码如下:

<view wx:for="{{condition}}" wx:for-index="idx" wx:for-item="itemName">
索引是{{idx}} 当前项是:{{itemName}}
</view>
wx:key的使用

类似于Vue列表渲染中的:key,小程序在实现列表渲染时,也建议为渲染出来的列表项指定唯一的key值,从而提高渲染的效率,示例代码如下:

<view wx:for="{{condition}}" wx:for-index="idx" wx:for-item="itemName" wx:key="id">
索引是{{idx}} 当前项是:{{itemName.text}}
</view>
    condition:[
      {
      id:1,
      text:'数据1'
    },
    {
      id:2,
      text:'数据2'
    },
    {
      id:3,
      text:'数据3'
    },
  ]

什么是WXSS?

WXSS(WeiXin Style Sheets)是一套样式语言,用于美化WXML的组件样式,类似于网页开发中的CSS

WXSS和CSS的关系

wxss 具有CSS大部分特性,同时,WXSS还对CSS进行了扩充以及修改,以适应微信小程序的开发. 与CSS相比,WXSS扩展的特性有:
rpx 尺寸单位
@import 样式导入
在这里插入图片描述

什么是rpx尺寸单位

rpx(responsive pixel)是微信小程序独有的,用来解决屏适配的尺寸单位.

rpx 的实现原理

rpx 的实现原理非常简单:鉴于不同设备屏幕的大小不同,为了实现屏幕的自主适配,rpx把所有设备的屏幕,在宽度上等分为750份(即:当前屏幕的总宽度为750px).
在较小的设备上,1rpx所代表的宽度较小
在较大的设备上,1rpx所代表的宽度较大
小程序在不同设备上运行的时候,会自动把rpx的呀那个是单位换算成对应的像素单位来渲染,从而实现屏幕适配.

rpx与px 之间的单位换算*

在iphone6上,屏幕宽度为375px,共有750个物理像素,等分为750rpx.则:
750rpx=375px=750物理像素
1rpx=0.5px=1物理像素
在这里插入图片描述
官方建议:开发微信小程序时,设计师可以用iPhone6 作为视觉稿的标准.
开发举例:在iPhone6 上如果要绘制宽100px,高20px的盒子,换算成rpx单位,宽高分别为200rpx 和40rpx.

样式导入

使用WXSS提供的@import语法,可以导入外联的样式表

@import 的语法格式

@import 后跟需要导入的外联样式表的相对路径,用;表示语句结束.示例如下:

新建公共样式表 .wxss
@import '../../wxss//index.wxss';  //引入公共样式

1.全局样式
定义在app.wxss中的样式称为全局样式,作用与每一个页面.
2.局部样式
在页面的.wxss文件中定义的样式称为局部样式,只作用于当前页面.
注意:
1.当局部样式和全局呀那个是冲突时,根据就近原则,局部样式会覆盖全局样式
2.当局部样式的权重大于或等于全局样式的权重时,才会覆盖全局的样式。

全局配置
全局配置文件及常用的配置项

小程序根目录下的app.json文件是小程序的全局配置文件,常用的配置项如下:
1.pages
记录当前小程序所有页面的存放路径
2.window
全局设置小程序窗口的外观
3.tabBar
设置小程序底部的tabBar 效果
4.style
是否启用新版的组件样式

小程序窗口的组成部分:

在这里插入图片描述

了解window 节点常用的配置项

在这里插入图片描述
设置导航栏的标题
设置步骤:app.json->window->navigationBarTitleText
需求:把导航条上的标题,从默认的WeChat 修改为:我的世界,效果如图所示:
在这里插入图片描述
设置导航栏的背景色
设置步骤:app.json->window->navigationBarBackgroundColor
需求把导航栏标题的背景色,从默认的#fff修改为#00b26a,效果如图所示:

在这里插入图片描述
设置导航栏的标题颜色
设置步骤 :app.json->window->navigationBarTextStyle
需求:把导航条上的标题,从默认的black修改为white,效果如上图
注意:navigationBarTextStyle 的可选值只有black 和white
全局开启下拉刷新功能
概念:下拉刷新是移动端的专有名词,指的是通过手指在屏幕上的下拉滑动操作,从而重新加载页面数据的行为。
设置步骤:app.json–>window–>把enablePullDownRefresh的值设置为true
注意:在app.json中启用下拉刷新功能,会作用每个小程序页面
设置下拉刷新功能之后,默认的窗口背景为白色.如果自定义下拉刷新窗口背景色,设置步骤为:
app.json–>window–>为backgroundColor指定16进制的颜色值#efefef.效果如下:
在这里插入图片描述
设置下拉刷新时loading的样式
当全局开启下拉刷新功能之后,默认窗口的loading样式为白色,如果要更改loading样式的效果,设置步骤为:app.json–>window–>backgroundTextStyle指定dark值.效果如下图
在这里插入图片描述
设置上拉触底的距离
概念:上拉触底是移动端的专有名词,通过手指在屏幕上的上拉华东操作,从而加载更多数据行为.
app.json–>window–>onReachBottomDistance 设置新的数值
注意:默认距离为50px,如果没有特殊需求,建议使用默认值即可.

什么是 tabBar ?

tabBar 是移动端应用常见的页面效果,用于实现多页面的快速切换.小程序中通常将其分为:
底部;tabBar
顶部tabBar
注意:tabBar 中只能配置最少2个,最多5个tab页签
当渲染顶部tabBar时,不显示icon,只显示文本
tsbBar的6个组成部分
在这里插入图片描述
1.backgroundColor:tabBar 的背景色
2.selectediconPath:选中时的图片路径
3.borderStyle:tabBar 上边框的颜色
4.iconPath:未选中时的图片路径
5.selectedColor:tab上文字选中时的颜色
6.color:tab上文字的默认(未选中)颜色
3.tabBar 节点的配置项
在这里插入图片描述
每个tab项的配置选项
在这里插入图片描述
效果图如下:
在这里插入图片描述
代码: app.json 文件

  "tabBar": {
    "list": [{
      "pagePath": "pages/index/index",
      "text": "首页"
    }, 
    {
      "pagePath": "pages/list/list",
      "text": "列表页"
    },
    {
      "pagePath":  "pages/logs/logs",
      "text": "登录页"
    }]
  },

需求描述

  1. 根据小图标,在小程序中配置如图所示的tabBar效果:
    实现步骤:
    1.拷贝图标资源
    1.把资源目录中的images文件夹,拷贝到小程序项目根目录中
    2.将需要用到的小图标分为3组,每组两个,其中:
    图片名称中包含-active的是选中之后的图标
    图片名称中不包含-active的是默认图标
    2.新建3个对应的tab页面
    通过app.json文件的pages节点,快速新建3个对应的tab页面,示例代码如下
    “pages”: [
    “pages/home/home”,
    “pages/message/message”,
    “pages/contact/contact”,
    ],
    其中,home 是首页,message 是消息页面,contact 是联系我们页面
    3.配置tabBar 选项
    1.打开app.json 配置文件,和pages,window 平级,新增tabBar 节点
    2.tabBar 节点中,新增list 数组,这个数组中存放放入,是每个tab项的配置对象
    3.在list 数组中,新增每一个tab项的配置对象,对象中包含的属性如下:
    pagePath 指定当前tab 对应的页面路径[必填]
    text 指定当前tab 上按钮的文字[必填]
    iconPath 指定当前tab未选中时候的图片路径[可选]
    selectedIconPath 指定当前tab被选中后高亮的图片路径[可选]
  "tabBar": {
    "list": [{
      "pagePath": "pages/home/home",
      "text": "首页",
      "iconPath": "./assets/image/icon/cunchu.png",
      "selectedIconPath": "./assets/image/icons/cunchu.png"
    },
    {
      "pagePath": "pages/message/message",
      "text": "消息",
      "iconPath": "./assets/image/icon/dianpu.png",
      "selectedIconPath": "./assets/image/icons/dianpu.png"
    },
    {
      "pagePath": "pages/contact/contact",
      "text": "文章内容",
      "iconPath": "./assets/image/icon/fenlei.png",
      "selectedIconPath": "./assets/image/icons/fenlei.png"
    }
  ]
  },

图标可以从阿里巴巴图标库自己注册账号https://www.iconfont.cn/获取

页面配置文件的作用

小程序中,每个页面都有自己的.json 配置文件,用来对当前页面的窗口外观,页面效果等进行配置
小程序中,app.json中的window 节点,可以全局配置小程序中每个页面的窗口表现.
如果某些小程序页面想要拥有特殊的窗口表现,此时,页面级别的.json 配置文件就可以实现这种需求.
注意:当页面配置与全局配置冲突时,根据就近原则,最终的效果以页面配置为准.

页面配置中常用的配置项

在这里插入图片描述

网络数据请求

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

出于安全性方面的考虑,小程序官方对数据接口的请求做出了如下两个限制:
1.只能请求HTTPS类型的接口
2.必须将接口的域名添加到信任列表中
在这里插入图片描述
配置request 合法域名
需求描述:假设在自己的微信小程序中,希望请求https://www.escook.cn/域名下的接口
配置步骤:登录微信小程序管理后台–>开发—>开发设置–>服务器域名—>修改request合法域名
注意事项:
1,域名只支持https 协议
2.域名不能使用IP地址或localhost
3.域名必须经过ICP 备案
4.服务器域名一个月内最多可申请5次修改

发送GET请求

调用微信小程序提供的wx.request()方法,可以发起GET数据请求,示例如下:

wx.request({
  url: 'url', //请求路径
  method:'GET', //请求方式
 data:{},//请求体
 success:(res)=>{
   console.log(res);
 }
})
发起post 请求

调用微信小程序提供的wx.request()方法,可以发起POST数据请求,示例代码如下:

wx.request({
  url: 'url', //请求路径
  method:'post', //请求方式
 data:{},//请求体
 success:(res)=>{
   console.log(res);
 }
})

在很多情况下,我们需要在页面刚加载的时候,自动请求一些初始化的数据.此时需要在页面的onLoad事件中调用获取数据的函数,示例代码如下:
在这里插入图片描述

跳过request合法域名效验

如果后端程序员仅仅提供了http协议的接口,暂时没有提供https协议的接口
此时为了不耽误开发的进度,我们可以在微信开发者工具中,临时开启[开发环境不效验请求域名,TLS版本及HTTPS证书]选项,跳过request 合法域名的效验。
注意:
跳过request 合法域名效验的选项,仅限在开发与调试阶段使用。
在这里插入图片描述
6.关于跨域和AJAX的说明
跨域问题只存在于基于浏览器的Web开发中,由于小程序的宿主环境不是浏览器,而是微信客户端,所以小程序中不存在跨域的问题。
Ajax技术的核心是依赖于浏览器中的XMLHttpRequest 这个对象,由于小程序的宿主环境是微信客户端,所以小程序中不能叫发起Ajax 请求,而是叫做发起网络数据请求.
案例:本地生活案例
在这里插入图片描述
步骤:
1.新建项目并梳理项目结构
2.配置导航栏效果
3.配置tabBar效果
4.实现轮播图
5.实现九宫格效果
6.实现图片布局

视图与逻辑

什么是页面导航?

页面导航指的是页面之间的相互跳转.例如:浏览器中实现页面导航的方式有如下两种:
1.链接
2.location.href
小程序中实现页面导航的两种方式

声明式导航

在页面上声明一个导航组件
通过点击组件实现页面跳转
导航到tabBar页面
tabBar页面指的是被配置为tabBar的页面.
在使用组件跳转到指定的tabBar页面时,需要指定url 属性和open-type属性, 其中
url 表示要跳转的页面的地址,必须以/开头
open-type 表示跳转的方式,必须为switchTab

<navigator url="/pages/message/message" open-type="switchTab"> 导航到消息页面</navigator>

2.导航到非tabBar 页面
非tabBar 页面指的是没有被配置为tabBar的页面
在使用组件跳转到普通的非tabBar页面时,则需要指定url属性和open-type属性,其中:
url:表示要跳转的页面的地址,必须以/开头
open-type 表示跳转的方式,必须为navigate

<navigator url="/pages/info/info" open-type="navigate"> 非tabBar页面</navigator>

注意:为了简便,在导航到非tabBar页面时,open-type="navigate"属性可以省略.
3.后退导航
如果要后退到上一页面或多级页面,则需要指定open-type属性和delta属性,其中:
open-type的值必须是navigateBack,表示进行后退导航
data的值必须是数字,表示要后退的层级。

<navigator open-type="navigateBack" delta="1"> 返回上一级</navigator>

注意:为了简便,如果只是后退到上衣页面,则可以省略delta属性,则其默认值就是1

编程式导航

调用小程序的导航API,实现页面的跳转
导航到tabBar 页面
条用wx.switchTab(Object object)方法, 可以跳转到tabBar 页面. 其中Object参数对象的属性列表如下:
在这里插入图片描述
示例代码:

<button bindtap="gotoMessage"></button>

  gotoMessage(){
    wx.switchTab({
      url: "/pages/message/message",
    })
  },

导航到非tabBar页面

调用wx.navigateTo(Object object)方法, 可以跳转到非TabBar的页面.其中Object参数对象的属性列表如下:
在这里插入图片描述

后退导航

调用wx.navigateBack(Object object)方法,可以返回上一页面或多级页面.其中Object参数对象可选的属性列表如下:
在这里插入图片描述
在这里插入图片描述

导航传参

1.声明式导航传参
navigator 组件的url 属性用来指定将要跳转到的页面的路径.同时,路径的后面还可以携带参数:
参数与路径之间使用?分隔
参数键与参数值用=相连
不同参数用&分隔

<navigator url="/pages/message/message?name='莲白'&age=20" open-type="switchTab"> 导航到消息页面</navigator>

2.变成式导航传参
调用 wx.navigateTo(Object object) 方法跳转到页面时,也可以携带参数,代码示例如下:

  gotoMessage(){
    wx.navigateTo({
      url: '/pages/info/info?name=zs&age=20',
    })
  },

3.在onLoad中接收导航参数
通过声明式导航传参或编程式导航传参所携带的参数,可以直接在onLoad 事件中直接获取到,示例代码如下:

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
console.log(options);
  },

options 就是导航传递过来的参数对象

页面事件
1.什么是下拉刷新

下拉刷新是移动端的专有名词,指的是通过手指在屏幕上的下拉滑动操作,从而重新加载页面数据的行为.

2. 启用下拉刷新

启用下拉刷新有两种方式:
1.全局开启下拉刷新
在app.json 的window 节点中,将enablePullDownRefresh 设置为true
2.局部开启下来刷新
在页面的.json 配置文件中,将enablePullDownRefresh 设置为true

3.配置下拉刷新窗口的样式

在全局或页面的.json配置文件中,通过backgroundColor 和backgroundTextStyle来配置下拉刷新窗口的样式,其中:
backgroundColor 用来配置下拉刷新窗口的背景颜色,仅支持16进制的颜色值
backgroundTextStyle用来配置下拉刷新loading的样式,仅支持dark和light

4.监听页面的下拉刷新事件

在页面的.js文件中,通过onPullDownRefresh()函数即可监听当前页面的下拉刷新事件.
例如,在页面的wxml 中有如下的ui结构,点击按钮可以让count值自增+1;

<view>{{count}}</view>
<button bindtap="gotoBack1"> count +1</button>
  gotoBack1(){
    this.setData({
      count:this.data.count+1
    })
  },

在触发页面的下拉刷新事件的时候将count 的值重置为0,示例代码如下:

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {
this.setData({
  count:0
})
  },

5.停止下拉刷新的效果
当处理完下拉刷新后,下拉刷新的loading效果会一直显示,不会主动消失,loading效果,此时,调用wx.stopPullDownRefresh()可以停止当前页面的下拉刷新,示例:

  onPullDownRefresh() {
this.setData({
  count:0
})
wx.stopPullDownRefresh()
  },
什么是上拉触底

上拉触底是移动端的专有名词,通过手指在屏幕上的上拉滑动操作,从而加载更多数据的行为.

监听页面的上拉触底事件

在页面的.js文件中,通过onReachBottom()函数即可监听当前页面的上拉触底事件.示例代码如下:

  onReachBottom() {
console.log('上拉触发事件');
  },
配置上拉触底距离

上拉触底距离指的是触发上事件时,滚动条距离页面底部的距离.
可以在全局或页面的.json 配置文件中,通过onReachBottomDistance 属性来配置上拉触底的距离.
小程序默认的触底距离是50px,在实际开发中,可以根据自己的需求修改这个默认值.
案例效果展示:
1,定义获取随机颜色的方法
2.在页面加载时获取初始数据
3.渲染UI 结构并美化页面效果
4.在上拉触底时调用获取随机颜色的方法
5.添加loading提示效果
6.对上拉触底进行节流处理

扩展

自定义编译模式

声明周期

什么是生命周期

生命周期(Life Cycle) 是指一个对象从创建–>运行–>销毁的整个阶段,强调的是一个时间段.
我们可以把每个小程序运行的过程,也概括为生命周期
小程序的启动,表示生命周期的开始
小程序的关闭,表示生命周期的结束
中间小程序运行的过程就是小程序的生命周期

生命周期的分类

在小程序中,生命周期分为两类,分别是:

应用生命周期

特指小程序从启动—>运行—>销毁的过程

页面生命周期

特指小程序中,每个页面的加载–>渲染—>销毁的过程。
其中,页面的生命周期范围较小,应用程序的生命周期范围较大如图所示:
在这里插入图片描述

什么是生命周期函数

生命周期函数:是由小程序框架提供的内置函数,会伴随着生命周期,自动按次序执行.
生命周期函数的作用:允许程序员在特定的时间点,执行某些特定的操作,例如,页面刚加载的时候,可以在onLoad生命周期函数中初始化页面的数据。
注意:生命周期强调的是时间段,生命周期函数强调的是时间点.

生命周期函数的分类

小程序中的生命周期函数分为两类,分别是:
1.应用 的生命周期函数
特指小程序从启动—>运行—>销毁期间依次调用的那些函数
2.页面的生命周期函数
特指小程序中,每个页面从加载—>渲染—>销毁期间依次第哦啊用的那些函数

应用的生命周期函数

小程序的应用生命周期函数需要在app.js 中进行声明,示例代码如下

  /**
   *小程序初始化完成时,执行此函数,全局只触发一次,可以做一些初始化的工作
   */
  onLoad(options) {
  },
    /**
   * 小程序启动,或从后台进入前台显示触发,
   */
  onShow() {

  },
    /**
   * 小程序从前台进入后台时触发
   */
  onHide() {

  },

页面生命周期函数

小程序的页面生命周期函数需要在页面的.js文件中进行生命,示例如下:

 /**
   * 监听页面加载,一个页面只调用1次
   */
  onLoad(options) {
  },
    /**
   * 监听页面显示
   */
  onShow() {

  },
   /**
   * 监听页面初次渲染完成,一个页面只调用1次
   */
  onReady() {

  },
    /**
   * 监听页面隐藏
   */
  onHide() {

  },
    /**
   * 监听页面卸载,一个页面只调用1次
   */
  onUnload() {

  },

wxs

什么是wxs
WXS(WeiXin Script)是小程序独有的一套脚本语言,结合WXML,可以构建出页面的结构.
wxs 的应用场景
wxml 中无法调用在页面的.js中定义的函数,但是,wxml中可以调用wxs中定义的函数.因此,小程序中wxs的典型应用场景就是过滤器.
wxs 和javaScript的关系*
虽然wxs的语法类似于javascript,但是wxs和javascript是完全不同的两种语言:
1.wxs有自己的数据类型
number 数值类型,string 字符串你类型,boolean布尔类型,object对象类型
function 函数类型 arrag 数组类型, data日期类型, regexp 正则
2.wxs 不支持类似于ES6及以上的语法形式
不支持:let const 解构赋值,展开运算符,箭头函数,对象属性简写 , etc…
支持:var 定义变量,普通function 函数等类似于ES5的语法
3.wxs遵循CommonJS规范
module 对象
require()函数
module.exports 对象
1.内嵌wxs 脚本
wxs 代码 可以编写在wxml文件中的标签内,就像javascript代码可以编写在html 文件中的

<view>{{m1.toUpper(username)}}</view>
<wxs module="m1">
module.exports.toUpper=function(str){
 return str.toUpperCase()
}
</wxs>

定义外联的wxs脚本
wxs代码还可以编写在以.wxs为后缀名的文件内,就像javascript代码可以编写在以.js为后缀名的文件中一样.示例代码如下:

function toLower(str){
  return str.toLowerCase()
}
module.exports={
  toLower:toLower
}

使用外联的wxs 脚本
在wxml 中引入外联的wxs 脚本时,必须为标签添加module和src属性,其中:
1.module 用来指定模块的名称
2.src 用来指定要引入的脚本的路径,且必须是相对路径

<wxs src="./message.wxs" module="m2"></wxs>
与JavaScript不同

为了减低wxs(WeiXin Script) 的学习成本,wxs 语言在设计时借大量鉴了JavaScript的语法,但是本质上, wxs 和JavaScript是完全不同的两种语言!
不能作为组件的事件回调
wxs 典型的应用场景就是过滤器,经常配合Mustache 语法进行使用,例如:

<view>{{m2.toLower(country)}}</view>

但是,在wxs中定义的函数不能作为组件的事件回调函数,例如,下面的用法是错误的:

<button bindtap="m2.toLower"></button>

隔离性
隔离性 指的是wxs的运行环境和其他JavaScript代码是隔离的,体现在如下两个方面:
1.wxs 不能调用js中定义的函数
2.wxs 不能调用小程序提供的API
性能好:
在ios 设备上,小程序内的WXS会比JavaScript 代码快2~20倍
在 android 设备上,二者的运行效率无差异
应用场景:可以对手机号码进行修改

高级用法:

创建自定义组件

1.在项目的根目录中,鼠标右键components–>test 文件夹
2.在新建的components–>test 文件夹上,鼠标右键 点击新建Component
3.键入组件的名称之后会自动生成组件对应的4个文件,后缀名分别为.js .json .wxml 和.wxss
注意:为了保证目录解构的清晰,建议把不同的组件,存放到单独目录中,例如:

在这里插入图片描述

引用组件:

组件的引用方式分为局部引用和全局引用,顾名思义:
局部引用:组件只能在当前被引用的页面内使用,
在页面的.json 配置文件中引用组件的方式,叫做局部引用 代码如下:

.
{
  "usingComponents": {
    "my-test1":"/components/test/indexTest"
  }
}
  <!-- 在页面的.wxml 文件中,使用组件 -->
  <my-test1></my-test1>

全局引用:组件可以在每个小程序页面中使用
在app.json 全局配置文件中引用组件的方式,叫做“全局引用” .示例代码如下:
在这里插入图片描述

全局引用VS局部引用

根据组件的使用频率和范围,来选择合适的引用方式
如果某个组件在多个页面中经常被用到,建议进行全局引用
如果某个组件只在特定的页面中被用到,建议进行局部引用
组件和页面的区别
从表面来看,组件和页面都是由.js ,.json .wxml 和.wxss 这四个文件组成的,但是组件和页面的.js 与.json 文件有明显的不同
组件的.json 文件中需要声明 “component”:true属性
组件的.js 文件中调用的是Component()函数
组件的时间处理函数需要定义到methods 节点中

组件样式隔离

默认情况下,自定义组件的样式只对当前组件生效,不会影响到组件之外的UI结构
在这里插入图片描述
组件A的样式不会影响组件C的样式
组件A的样式不会影响小程序页面的样式
小程序页面的样式不会影响组件A和C的样式
好处:
1.防止外界样式影响组件内部的样式
2.防止组件的样式破坏外界的样式

组件样式隔离的注意点

app.wxss 中的全局样式对组件无效
只有class 选择器会有样式隔离效果,id 选择器,属性选择器,标签选择器不受样式隔离的影响
建议:在组件和引用组件的页面中建议使用class 选择器,不要使用id ,属性,标签选择器!
修改组件的样式隔离选项
默认情况下,自定义组件的呀那个是隔离特性能够防止组件内外样式互相干扰的问题,但有时,我们希望在外界能够控制组件内部的样式,此时,可以通过stylesolation 修改组件的样式隔离选项,用法如下:
在这里插入图片描述
在这里插入图片描述
自定义组件–数据,方法和属性
1.data 数据
在小程序组件中,用于组件模板渲染的私有数据,需要定义到data节点中,示例如下:
在这里插入图片描述
2 methods 方法
在小程序组件中,事件处理函数和自定义方法需要定义到methods 节点中,示例代码如下:
在这里插入图片描述
3.properties 属性
在小程序组件中,properties 是组件的对外属性,用于接收外界传递组件中的数据,
在这里插入图片描述
4.data 和properties 的区别
在小程序的组件中,properties属性和data数据的用法相同,它们都是可读可写的,只不过:
data 更倾向于存储组件的私有数据
properties更倾向于存储外界传递到组件中的数据

在这里插入图片描述
使用setData 修改properties 的值
由于data 数据和properties 属性在本质上没有任何区别,因此Properties属性的值也可以用于页面渲染,或使用setData 为properties 中的属性重新赋值,示例如下:
在这里插入图片描述
什么是数据监听器
数据监听器用于监听和响应任何属性和数据字段的变化,从而执行特定的操作.它的作用类似于Vue中的watch 侦听器.在小程序组件中,数据侦听器的基本语法格式如下:

在这里插入图片描述

数据监听器的基本用法

组件的UI结构如下:
在这里插入图片描述
在这里插入图片描述
监听对象数据的变化
数据监听器支持监听对象中单个或多个属性的变化,示例语法如下:
在这里插入图片描述
监听对象中所有属性的变化
如果某个对象中需要被监听的属性太多,为了方便,可以使用通配符**来监听对象中所有属性的变化,示例代码如下:
在这里插入图片描述

什么是纯数据字段

概念:纯数据字段指的是哪些不用于界面渲染的data字段
应用场景:例如有些情况下,某些data中的字段既不会展示在界面上,也不会传递给其他组件,仅仅在当前组件内部使用,带有这些特性的data字段适合被设置为纯数据字段。
好处:纯数据字段有助于提升页面更新的性能.
2. 使用规则
在Component 构造器的options节点中,指定pureDataPattern为一个正则表达式,字段名符合这个正则表达式的字段将称为纯数据字段,示例如下:
在这里插入图片描述
使用纯数据字段改造数据监听器案例
在这里插入图片描述
组件全部的生命周期函数
小程序组件可用的全部生命周期如下表所示:
在这里插入图片描述

组件主要的生命周期函数

在小程序组件中,最重要的生命周期函数有3个,分别是created ,attached,detached 它们各自的特点如下:
1.组件实例刚被创建好的时候,created 生命周期函数会被触发
此时还不能调用setData
通常在这个生命周期函数中,只应该用于给组件的this添加一些自定义的属性字段
2. 在组件完全初始化完毕 ,进入页面节点树后,attached 生命周期函数会被触发
此时,this.data 已被初始化完毕
这个生命周期很有用,绝大多数初始化的工作可以在这个时机进行(例如发请求获取初始数据)
3. 在组件离开页面节点树后,detached 生命周期函数会被触发
退出一个页面时,会触发页面内每个自定义组件的detached生命周期函数
此时适合做一些清理性质的工作

lifetimes节点

在小程序组件中,生命周期函数可以直接定义在Component 构造器的第一级参数中,可以在lifetimes 节点内进行声明(这是推荐的方式,其优先级最高).示例代码如下:
在这里插入图片描述
什么是组件所在页面的生命周期
有时,自定义组件的行为依赖于页面状态的变化,此时就需要用到组件所在页面的生命周期
例如:每当触发页面的show生命周期函数的时候,
在自定义组件中,组件所在页面的生命周期函数有如下3个,分别是:
在这里插入图片描述

pageLifetimes 节点

组件所在页面的生命周期函数,需要定义在pageLifetimes 节点,示例代码如下:
在这里插入图片描述

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值