每当学习一个新的技术,学完之后,觉得总要留下点什么,要不果过段时间再回头看时,会发现好陌生呀,所以记录一下,用到时再翻一下,当前微信小程序开发我是视频和文档结合着看的,并且项目中的例子都认真的实现了一下,个人觉得还是讲的不错的,欢迎学习。
B 站小程序视频地址:https://www.bilibili.com/video/BV1834y1676P
在线讲义地址:https://applet-base-api-t.itheima.net/docs-uni-shop/2.tabbar.html
接口文档 API 地址:https://www.uinav.com 或者直接访问:https://www.showdoc.com.cn/128719739414963/2513235043485226
Gitee 项目地址
小程序基础知识点:https://gitee.com/xiaoshiStudy/xcx/tree/master/mp_01
小程序使用第三方组件到项目练习:https://gitee.com/xiaoshiStudy/xcx/tree/master/mp_npm
小程序练习项目:https://gitee.com/xiaoshiStudy/xcx/tree/master/uniapp-shop
小程序简介
-
小程序与普通网页开发的区别
-
申请小程序开发账号
-
安装小程序开发者工具
-
创建和配置小程序项目
-
地理定位
-
扫码
-
支付
-
网页运行在浏览器环境中
-
小程序运行在微信环境中
-
运行环境不同
-
API 不同
由于运行环境的不同,所以小程序中,无法调用 DOM 和 BOM 的 API。但是,小程序中可以调用微信环境提供的各种 API,例如:
-
开发模式不同
网页的开发模式:浏览器 + 代码编辑器,小程序有自己的一套标准开发模式:
-
体验小程序
可使用手机微信(6.7.2 及以上版本)扫码下方小程序码,体验小程序:
注册小程序
注册地址:链接(https://mp.weixin.qq.com/)
点击注册按钮根据流程填写信息,主题类型选择个人
获取appid:设置->基本设置->账号信息(AppID 小程序ID)
下载开发工具
推荐下载和安装最新的稳定版(Stable Build)的微信开发者工具,下载页面的
直接下一步默认安装即可
创建小程序项目
填写项目信息,点击确定,注意不适用云开发,选择 JavaScript 基础模板
小程序代码的构成 – 项目结构
-
了解项目的基本组成结构
-
pages 用来存放所有小程序的页面
-
utils 用来存放工具性质的模块(例如:格式化时间的自定义模块)
-
app.js 小程序项目的入口文件
-
app.json 小程序项目的全局配置文件
-
app.wxss 小程序项目的全局样式文件
-
project.config.json 项目的配置文件
-
sitemap.json 用来配置小程序及其页面是否允许被微信索引
-
小程序页面的组成部分
小程序官方建议把所有小程序的页面,都存放在 pages 目录中,以单独的文件夹存在,其中,每个页面由 4 个基本文件组成,它们分别是:
-
.js 文件(页面的脚本文件,存放页面的数据、事件处理函数等)
-
.json 文件(当前页面的配置文件,配置窗口的外观、表现等)
-
.wxml 文件(页面的模板结构文件)
-
.wxss 文件(当前页面的样式表文件)
小程序代码的构成 – JSON 配置文件
-
JSON 配置文件的作用
JSON 是一种数据格式,在实际开发中,JSON 总是以配置文件的形式出现。小程序项目中也不例外:通过不同的 .json 配置文件,可以对小程序项目进行不同级别的配置。
小程序项目中有 4 种 json 配置文件,分别是:
-
项目根目录中的 app.json 配置文件
-
项目根目录中的 project.config.json 配置文件
-
项目根目录中的 sitemap.json 配置文件
-
每个页面文件夹中的 .json 配置文件
-
app.json 文件
app.json 是当前小程序的全局配置,包括了小程序的所有页面路径、窗口外观、界面表现、底部 tab 等。Demo 项目里边的 app.json 配置内容如下:
-
pages:用来记录当前小程序所有页面的路径
-
window:全局定义小程序所有页面的背景色、文字颜色等
-
style:全局定义小程序组件所使用的样式版本
-
sitemapLocation:用来指明 sitemap.json 的位置
-
project.config.json 文件
project.config.json 是项目配置文件,用来记录我们对小程序开发工具所做的个性化配置,例如:
-
setting 中保存了编译相关的配置
-
projectname 中保存的是项目名称
-
appid 中保存的是小程序的账号 ID
-
sitemap.json 文件
微信现已开放小程序内搜索,效果类似于 PC 网页的 SEO。sitemap.json 文件用来配置小程序页面是否允许微信索引。
当开发者允许微信索引时,微信会通过爬虫的形式,为小程序的页面内容建立索引。当用户的搜索关键字和页面的索引匹配成功的时候,小程序的页面将可能展示在搜索结果中。
注意:sitemap 的索引提示是默认开启的,如需要关闭 sitemap 的索引提示,可在小程序项目配置文件 project.config.json 的 setting 中配置字段 checkSiteMap 为 false
-
页面的 .json 配置文件
小程序中的每一个页面,可以使用 .json 文件来对本页面的窗口外观进行配置,页面中的配置项会覆盖 app.json 的 window 中相同的配置项。
-
新建小程序页面
只需要在 app.json -> pages 中新增页面的存放路径,小程序开发者工具即可帮我们自动创建对应的页面文件。
-
修改项目首页
只需要调整 app.json -> pages 数组中页面路径的前后顺序,即可修改项目的首页。小程序会把排在第一位的页面,当作项目首页进行渲染。
小程序代码的构成 – WXML 模板
-
什么是 WXML
WXML(WeiXin Markup Language)是小程序框架设计的一套标签语言,用来构建小程序页面的结构,其作用类似于网页开发中的 HTML。
-
WXML 和 HTML 的区别
标签名称不同
属性节点不同
提供了类似于 Vue 中的模板语法
-
数据绑定
-
列表渲染
-
条件渲染
-
<a href="#">超链接</a>
-
-
HTML (div, span, img, a)
-
WXML(view, text, image, navigator)
小程序代码的构成 – WXSS 样式
-
什么是 WXSS
WXSS (WeiXin Style Sheets)是一套样式语言,用于描述 WXML 的组件样式,类似于网页开发中的 CSS。
-
WXSS 和 CSS 的区别
新增了 rpx 尺寸单位
提供了全局的样式和局部样式
WXSS 仅支持部分 CSS 选择器
-
.class 和 #id
-
element
-
并集选择器、后代选择器
-
::after 和 ::before 等伪类选择器
-
项目根目录中的 app.wxss 会作用于所有小程序页面
-
局部页面的 .wxss 样式仅对当前页面生效
-
CSS 中需要手动进行像素单位换算,例如 rem
-
WXSS 在底层支持新的尺寸单位 rpx,在不同大小的屏幕上小程序会自动进行换算
小程序代码的构成 – JS 逻辑交互
-
小程序中的 .js 文件
一个项目仅仅提供界面展示是不够的,在小程序中,我们通过 .js 文件来处理用户的操作。例如:响应用户的点击、获取用户的位置等等。
-
小程序中 .js 文件的分类
小程序中的 JS 文件分为三大类,分别是:
app.js
页面的 .js 文件
普通的 .js 文件
-
是普通的功能模块文件,用来封装公共的函数或属性供页面使用 -
是页面的入口文件,通过调用 Page() 函数来创建并运行页面 -
是整个小程序项目的入口文件,通过调用 App() 函数来启动整个小程序
小程序的宿主环境 – 宿主环境简介
-
什么是宿主环境
宿主环境(host environment)指的是程序运行所必须的依赖环境。例如:
Android 系统和 iOS 系统是两个不同的宿主环境。安卓版的微信 App 是不能在 iOS 环境下运行的,所以,
Android 是安卓软件的宿主环境,脱离了宿主环境的软件是没有任何意义的!
-
小程序的宿主环境
手机微信是小程序的宿主环境,如图所示:
小程序借助宿主环境提供的能力,可以完成许多普通网页无法完成的功能,例如:微信扫码、微信支付、微信登录、地理定位、etc…
-
小程序宿主环境包含的内容
-
通信模型
-
运行机制
-
组件
-
API
小程序的宿主环境 – 通信模型
-
通信的主体
小程序中通信的主体是渲染层和逻辑层,其中:
-
WXML 模板和 WXSS 样式工作在渲染层
-
JS 脚本工作在逻辑层
-
小程序的通信模型
小程序中的通信模型分为两部分:
渲染层和逻辑层之间的通信
逻辑层和第三方服务器之间的通信
-
由微信客户端进行转发 -
由微信客户端进行转发 -
小程序启动的过程
-
把小程序的代码包下载到本地
-
解析 app.json 全局配置文件
-
执行 app.js 小程序入口文件,调用 App() 创建小程序实例
-
渲染小程序首页
-
小程序启动完成
-
页面渲染的过程
-
加载解析页面的 .json 配置文件
-
加载页面的 .wxml 模板和 .wxss 样式
-
执行页面的 .js 文件,调用 Page() 创建页面实例
-
页面渲染完成
小程序的宿主环境 – 组件
-
程序中组件的分类
小程序中的组件也是由宿主环境提供的,开发者可以基于组件快速搭建出漂亮的页面结构。官方把小程序的组件分为了 9 大类,分别是:
-
视图容器
-
基础内容
-
表单组件
-
导航组件
-
媒体组件
-
map 地图组件
-
canvas 画布组件
-
开放能力
-
无障碍访问
-
常用的视图容器类组件
view
scroll-view
swiper 和 swiper-item
-
轮播图容器组件 和 轮播图 item 组件 -
可滚动的视图区域
-
常用来实现滚动列表效果
-
普通视图区域
-
类似于 HTML 中的 div,是一个块级元素
-
常用来实现页面的布局效果
-
view 组件的基本使用
实现 flex 横向布局效果:
<!--pages/list/list.wxml-->
<scroll-view class="container1" scroll-y>
<view>A</view>
<view>B</view>
<view>C</view>
</scroll-view>
/* pages/list/list.wxss */
.container1 view{
width: 100px;
height: 100px;
text-align: center;
line-height: 100px;
}
.container1 view:nth-child(1){
background-color: lightgreen;
}
.container1 view:nth-child(2){
background-color: lightblue;
}
.container1 view:nth-child(3){
background-color: lightpink;
}
.container1{
border: 1px solid red;
width: 100px;
height: 120px;
} -
scroll-view 组件的基本使用
<!--pages/list/list.wxml-->
<scroll-view class="container1" scroll-y> 省略..... </scroll-view>
// 省略样式
.container1{
border:1px solied red;
height:120px;
width:100px;
} -
swiper 和 swiper-item 组件的基本使用
<!-- wxml 页面代码 -->
<!--轮播图结构-->
<swiper class="swiper-container" indicator-dots indicator-color="grap" autoplay interval="3000" circular>
<!-- 第一个轮播图 -->
<swiper-item>
<view class="item">A</view>
</swiper-item>
<!-- 第二个轮播图 -->
<swiper-item>
<view class="item">B</view>
</swiper-item>
<!-- 第三个轮播图 -->
<swiper-item>
<view class="item">C</view>
</swiper-item>
</swiper>
// 对应页面的 .wxss 样式
/* pages/swipper/swipper.wxss */
.swiper-container{
height: 150px;
}
.item{
height: 100%;
line-height: 150px;
text-align: center;
}
swiper-item:nth-child(1) .item{
background-color: lightgreen;
}
swiper-item:nth-child(2) .item{
background-color: lightskyblue;
}
swiper-item:nth-child(3) .item{
background-color: lightpink;
} -
swiper 组件的常用属性
属性 类型 默认值 说明 indicator-dots boolean false 是否显示面板指示点 indicator-color color rgba(0, 0, 0, .3) 指示点颜色 indicator-active-color color #000000 当前选中的指示点颜色 autoplay boolean false 是否自动切换 interval number 5000 自动切换时间间隔 circular boolean false 是否采用衔接滑动 -
常用的基础内容组件
text
rich-text
-
富文本组件
-
支持把 HTML 字符串渲染为 WXML 结构
-
文本组件
-
类似于 HTML 中的 span 标签,是一个行内元素
-
text 组件的基本使用
通过 text 组件的 selectable 属性,实现长按选中文本内容的效果:
<!--pages/text/text.wxml-->
<view>
<!-- 手机号长安选中 selectable 已废弃 -->
<text user-select>18500000000</text>
</view> -
rich-text 组件的基本使用
<!--pages/richtext/richtext.wxml-->
<!-- rich-text 通过组件nodes 属性,把HTML字符串渲染为对应的 ui 结构 -->
<rich-text nodes="<h1 style='color:red;'>标题</h1>"></rich-text> -
其它常用组件
button
image
navigator
-
页面导航组件
-
类似于 HTML 中的 a 链接
-
图片组件
-
image 组件默认宽度约 300px、高度约 240px
-
按钮组件
-
功能比 HTML 中的 button 按钮丰富
-
通过 open-type 属性可以调用微信提供的各种功能(客服、转发、获取用户授权、获取用户信息等)
-
button 按钮的基本使用
<view>
<button>默认按钮</button>
<button type="primary">按钮</button>
<button type="warn">按钮</button>
<button type="primary" size="mini">小按钮</button>
<button type="primary" size="mini" plain="true">小按钮</button>
</view> -
image 组件的基本使用
<text>pages/image/image.wxml</text>
<image></image>
<image src="/image/1.png" mode="aspectFit"></image>
// 样式
/* pages/image/image.wxss */
image{
border: 1px solid red;
} -
image 组件的 mode 属性
image 组件的 mode 属性用来指定图片的裁剪和缩放模式,常用的 mode 属性值如下:
mode 值 说明 scaleToFill (默认值)缩放模式,不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素 aspectFit 缩放模式,保持纵横比缩放图片,使图片的长边能完全显示出来。也就是说,可以完整地将图片显示出来。 aspectFill 缩放模式,保持纵横比缩放图片,只保证图片的短边能完全显示出来。也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。 widthFix 缩放模式,宽度不变,高度自动变化,保持原图宽高比不变 heightFix 缩放模式,高度不变,宽度自动变化,保持原图宽高比不变
小程序的宿主环境 – API
-
小程序 API 概述
小程序中的 API 是由宿主环境提供的,通过这些丰富的小程序 API,开发者可以方便的调用微信提供的能力,例如:获取用户信息、本地存储、支付功能等。
-
小程序 API 的 3 大分类
小程序官方把 API 分为了如下 3 大类:
事件监听 API
同步 API
异步 API
-
特点:类似于 jQuery 中的 $.ajax(options) 函数,需要通过 success、fail、complete 接收调用的结果
-
举例:wx.request() 发起网络数据请求,通过 success 回调函数接收数据
-
特点1:以 Sync 结尾的 API 都是同步 API
-
特点2:同步 API 的执行结果,可以通过函数返回值直接获取,如果执行出错会抛出异常
-
举例:wx.setStorageSync(‘key’, ‘value’) 向本地存储中写入内容
-
特点:以 on 开头,用来监听某些事件的触发
-
举例:wx.onWindowResize(function callback) 监听窗口尺寸变化的事件
WXML 模板语法 – 数据绑定
-
数据绑定的基本原则
-
在 data 中定义数据
-
在 WXML 中使用数据
-
在 data 中定义页面的数据
在页面对应的 .js 文件中,把数据定义到 data 对象中即可:
Page({
data:{
// 字符串类型的数据
info:"init data",
// 数组类型的数据
msgList:[{msg:"hello"},{msg:"world"}]
}
}) -
Mustache 语法的格式
把data中的数据绑定到页面中渲染,使用 Mustache 语法(双大括号)将变量包起来即可。语法格式为:
<view>{{ 要绑定的数据名称 }}</view>
-
Mustache 语法的应用场景
Mustache 语法的主要应用场景如下:
-
绑定内容
-
绑定属性
-
运算(三元运算、算术运算等)
-
动态绑定内
页面的数据如下:
Page({
data:{
info:"init data"
}
})页面的结构如下:
<view>{{ info }}</view>
-
动态绑定属性
页面的数据如下:
Page({
data:{
imgSrc:"http://www.itheima.com/images/logo.png"
}
})页面结构如下:
<image src="{{imgSrc}}"></image>
-
三元运算
页面的数据如下:
Page({
data:{
randomNum:Math.random() * 10 // 生成 10 以内的随机数
}
})页面结构如下:
<view>{{randomNum1 >= 5 ?'数值大于等于5':'数值小于5'}}</view>
-
算数运算
页面的数据如下:
Page({
data:{
randomNum2 : Math.random().toFixed(2) // 保留两位小数
}
})页面结构如下:
<view>生成100以内的随机数:{{randomNum2*100}}</view>
WXML 模板语法 – 事件绑定
-
什么是事件
-
程序中常用的事件
类型 绑定方式 事件描述 tap bindtap 或 bind:tap 手指触摸后马上离开,类似于 HTML 中的 click 事件 input bindinput 或 bind:input 文本框的输入事件 change bindchange 或 bind:change 状态改变时触发 -
事件对象的属性列表
当事件回调触发的时候,会收到一个事件对象 event,它的详细属性如下表所示:
属性 类型 说明 type String 事件类型 timeStamp Integer 页面打开到触发事件所经过的毫秒数 target Object 触发事件的组件的一些属性值集合 currentTarget Object 当前组件的一些属性值集合 detail Object 额外的信息 touches Array 触摸事件,当前停留在屏幕中的触摸点信息的数组 changedTouches Array 触摸事件,当前变化的触摸点信息的数组 -
target 和 currentTarget 的区别
target 是触发该事件的源头组件,而 currentTarget 则是当前事件所绑定的组件。举例如下:
点击内部的按钮时,点击事件以冒泡的方式向外扩散,也会触发外层 view 的 tap 事件处理函数。
此时,对于外层的 view 来说:
-
e.target 指向的是触发事件的源头组件,因此,e.target 是内部的按钮组件
-
e.currentTarget 指向的是当前正在触发事件的那个组件,因此,e.currentTarget 是当前的 view 组件
-
bindtap 的语法格式
在小程序中,不存在 HTML 中的 onclick 鼠标点击事件,而是通过 tap 事件来响应用户的触摸行为。
-
通过 bindtap,可以为组件绑定 tap 触摸事件,语法如下:
<button type="primary" bindtap= "btnTapHandler">按钮</button>
-
在页面的 .js 文件中定义对应的事件处理函数,事件参数通过形参 event(一般简写成 e) 来接收:
Page({
btnTapHandler(e){ // 按钮的 tap 事件处理函数
console.log(e) // 事件参数对象 e
}
}) -
在事件处理函数中为 data 中的数据赋值
通过调用 this.setData(dataObject) 方法,可以给页面 data 中的数据重新赋值,示例如下:
// 页面的 .js 文件
Page({
data:{
count:0
},
// 修改 count 的值
changeCount(){
this.setData({
count:this.data.count + 1
})
}
}) -
事件传参
小程序中的事件传参比较特殊,不能在绑定事件的同时为事件处理函数传递参数。例如,下面的代码将不能正常工作:
<button type="primary" bindtap="btnHandler(123)">
事件传参
</button>因为小程序会把 bindtap 的属性值,统一当作事件名称来处理,相当于要调用一个名称为 btnHandler(123) 的事件处理函数。
可以为组件提供 data-* 自定义属性传参,其中 * 代表的是参数的名字,示例代码如下:
<button bindtap="btnHandler" data-info="{{2}}">事件传参</button>
最终:
在事件处理函数中,通过 event.target.dataset.参数名 即可获取到具体参数的值,示例代码如下:
btnHandler(event){
// dataset 是一个对象,包含了所有通过 data-* 传递过来的参数项
console.log(event.target.dataset)
// 通过dataset 可以访问到具体参数的值
console.log(event.target.dataset.info)
} -
info 会被解析为参数的名字
-
数值 2 会被解析为参数的值
-
bindinput 的语法格式
在小程序中,通过 input 事件来响应文本框的输入事件,语法格式如下:
-
通过 bindinput,可以为文本框绑定输入事件:
<input bindinput="inputHandler"></input>
-
在页面的 .js 文件中定义事件处理函数:
inputHandler(e){
// e.detail.value 是变化后,文本框最新的值
console.log(e.detail.value)
} -
实现文本框和 data 之间的数据同步
实现步骤:
实现文本框和 data 之间的数据同步
定义数据:
Page({
data:{
msg:"你好"
}
})渲染结构:
<input value="{{msg}}" bindinput="iptHandler"></input>
美化样式:
input{
border:1px solid #eee;
padding:5px;
margin:5px;
border-radius:3px;
}绑定 input 事件处理函数:
// 文本框内容改变事件
iptHandler(e){
this.setData({
// 通过 e.detail.value 获取文本框最新的值
msg:e.detail.value
})
} -
定义数据
-
渲染结构
-
美化样式
-
绑定 input 事件处理函数
WXML 模板语法 – 条件渲染
-
wx:if
在小程序中,使用 wx:if=”{{condition}}” 来判断是否需要渲染该代码块:
<view wx:if="{{condition}}">true</view>
也可以用 wx:elif 和 wx:else 来添加 else 判断:
<view wx:if="{{type===1}}">男</view>
<view wx:elif="{{type===2}}">女</view>
<view wx:else>保密</view> -
和<block>使用 wx:if
如果要一次性控制多个组件的展示与隐藏,可以使用一个
标签将多个组件包装起来,并在 标签上使用 wx:if 控制属性,示例如下: <block wx:if="{{true}}">
<view>view1</view>
<view>view2</view>
</block>注意:
并不是一个组件,它只是一个包裹性质的容器,不会在页面中做任何渲染。 -
hidden
在小程序中,直接使用 hidden=”{{ condition }}” 也能控制元素的显示与隐藏:
<view hidden="{{ condition }}">条件为 true 隐藏,条件为 false 显示</view>
-
wx:if 与 hidden 的对比
运行方式不同
使用建议
-
频繁切换时,建议使用 hidden
-
控制条件复杂时,建议使用 wx:if 搭配 wx:elif、wx:else 进行展示与隐藏的切换
-
wx:if 以动态创建和移除元素的方式,控制元素的展示与隐藏
-
hidden 以切换样式的方式(display: none/block;),控制元素的显示与隐藏
WXML 模板语法 – 列表渲染
-
wx:for
通过 wx:for 可以根据指定的数组,循环渲染重复的组件结构,语法示例如下:
<view wx:for="{{array}}">
索引是:{{index}} 当前项是:{{item}}
</view>默认情况下,当前循环项的索引用 index 表示;当前循环项用 item 表示。
-
手动指定索引和当前项的变量名
示例代码如下:
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
索引是:{{idx}} 当前项是:{{itemName}}
</view> -
使用 wx:for-index 可以指定当前循环项的索引的变量名
-
使用 wx:for-item 可以指定当前项的变量名
-
wx:key 的使用
类似于 Vue 列表渲染中的 :key,小程序在实现列表渲染时,也建议为渲染出来的列表项指定唯一的 key 值,从而提高渲染的效率,示例代码如下:
// data 数据
data: {
userList:[
{id:1,name:"名字1"},
{id:2,name:"名字2"},
{id:3,name:"名字3"}
]
}
// 对应的 wxml 页面
<view wx:for="{{userList}}" wx:key="id" class="username">{{item.name}</view>
WXSS 模板样式
-
什么是 WXSS
WXSS (WeiXin Style Sheets)是一套样式语言,用于美化 WXML 的组件样式,类似于网页开发中的 CSS。
-
WXSS 和 CSS 的关系
WXSS 具有 CSS 大部分特性,同时,WXSS 还对 CSS 进行了扩充以及修改,以适应微信小程序的开发。与 CSS 相比,WXSS 扩展的特性有:
WXSS 模板样式 – rpx
-
什么是 rpx 尺寸单位
rpx(responsive pixel)是微信小程序独有的,用来解决屏适配的尺寸单位。
-
rpx 的实现原理
rpx 的实现原理非常简单:鉴于不同设备屏幕的大小不同,为了实现屏幕的自动适配,rpx 把所有设备的屏幕,在宽度上等分为 750 份(即:当前屏幕的总宽度为 750rpx)。
小程序在不同设备上运行的时候,会自动把 rpx 的样式单位换算成对应的像素单位来渲染,从而实现屏幕适配。
-
在较小的设备上,1rpx 所代表的宽度较小
-
在较大的设备上,1rpx 所代表的宽度较大
-
rpx 与 px 之间的单位换算
在 iPhone6 上,屏幕宽度为375px,共有 750 个物理像素,等分为 750rpx。则:
官方建议:开发微信小程序时,设计师可以用 iPhone6 作为视觉稿的标准。
开发举例:在 iPhone6 上如果要绘制宽100px,高20px的盒子,换算成rpx单位,宽高分别为 200rpx 和 40rpx。
-
750rpx = 375px = 750 物理像素
-
1rpx = 0.5px = 1物理像素
设备 rpx换算px (屏幕宽度/750) px换算rpx (750/屏幕宽度) iPhone5 1rpx = 0.42px 1px = 2.34rpx iPhone6 1rpx = 0.5px 1px = 2rpx iPhone6 Plus 1rpx = 0.552px 1px = 1.81rpx
WXSS 模板样式 – 样式导入
-
什么是样式导入
使用 WXSS 提供的 @import 语法,可以导入外联的样式表。
-
@import 的语法格式
/** common.wxss **/
.small-p{
padding:5px;
}/** app.wxss **/
@import "common.wxss"
.small-p{
padding:15px;
}
WXSS 模板样式 – 全局样式和局部样式
-
全局样式
定义在 app.wxss 中的样式为全局样式,作用于每一个页面。
-
局部样式
在页面的 .wxss 文件中定义的样式为局部样式,只作用于当前页面。
注意:
-
当局部样式和全局样式冲突时,根据就近原则,局部样式会覆盖全局样式
-
当局部样式的权重大于或等于全局样式的权重时,才会覆盖全局的样式
全局配置
-
全局配置文件及常用的配置项
小程序根目录下的 app.json 文件是小程序的全局配置文件。常用的配置项如下:
pages
window
tabBar
style
-
是否启用新版的组件样式 -
设置小程序底部的 tabBar 效果 -
全局设置小程序窗口的外观 -
记录当前小程序所有页面的存放路径
全局配置 – window
-
小程序窗口的组成部分
-
了解 window 节点常用的配置项
属性名 类型 默认值 说明 navigationBarTitleText String 字符串 导航栏标题文字内容 navigationBarBackgroundColor HexColor #000000 导航栏背景颜色,如 #000000 navigationBarTextStyle String white 导航栏标题颜色,仅支持 black / white backgroundColor HexColor #ffffff 窗口的背景色 backgroundTextStyle String dark 下拉 loading 的样式,仅支持 dark / light enablePullDownRefresh Boolean false 是否全局开启下拉刷新 onReachBottomDistance Number 50 页面上拉触底事件触发时距页面底部距离,单位为px -
设置导航栏的标题
设置步骤:app.json -> window -> navigationBarTitleText
需求:把导航栏上的标题,从默认的 “WeChat”修改为“黑马程序员”
-
设置导航栏的背景色
设置步骤:app.json -> window -> navigationBarBackgroundColor
需求:把导航栏标题的背景色,从默认的 #fff 修改为 #2b4b6b
-
设置导航栏的标题颜色
设置步骤: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 值。
注意:backgroundTextStyle 的可选值只有 light 和 dark
-
设置上拉触底的距离
概念:上拉触底是移动端的专有名词,通过手指在屏幕上的上拉滑动操作,从而加载更多数据的行为。
设置步骤:app.json -> window -> 为 onReachBottomDistance 设置新的数值
注意:默认距离为50px,如果没有特殊需求,建议使用默认值即可。
全局配置 – tabBar
-
什么是 tabBar
tabBar 是移动端应用常见的页面效果,用于实现多页面的快速切换。小程序中通常将其分为:
-
底部 tabBar
-
顶部 tabBar
注意:
-
tabBar中只能配置最少 2 个、最多 5 个 tab 页签
-
当渲染顶部 tabBar 时,不显示 icon,只显示文本
-
tabBar 的 6 个组成部分
-
backgroundColor:tabBar 的背景色
-
selectedIconPath:选中时的图片路径
-
borderStyle:tabBar 上边框的颜色
-
iconPath:未选中时的图片路径
-
selectedColor:tab 上的文字选中时的颜色
-
color:tab 上文字的默认(未选中)颜色
-
tabBar 节点的配置项
属性 类型 必填 默认值 描述 position String 否 bottom tabBar 的位置,仅支持 bottom/top borderStyle String 否 black tabBar 上边框的颜色,仅支持 black/white color HexColor 否 tab 上文字的默认(未选中)颜色 selectedColor HexColor 否 tab 上的文字选中时的颜色 backgroundColor HexColor 否 tabBar 的背景色 list Array 是 tab 页签的列表,最少 2 个、最多 5 个 tab -
每个 tab 项的配置选项
属性 类型 必填 描述 pagePath String 是 页面路径,页面必须在 pages 中预先定义 text String 是 tab 上显示的文字 iconPath String 否 未选中时的图标路径;当 postion 为 top 时,不显示 icon selectedIconPath String 否 选中时的图标路径;当 postion 为 top 时,不显示 icon
页面配置
-
页面配置文件的作用
小程序中,每个页面都有自己的 .json 配置文件,用来对当前页面的窗口外观、页面效果等进行配置。
-
页面配置和全局配置的关系
小程序中,app.json 中的 window 节点,可以全局配置小程序中每个页面的窗口表现。
如果某些小程序页面想要拥有特殊的窗口表现,此时,“页面级别的 .json 配置文件”就可以实现这种需求。
注意:当页面配置与全局配置冲突时,根据就近原则,最终的效果以页面配置为准。
-
页面配置中常用的配置项
属性 类型 默认值 描述 navigationBarBackgroundColor HexColor #000000 当前页面导航栏背景颜色,如 #000000 navigationBarTextStyle String white 当前页面导航栏标题颜色,仅支持 black / white navigationBarTitleText String 当前页面导航栏标题文字内容 backgroundColor HexColor #ffffff 当前页面窗口的背景色 backgroundTextStyle String dark 当前页面下拉 loading 的样式,仅支持 dark / light enablePullDownRefresh Boolean false 是否为当前页面开启下拉刷新的效果 onReachBottomDistance Number 50 页面上拉触底事件触发时距页面底部距离,单位为 px
网络数据请求
-
小程序中网络数据请求的限制
出于安全性方面的考虑,小程序官方对数据接口的请求做出了如下两个限制:
-
只能请求 HTTPS 类型的接口
-
必须将接口的域名添加到信任列表中
-
配置 request 合法域名
需求描述:假设在自己的微信小程序中,希望请求 https://applet-base-api-t.itheima.net/ 域名下的接口
配置步骤:登录微信小程序管理后台 -> 开发 -> 开发设置 -> 服务器域名 -> 修改 request 合法域名
注意事项:
-
域名只支持 https 协议
-
域名不能使用 IP 地址或 localhost
-
域名必须经过 ICP 备案
-
服务器域名一个月内最多可申请 5 次修改
-
发起 GET 请求
调用微信小程序提供的 wx.request() 方法,可以发起 GET 数据请求,示例代码如下:
// get请求
getInfo(){
wx.request({
url: 'https://applet-base-api-t.itheima.net/api/get',
method:"GET", // 请求方式
data:{
name:"zs",
age:20
},
success:(res)=>{
console.log(res.data);
}
})
}注意:跳过 request 合法域名校验
如果后端程序员仅仅提供了 http 协议的接口、暂时没有提供 https 协议的接口。
此时为了不耽误开发的进度,我们可以在微信开发者工具中,临时开启「开发环境不校验请求域名、TLS 版本及 HTTPS 证书」选项,跳过 request 合法域名的校验。
注意:跳过 request 合法域名校验的选项,仅限在开发与调试阶段使用!
-
发起 POST 请求
调用微信小程序提供的 wx.request() 方法,可以发起 POST 数据请求,示例代码如下:
// post请求地址
postInfo(){
wx.request({
url: 'https://applet-base-api-t.itheima.net/api/post',
method:"post", // 请求方式
data:{
name:"zs",
sex:"男"
},
// post请求后端用字段接口需要添加类型
header:{
"Content-Type": "application/x-www-form-urlencoded"
},
success:(res)=>{
console.log(res.data);
}
})
} -
在页面刚加载时请求数据
在很多情况下,我们需要在页面刚加载的时候,自动请求一些初始化的数据。此时需要在页面的 onLoad 事件中调用获取数据的函数,示例代码如下:
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
this.getInfo();
this.postInfo();
}, -
关于跨域和 Ajax 的说明
跨域问题只存在于基于浏览器的 Web 开发中。由于小程序的宿主环境不是浏览器,而是微信客户端,所以小程序中不存在跨域的问题。
Ajax 技术的核心是依赖于浏览器中的 XMLHttpRequest 这个对象,由于小程序的宿主环境是微信客户端,所以小程序中不能叫做“发起 Ajax 请求”,而是叫做“发起网络数据请求”。
页面导航
-
什么是页面导航
页面导航指的是页面之间的相互跳转。例如,浏览器中实现页面导航的方式有如下两种:
-
链接
-
location.href
-
小程序中实现页面导航的两种方式
声明式导航
编程式导航
-
调用小程序的导航 API,实现页面的跳转 -
在页面上声明一个
导航组件 -
通过点击
组件实现页面跳转
页面导航 – 声明式导航
-
导航到 tabBar 页面
tabBar 页面指的是被配置为 tabBar 的页面。
在使用
组件跳转到指定的 tabBar 页面时,需要指定 url 属性和 open-type 属性,其中: 示例代码如下:
<navigator url="/pages/message/message" open-type="switchTab">导航到消息页面</navigator>
-
url 表示要跳转的页面的地址,必须以 / 开头
-
open-type 表示跳转的方式,必须为 switchTab
-
导航到非 tabBar 页面
非 tabBar 页面指的是没有被配置为 tabBar 的页面。
在使用
组件跳转到普通的非 tabBar 页面时,则需要指定 url 属性和 open-type 属性,其中: 示例代码如下:
<navigator url="/pages/info/info" open-type="navigate">导航到info页面</navigator>
注意:为了简便,在导航到非 tabBar 页面时,open-type=”navigate” 属性可以省略。
-
url 表示要跳转的页面的地址,必须以 / 开头
-
open-type 表示跳转的方式,必须为 navigate
-
后退导航
如果要后退到上一页面或多级页面,则需要指定 open-type 属性和 delta 属性,其中:
示例代码如下:
<navigator open-type="navigateBack" delta="1">返回上一次</navigator>
注意:为了简便,如果只是后退到上一页面,则可以省略 delta 属性,因为其默认值就是 1。
-
open-type 的值必须是 navigateBack,表示要进行后退导航
-
delta 的值必须是数字,表示要后退的层级
页面导航 – 编程式导航
-
导航到 tabBar 页面
调用 wx.switchTab(Object object) 方法,可以跳转到 tabBar 页面。其中 Object 参数对象的属性列表如下:
属性 类型 是否必选 说明 url string 是 需要跳转的 tabBar 页面的路径,路径后不能带参数 success function 否 接口调用成功的回调函数 fail function 否 接口调用失败的回调函数 complete function 否 接口调用结束的回调函数(调用成功、失败都会执行) 实例代码如下:
// 页面结构代码
<button type="primary" bindtap="gotoMessage">跳转到消息页面</button>
// 通过编程式导航,跳转到 message 页面
gotoMessage(){
wx.switchTab({
url:"/pages/message/message"
})
} -
导航到非 tabBar 页面
调用 wx.navigateTo(Object object) 方法,可以跳转到非 tabBar 的页面。其中 Object 参数对象的属性列表如下:
属性 类型 是否必选 说明 url string 是 需要跳转到的非 tabBar 页面的路径,路径后可以带参数 success function 否 接口调用成功的回调函数 fail function 否 接口调用失败的回调函数 complete function 否 接口调用结束的回调函数(调用成功、失败都会执行) 示例代码如下:
// 页面结构代码
<button type="primary" bindtap="gotoInfo">跳转info页面</button>
// 通过编程式导航,跳转到 info 页面
gotoInfo(){
wx.navigateTo({
url:"/pages/message/message"
})
} -
后退导航
调用 wx.navigateBack(Object object) 方法,可以返回上一页面或多级页面。其中 Object 参数对象可选的属性列表如下:
属性 类型 默认值 是否必选 说明 delta number 1 否 返回的页面数,如果 delta 大于现有页面数,则返回到首页 success function 否 接口调用成功的回调函数 fail function 否 接口调用失败的回调函数 complete function 否 接口调用结束的回调函数(调用成功、失败都会执行) 实例代码如下:
// 页面结构
<button bindtap="gotoBack">后退</button>
// 编程式导航,后退到上一页面
gotoBack(){
wx.navigateBack();
}
页面导航 – 导航传参
-
声明式导航传参
navigator 组件的 url 属性用来指定将要跳转到的页面的路径。同时,路径的后面还可以携带参数:
代码示例如下:
<navigator url="/pages/info/info?name=ceshi&age=10">跳转到info页面带参数</navigator>
-
参数与路径之间使用 ? 分隔
-
参数键与参数值用 = 相连
-
不同参数用 & 分隔
-
编程式导航传参
调用 wx.navigateTo(Object object) 方法跳转页面时,也可以携带参数,代码示例如下:
// 页面结构
<button bindtap="gotoInfo2">编程式导航传参</button>
gotoInfo2(){
wx.navigateTo({
url: '/pages/info/info?name=ss&age=12',
})
} -
在 onLoad 中接收导航参数
通过声明式导航传参或编程式导航传参所携带的参数,可以直接在 onLoad 事件中直接获取到,示例代码如下:
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
// 导航传参接收
console.log(options);
}
页面事件 – 下拉刷新事件
-
什么是下拉刷新
下拉刷新是移动端的专有名词,指的是通过手指在屏幕上的下拉滑动操作,从而重新加载页面数据的行为。
-
启用下拉刷新
启用下拉刷新有两种方式:
全局开启下拉刷新
局部开启下拉刷新
在实际开发中,推荐使用第 2 种方式,为需要的页面单独开启下拉刷新的效果。
-
在页面的 .json 配置文件中,将 enablePullDownRefresh 设置为 true -
在 app.json 的 window 节点中,将 enablePullDownRefresh 设置为 true -
配置下拉刷新窗口的样式
在全局或页面的 .json 配置文件中,通过 backgroundColor 和 backgroundTextStyle 来配置下拉刷新窗口的样式,其中:
-
backgroundColor 用来配置下拉刷新窗口的背景颜色,仅支持16 进制的颜色值
-
backgroundTextStyle 用来配置下拉刷新 loading 的样式,仅支持 dark 和 light
-
监听页面的下拉刷新事件
在页面的 .js 文件中,通过 onPullDownRefresh() 函数即可监听当前页面的下拉刷新事件。例如,在页面的 wxml 中有如下的 UI 结构,点击按钮可以让 count 值自增 +1:
// 页面结构
<view>count值:{{count}}</view>
<button bindtap="countAdd">+1</button>
// +1 按钮的点击事件处理函数
countAdd(){
this.setData({
count:this.data.count+1
})
}监听页面的下拉刷新事件
在触发页面的下拉刷新事件的时候,如果要把 count 的值重置为 0,示例代码如下:
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
this.setData({
count:0
})
} -
停止下拉刷新的效果
当处理完下拉刷新后,下拉刷新的 loading 效果会一直显示,不会主动消失,所以需要手动隐藏下拉刷新的 loading 效果。此时,调用 wx.stopPullDownRefresh() 可以停止当前页面的下拉刷新。示例代码如下:
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
this.setData({
count:0
});
// 当数据重置成功之后,调用此函数,关闭下拉刷新效果
wx.stopPullDownRefresh()
}
页面事件 – 上拉触底事件
-
什么是上拉触底
上拉触底是移动端的专有名词,通过手指在屏幕上的上拉滑动操作,从而加载更多数据的行为。
-
监听页面的上拉触底事件
在页面的 .js 文件中,通过 onReachBottom() 函数即可监听当前页面的上拉触底事件。示例代码如下:
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
console.log("出发了上拉触底事件")
} -
配置上拉触底距离
上拉触底距离指的是触发上拉触底事件时,滚动条距离页面底部的距离。
可以在全局或页面的 .json 配置文件中,通过 onReachBottomDistance 属性来配置上拉触底的距离。
小程序默认的触底距离是 50px,在实际开发中,可以根据自己的需求修改这个默认值。
页面事件 – 上拉触底案例
-
案例效果展示
-
案例的实现步骤
-
定义获取随机颜色的方法
-
在页面加载时获取初始数据
-
渲染 UI 结构并美化页面效果
-
在上拉触底时调用获取随机颜色的方法
-
添加 loading 提示效果
-
对上拉触底进行节流处理
-
实现步骤
步骤1 – 定义获取随机颜色的方法
/**
* 页面的初始数据
*/
data: {
// 随机颜色列表
colorList:[]
},
// 获取随机颜色
getColors(){
wx.request({
url: 'https://applet-base-api-t.itheima.net/api/color',
method:"GET",
success:({data:res})=>{
// console.log(res);
this.setData({
colorList:[...this.data.colorList,...res.data]
})
}
})
}步骤2 – 在页面加载时获取初始数据
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
this.getColors();
}步骤3 – 渲染 UI 结构并美化页面效果
// 对应的 wxml 页面
<view class="num-item" style="background-color:rgb({{item}});" wx:for="{{colorList}}" wx:key="index">{{item}}</view>
// 样式
.num-item{
border: 1rpx solid #efefef;
border-radius: 8rpx;
line-height: 200rpx;
margin: 5rpx;
text-align: center;
text-shadow: 0rpx 0rpx 5rpx #fff;
box-shadow: 1rpx,1rpx,6rpx,#aaa;
}步骤4 – 上拉触底时获取随机颜色
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
this.getColors();
}步骤5 – 添加 loading 提示效
// 获取随机颜色
getColors(){
wx.showLoading({
title: '数据加载中',
});
wx.request({
// 省略......
complete:()=>{
wx.hideLoading();
}
})
},步骤6 – 对上拉触底进行节流处理
在 data 中定义 isloading 节流阀
在 getColors() 方法中修改 isloading 节流阀的值
在 onReachBottom 中判断节流阀的值,从而对数据请求进行节流控制
// data 添加 isloading
data: {
colorList:[],
isloading:false
},
// 获取随机颜色
getColors(){
this.setData({
isloading:true
});
// 省略......
wx.request({
// 省略......
complete:()=>{
wx.hideLoading();
this.setData({
isloading:false
});
}
})
}, -
如果节流阀的值为 true,则阻止当前请求
-
如果节流阀的值为 false,则发起数据请求
-
在刚调用 getColors 时将节流阀设置 true
-
在网络请求的 complete 回调函数中,将节流阀重置为 false
-
false 表示当前没有进行任何数据请求
-
true 表示当前正在进行数据请求
生命周期
-
什么是生命周期
生命周期(Life Cycle)是指一个对象从创建 -> 运行 -> 销毁的整个阶段,强调的是一个时间段。例如:
我们可以把每个小程序运行的过程,也概括为生命周期:
-
小程序的启动,表示生命周期的开始
-
小程序的关闭,表示生命周期的结束
-
中间小程序运行的过程,就是小程序的生命周期
-
张三出生,表示这个人生命周期的开始
-
张三离世,表示这个人生命周期的结束
-
中间张三的一生,就是张三的生命周期
-
生命周期的分类
在小程序中,生命周期分为两类,分别是:
应用生命周期
页面生命周期
其中,页面的生命周期范围较小,应用程序的生命周期范围较大,如图所示:
-
特指小程序中,每个页面的加载 -> 渲染 -> 销毁的过程 -
特指小程序从启动 -> 运行 -> 销毁的过程 -
什么是生命周期函数
生命周期函数:是由小程序框架提供的内置函数,会伴随着生命周期,自动按次序执行。
生命周期函数的作用:允许程序员在特定的时间点,执行某些特定的操作。例如,页面刚加载的时候,可以在 onLoad 生命周期函数中初始化页面的数据。
注意:生命周期强调的是时间段,生命周期函数强调的是时间点。
-
生命周期函数的分类
小程序中的生命周期函数分为两类,分别是:
应用的生命周期函数
页面的生命周期函数
-
特指小程序中,每个页面从加载 -> 渲染 -> 销毁期间依次调用的那些函数 -
特指小程序从启动 -> 运行 -> 销毁期间依次调用的那些函数 -
应用的生命周期函数
小程序的应用生命周期函数需要在 app.js 中进行声明,示例代码如下:
// app.js 文件
App({
// 小程序初始化完成,执行此函数,全局只触发一次。可以做一些初始化工作
onLaunch:function(options){},
// 小程序启动,或从后台进入前台显示时触发,
onShow:function(options){},
// 小程序从前台进入后台时触发
onHide:function(){}
}) -
页面的生命周期函数
小程序的页面生命周期函数需要在页面的 .js 文件中进行声明,示例代码如下:
// 页面的 .js 文件
Page({
onLoad:function(options){}, // 监听页面加载,一个页面只调用1次
onShow:function(){}, // 监听页面显示
onReady:function(){}, // 监听页面初次渲染完成,一个页面只调用1次
onHide:function(){}, // 监听页面隐藏
onUnload:function(){} // 监听页面卸载,一个页面只调用1次
})
WXS 脚本 – 概述
-
什么是 wxs
WXS(WeiXin Script)是小程序独有的一套脚本语言,结合 WXML,可以构建出页面的结构。
-
wxs 的应用场景
wxml 中无法调用在页面的 .js 中定义的函数,但是,wxml 中可以调用 wxs 中定义的函数。因此,小程序中 wxs 的典型应用场景就是“过滤器”。
-
wxs 和 JavaScript 的关系*
虽然 wxs 的语法类似于 JavaScript,但是 wxs 和 JavaScript 是完全不同的两种语言:
wxs 有自己的数据类型
wxs 不支持类似于 ES6 及以上的语法形式
wxs 遵循 CommonJS 规范
-
module 对象
-
require() 函数
-
module.exports 对象
-
不支持:let、const、解构赋值、展开运算符、箭头函数、对象属性简写、etc…
-
支持:var 定义变量、普通 function 函数等类似于 ES5 的语法
-
number 数值类型、string 字符串类型、boolean 布尔类型、object 对象类型、
-
function 函数类型、array 数组类型、 date 日期类型、 regexp 正则
WXS 脚本 – 基础语法
-
内嵌 wxs 脚本
wxs 代码可以编写在 wxml 文件中的
标签内,就像 Javascript 代码可以编写在 html 文件中的
自定义组件 – behaviors
-
什么是 behaviors
behaviors 是小程序中,用于实现组件间代码共享的特性,类似于 Vue.js 中的 “mixins”。
-
behaviors 的工作方式
每个 behavior 可以包含一组属性、数据、生命周期函数和方法。组件引用它时,它的属性、数据和方法会被合并到组件中。
每个组件可以引用多个 behavior,behavior 也可以引用其它 behavior。
-
创建 behavior
调用 Behavior(Object object) 方法即可创建一个共享的 behavior 实例对象,供所有的组件使用:
创建对应的 behavior 的 js 文件
// 使用 Behavior() 方式,创建实例对象
// 并使用 module.exports 将 behavior 共享出去
module.exports = Behavior({
// 属性节点
properties:{},
// 私有属性节点
data:{username:"ceshi",age:20},
// 事件处理函数和自定义方法节点
methods:{}
// 其他节点...
}) -
导入并使用 behavior
在组件中,使用 require() 方法导入需要的 behavior,挂载后即可访问 behavior 中的数据或方法,示例代码如下:
// 使用 require() 导入需要定义的 behavior
const myBehavior = require("../../behaviors/my-behavior");
Component({
// 将导入的 behavior 实例对象,挂载到 behavior 数组节点中,即可生效
behaviors:[myBehavior],
// 组件的其他节点
}) -
behavior 中所有可用的节点
可用的节点 类型 是否必填 描述 properties Object Map 否 同组件的属性 data Object 否 同组件的数据 methods Object 否 同自定义组件的方法 behaviors String Array 否 引入其它的 behavior created Function 否 生命周期函数 attached Function 否 生命周期函数 ready Function 否 生命周期函数 moved Function 否 生命周期函数 detached Function 否 生命周期函数 -
同名字段的覆盖和组合规则*
组件和它引用的 behavior 中可以包含同名的字段,此时可以参考如下 3 种同名时的处理规则:
关于详细的覆盖和组合规则,大家可以参考微信小程序官方文档给出的说明:链接
-
同名的数据字段 (data)
-
同名的属性 (properties) 或方法 (methods)
-
同名的生命周期函数
安装和使用 Vant 组件库
小程序对 npm 的支持与限制
目前,小程序中已经支持使用 npm 安装第三方包,从而来提高小程序的开发效率。但是,在小程序中使用 npm 包有如下 3 个限制:
不支持依赖于 Node.js 内置库的包
不支持依赖于浏览器内置对象的包
不支持依赖于 C++ 插件的包 总结:虽然 npm 上的包有千千万,但是能供小程序使用的包却“为数不多”。
-
什么是 Vant Weapp
Vant Weapp 是有赞前端团队开源的一套小程序 UI 组件库,助力开发者快速搭建小程序应用。它所使用的是 MIT 开源许可协议,对商业使用比较友好。
官方文档地址:链接
扫描下方的小程序二维码,体验组件库示例:
-
安装 Vant 组件库
在小程序项目中,安装 Vant 组件库主要分为如下 3 步:
详细的操作步骤,大家可以参考 Vant 官方提供的快速上手教程:链接
-
通过 npm 安装(建议指定版本为@1.3.3),在小程序项目根目录打开终端或命令窗口
安装之前初始化一个 json 包
npm init -y
安装下载 Vant 包
npm install @vant/weapp@1.3.3 -S --production
-
构建 npm 包
微信小程序开发工具,工具栏目录下有构建 npm,点击构建后,项目中会出现构建成功的文件加
miniprogram_npm
-
修改 app.json
将 app.json 中的
"style": "v2"
去除,小程序的新版基础组件强行加上了许多样式,难以覆盖,不关闭将造成部分组件样式混乱。 -
使用 Vant 组件
对于常用的一些组件,可以在项目根目录
app.json
中添加,以 Button 组件为例,只需要在app.json
或index.json
中配置 Button 对应的路径即可。"usingComponents": {
"van-button": "@vant/weapp/button/index"
}在页面
xx.wxml
直接使用即可,可参考官方文档:链接<van-button type="default">默认按钮</van-button
-
定制全局主题样式
Vant Weapp 使用 CSS 变量来实现定制主题。关于 CSS 变量的基本用法,请参考 MDN 文档:链接
颜色变量,可参考 Vant 官方提供的配置文件:链接
在 app.wxss 中,写入 CSS 变量,即可对全局生效:
page{
--button-primary-background-color:#e00000;
--button-primary-border-color: #ee0000;
}
小程序 API Promise化
-
基于回调函数的异步 API 的缺点
默认情况下,小程序官方提供的异步 API 都是基于回调函数实现的,例如,网络请求的 API 需要按照如下的方式调用:
wx.request({
method :"",
url: "",
data: {},
success:() => [},// 请求成功的回调函数6
fail:() => {},// 请求失败的回调函数6
complete: ()=> {} // 请求完成的回调函数
})缺点:容易造成回调地狱的问题,代码的可读性、维护性差!
-
什么是 API Promise 化
API Promise 化,指的是通过额外的配置,将官方提供的、基于回调函数的异步 API,升级改造为基于 Promise 的异步 API,从而提高代码的可读性、维护性,避免回调地狱的问题。
-
实现 API Promise 化
在小程序中,实现 API Promise 化主要依赖于
miniprogram-api-promise
这个第三方的 npm 包。它的安装和使用步骤如下:在小程序项目根目录下打卡终端或命令行面板安装
npm install --save miniprogram-api-promise@1.0.4
在小程序入口文件中
app.js
,只需调用一次 promisifyAll() 方法,即可实现异步 API 的 Promise 化import {promisifyAll} from "miniprogram-api-promise"
const wxp = wx.p={}
promisifyAll(wx,wxp) -
调用 Promise 化之后的异步 API
// 页面所在的 .wxml 接口
<van-button type="primary" bindtap="getInfo">按钮</van-button>
// 在对应的 .js 文件中,定义对应的 tap 事件处理函数
async getInfo(){
const {data:res} = await wx.p.request({
url:"https://applet-base-api-t.itheima.net/api/get",
method:"GET",
data:{
name:"ceshi",
age:20
}
})
console.log(res)
},
全局数据共享
-
什么是全局数据共享
全局数据共享(又叫做:状态管理)是为了解决组件之间数据共享的问题。开发中常用的全局数据共享方案有:Vuex、Redux、MobX 等。
-
小程序中的全局数据共享方案
在小程序中,可使用 mobx-miniprogram 配合 mobx-miniprogram-bindings 实现全局数据共享。其中:
全局数据共享 – MobX
-
安装 MobX 相关的包
在项目中运行如下的命令,安装 MobX 相关的包:
npm install --save mobx-miniprogram@4.13.2 mobx-miniprogram-bindings@1.2.1
注意:MobX 相关的包安装完毕之后,记得删除 miniprogram_npm 目录后,重新构建 npm
-
创建 MobX 的 Store 实例
在项目根目录中,创建 store 文件夹,创建 store.js 文件,添加以下内容
import { action, observable} from "mobx-miniprogram"
export const store = observable({
// 数据字段
numA:1,
numB:2,
// 计算属性
get sum(){
return this.numA + this.numB;
},
// action 方法,用来修饰 store 中的数据
updateNumA:action(function(step){
this.numA += step
}),
updateNumB:action(function(step){
this.numB += step
})
}) -
将 Store 中的成员绑定到页面中
在页面的 js 文件中绑定 store
// pages/home/home.js
import {createStoreBindings} from "mobx-miniprogram-bindings"
import {store} from "../../store/store"
Page({
/**
* 页面的初始数据
*/
data: {
},
// 按钮绑定事件
btnHandler(e){
// 修改共享数据值
this.updateNumA(e.target.dataset.step);
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.storeBindings = createStoreBindings(this,{
store,
fields:["numA","numB","sum"],
actions:["updateNumA"]
})
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
console.log("销毁共享数据")
this.storeBindings.destroyStoreBindings();
}
}) -
在页面上使用 Store 中的成员
<!-- 全局数据共享 -->
<view>{{numA}} + {{numB}} = {{sum}}</view>
<van-button type="primary" bindtap="btnHandler" data-step="{{1}}">numA + 1</van-button>
<van-button type="info" bindtap="btnHandler" data-step="{{-1}}">numA - 1</van-button>注意:
van-button
标签,是自定义组件,在根目录 app.json 下添加以下内容"usingComponents": {
"van-button": "@vant/weapp/button/index"
} -
将 Store 中的成员绑定到组件中
-
在项目根目录下创建组件 components 文件夹
-
创建 numbers 文件夹,接着创建 numbers 组件
-
在项目全局配置文件 app.json 引用定义的组件,添加以下内容
"usingComponents": {
"van-button": "@vant/weapp/button/index",
"my-numbers": "/components/numbers/numbers"
} -
在组件 numbers.js 文件中绑定 store
import { storeBindingsBehavior } from "mobx-miniprogram-bindings"
import { store } from "../../store/store"
Component({
// 通过 storeBindingsBehavior 实现自动绑定
behaviors:[storeBindingsBehavior],
storeBindings:{
store,
fields:{
// 绑定字段的第一种方式
numA:()=>store.numA,
// 绑定字段的第二种方式
numB:(store)=>store.numB,
// numA:"numA",
// 绑定字段的第三种方式,常用的方式
sum:"sum"
},
// 指定要绑定的方法
actions:{
updateNumB:"updateNumB"
}
},
/**
* 组件的属性列表
*/
properties: {
},
/**
* 组件的初始数据
*/
data: {
},
/**
* 组件的方法列表
*/
methods: {
// 组件页面自定义事件
btnHandler2(e){
this.updateNumB(e.target.dataset.step);
}
}
}) -
在组件中使用 Store 中的成员
<!--numbers.wxml-->
<view>{{numA}} + {{numB}} = {{sum}}</view>
<van-button type="primary" bindtap="btnHandler2" data-step="{{1}}">numB + 1</van-button>
<van-button type="info" bindtap="btnHandler2" data-step="{{-1}}">numB - 1</van-button>
分包 – 基础概念
-
什么是分包
分包指的是把一个完整的小程序项目,按照需求划分为不同的子包,在构建时打包成不同的分包,用户在使用时按需进行加载。
-
分包的好处
对小程序进行分包的好处主要有以下两点:
-
可以优化小程序首次启动的下载时间
-
在多团队共同开发时可以更好的解耦协作
-
分包前项目的构成
分包前,小程序项目中所有的页面和资源都被打包到了一起,导致整个项目体积过大,影响小程序首次启动的下载时间。
-
分包后项目的构成
分包后,小程序项目由 1 个主包 + 多个分包组成:
主包:一般只包含项目的启动页面或 TabBar 页面、以及所有分包都需要用到的一些公共资源
分包:只包含和当前分包有关的页面和私有资源
-
分包的加载规则
在小程序启动时,默认会下载主包并启动主包内页面,tabBar 页面需要放到主包中
当用户进入分包内某个页面时,客户端会把对应分包下载下来,下载完成后再进行展示,非 tabBar 页面可以按照功能的不同,划分为不同的分包之后,进行按需下载
-
分包的体积限制
目前,小程序分包的大小有以下两个限制:
-
整个小程序所有分包大小不超过 16M(主包 + 所有分包)
-
单个分包/主包大小不能超过 2M
分包 – 使用方法
-
配置方法
-
打包原则
-
小程序会按 subpackages 的配置进行分包,subpackages 之外的目录将被打包到主包中
-
主包也可以有自己的 pages(即最外层的 pages 字段)
-
tabBar 页面必须在主包内
-
分包之间不能互相嵌套
-
引用原则
-
主包无法引用分包内的私有资源
-
分包之间不能相互引用私有资源
-
分包可以引用主包内的公共资源
分包 – 独立分包
-
什么是独立分包
独立分包本质上也是分包,只不过它比较特殊,可以独立于主包和其他分包而单独运行。
-
独立分包和普通分包的区别
最主要的区别:是否依赖于主包才能运行
-
普通分包必须依赖于主包才能运行
-
独立分包可以在不下载主包的情况下,独立运行
-
独立分包的应用场景
开发者可以按需,将某些具有一定功能独立性的页面配置到独立分包中。原因如下:
注意:一个小程序中可以有多个独立分包。
-
当小程序从普通的分包页面启动时,需要首先下载主包
-
而独立分包不依赖主包即可运行,可以很大程度上提升分包页面的启动速度
-
独立分包的配置方法
-
引用原则
独立分包和普通分包以及主包之间,是相互隔绝的,不能相互引用彼此的资源!例如:
-
主包无法引用独立分包内的私有资源
-
独立分包之间,不能相互引用私有资源
-
独立分包和普通分包之间,不能相互引用私有资源
-
特别注意:独立分包中不能引用主包内的公共资源
分包 – 分包预下载
-
什么是分包预下载
分包预下载指的是:在进入小程序的某个页面时,由框架自动预下载可能需要的分包,从而提升进入后续分包页面时的启动速度。
"preloadRule": { // 分包预下载的规则
"pages/contact/contact": { // 触发分包预下载的页面路径
// network 表示在指定的网络模式下进行预下载
// 可选值为: all(不限网络) 和 wifi (仅 wifi 模式下进行预下载)
// 默认值为: wifi
"network":"all",
// packages 表示进入页面后,预下载哪些分包
// 可以通过 root 或 name 指定预下载哪些分包
"packages": ["pkgA"]
}
} -
分包预下载的限制
同一个分包中的页面享有共同的预下载大小限额 2M,例如:
自定义 tabBar
-
需要用到的知识点
-
自定义组件 -
Vant 组件库 -
MobX 数据共享 -
组件样式隔离 -
组件数据监听器 -
组件的 behaviors -
Vant 样式覆盖 -
实现步骤
自定义 tabBar 分为 3 大步骤,分别是:
详细步骤,可以参考小程序官方给出的文档:链接
1、在
app.json
中的tabBar
项指定custom
字段,同时其余tabBar
相关配置也补充完整所有 tab 页的 json 里需声明
usingComponents
项,也可以在app.json
全局开启{
"tabBar": {
"custom": true,
......
},
"usingComponents": {
"van-tabbar": "@vant/weapp/tabbar/index",
"van-tabbar-item": "@vant/weapp/tabbar-item/index"
}
}2、创建 tabBar 文件代码,在代码根目录下添加入口文件,注意命名方式,按照官方文档所给出的
custom-tab-bar/index.js
custom-tab-bar/index.json
custom-tab-bar/index.wxml
custom-tab-bar/index.wxss3、参考 vant 组件库对应的 tabBar 内容,链接,复制以下内容到
index.wxml
文件内<van-tabbar active="{{ active }}" bind:change="onChange">
<van-tabbar-item name="home" icon="home-o">标签</van-tabbar-item>
<van-tabbar-item name="search" icon="search">标签</van-tabbar-item>
<van-tabbar-item name="friends" icon="friends-o">标签</van-tabbar-item>
<van-tabbar-item name="setting" icon="setting-o">标签</van-tabbar-item>
</van-tabbar>在
index.js
文件内 data 属性添加active:0
,添加onChange
方法Component({
data: {
active: 0
},
/**
* 组件的方法列表
*/
methods: {
onChange(event) {
// event.detail 的值为当前选中项的索引
this.setData({ active: event.detail });
}
}
})如何动态切换图标呢?动态替换图标内容
index.wxml
页面内容如下<van-tabbar active="{{ active }}" bind:change="onChange" active-color="#13A7A0">
<van-tabbar-item wx:for="{{list}}" wx:key="index" info="{{(item.info && item.info > 0) ? item.info : ''}}">
<image slot="icon" src="{{ item.iconPath }}" mode="aspectFit" style="width: 30px; height: 25px;" />
<image slot="icon-active" src="{{ item.selectedIconPath }}" mode="aspectFit" style="width: 30px; height: 25px;" />
{{item.text}}
</van-tabbar-item>
</van-tabbar>把
app.json
中 tabBar 中 list 数据拿到ustom-tab-bar/index.js
中data
数据下/**
* 组件的初始数据
*/
data: {
active: 0,
"list": [
{
"pagePath": "/pages/home/home",
"text": "首页",
"iconPath": "/images/tabs/home.png",
"selectedIconPath": "/images/tabs/home-active.png"
},
{
"pagePath": "/pages/message/message",
"text": "消息",
"iconPath": "/images/tabs/message.png",
"selectedIconPath": "/images/tabs/message-active.png",
info: 2
},
{
"pagePath": "/pages/contact/contact",
"text": "联系我们",
"iconPath": "/images/tabs/contact.png",
"selectedIconPath": "/images/tabs/contact-active.png"
}
]
},样式覆盖,修改 vant 组件样式是不起作用,官方文档参考。
4、渲染 tarBar 上的数字徽标,把 Store 中的数据绑定到组件中使用,微信官方文档扩展能力,示例
在自定义组件 tabBar 文件
ustom-tab-bar/index.js
中,引入以下内容,注意 store 的相对路径import { storeBindingsBehavior } from "mobx-miniprogram-bindings"
import { store } from "../store/store"
// 和 data 属性同级下添加 behaviors 和 storeBindings 要绑定的字段
// 通过 storeBindingsBehavior 实现自动绑定
behaviors:[storeBindingsBehavior],
storeBindings:{
store,
fields:{
// 绑定字段
sum:"sum",
active:"activeTabBarIndex"
},监听
sum
数值的变化并把值赋值给list
列表中info
字段// 监听 sum 数据变化,并赋值给 'list[1].info'
observers:{
'sum':function(val){
this.setData({
'list[1].info':val
})
}
},5、实现 tabBar 页面的切换效果,首先在
store
公共字段activeTabBarIndex
,代表tarBar
对应页面的索引在
store.js
添加以下方法,可参考上面全局数据共享import { action, observable} from "mobx-miniprogram"
export const store = observable({
// 数据字段
activeTabBarIndex: 0,
// 修改tab索引
updateActiveTabBarIndex: action(function(index) {
this.activeTabBarIndex = index
})
})修改
custom-tab-bar/index.js
方法中onChange
事件/**
* 组件的方法列表
*/
methods: {
onChange(event) {
// event.detail 的值为当前选中项的索引
// this.setData({ active: event.detail });
this.updateActive(event.detail);
wx.switchTab({
// 注意:这里不能跳转的 list 路径前加 /
url: this.data.list[event.detail].pagePath
})
}
}到这里就完成的
tarBar
动态切换效果 -
配置信息 -
添加 tabBar 代码文件 -
编写 tabBar 代码 -
修改
tarBar
选中项文本的值在
custom-tab-bar/index.wxml
页面中van-tabbar
添加标签active-colo
active-color="#13A7A0"
完结
原文始发于微信公众号(师小师):一起学小程序开发
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/226306.html