微信小程序
设置代理
当我们在自己的电脑上配置了其他代理的时候就会影响到微信开发者工具的使用。所以我们可以将微信开发者工具的代理模式修改为
不使用任何代理,勾选后直连网络
创建小程序项目
此步骤不做过多赘述,要注意的就是从官网上找到自己的AppID,然后将自己的AppID填入到对应的位置。
项目结构
1、pages:用来存放所有小程序的页面
2、utils:用来存放工具性质的模块(例如:格式化时间的自定义模块)
3、app.js:小程序项目的入口文件
4、app.json:小程序项目的全局配置文件
5、app.wxss:小程序项目的全局样式文件
6、project.config.json:项目的配置文件
7、sitemap.json:用来配置小程序及其页面是否允许被微信索引
sitemap.json:
1 | { |
新建小程序页面
找到相应的配置文件(微信开发者工具是app.json;Hbulidx是pages.json)在其中的pages对象下按照给定规则新增页面配置,保存后,开发者工具中就会自动新增一个页面文件夹
修改项目首页
只需要调整相应配置文件中pages数组中页面路径的前后顺序,即可修改项目的首页。小程序会把排在第一个位的页面,当作项目首页进行渲染。
wxss和css的区别
1、新增了rpx尺寸单位
CSS中需要手动进行像素单位换算,例如 rem
WXSS在底层支持新的尺寸单位rpx,在不同大小的屏幕上小程序会自动进行换算
2、提供了全局的样式和局部样式
项目根目录中的app.wxss会作用于所有小程序页面
局部页面的.wxss样式仅对当前页面生效
3、WXSS仅支持部分CSS选择器
.class 和 #id
element
并集选择器、后代选择器
::after
和 ::before
等伪类选择器
常用的视图容器类组件
view:
1、普通视图区域
2、类似于HTML中的div,是一个块级元素
3、常用来实现页面的布局效果
scroll-view:
1、可滚动的视图区域
2、常用来实现滚动列表效果
例:
<scroll-view class="container" scroll-y>
注意:使用时一定要给定该容器一个固定的高度
scroll-x:横向滚动
scroll-y:纵向滚动
swiper和swiper-item:
1、轮播图容器组件和轮播图item组件
基本使用:
1 | <!-- indicator-dots 属性:显示面板指示点 --> |
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
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 | 是否采用衔接滑动 |
常用的基础内容组件
1、text
文本组件
类似于HTML中的span标签,是一个行内元素
实现长按选中的效果:<text selectable>内容</text>
2、rich-text
富文本组件
支持把HTML字符串渲染为WXML结构
基本使用:
<rich-text nodes="<h1 style='color: red;'>内容</h1>"></rich-text>
注意这里的
nodes
属性
各组件使用文档:视图容器 | 微信开放文档 (qq.com)
小程序API的3大分类
1、事件监听API
特点:以on开头,用来监听某些事件的触发
例如:wx.onWindowResize(function callback)监听窗口尺寸变化的事件
2、同步API
特点1:以Sync结尾的API都是同步API
特点2:同步API的执行结果,可以通过函数返回值直接获取,如果执行出错会抛出异常
例如:wx.setStorageSync(‘key’, ‘value’)向本地存储中写入内容
3、异步API
特点:类似于jQuery中的$.ajax(options)函数,需要通过success、fail、complete接收调用的结果
例如:wx.request()发起网络数据请求,通过success回调函数接收数据
小程序发布上线
上传代码—>提交审核—>发布
数据绑定
于Vue不同,在小程序中使用mustache语法来绑定数据
例如:<image src="{{imgSrc}}"></image>
三元运算符
小程序的mustache语法
{{xxx ? xxx : xxx}}
中可以写三元运算符
常用的事件
类型 | 绑定方式 | 事件描述 |
---|---|---|
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 | 触摸事件,当前变化的触摸点信息的数组 |
bindtap的语法格式
在小程序中,不存在HTML中的onclick鼠标点击事件,而是通过tap事件来响应用户的触摸行为。
1、通过bindtap,可以为组件绑定tap触摸事件,语法如下:
1 | <button type="primary" bindtap="btnTapHandler">按钮</button> |
2、在页面的.js文件中定义对应的事件处理函数,事件参数通过形参event(一般简写成e)来接收:
1 | Page({ |
在事件处理函数中为data中的数据赋值
通过调用this.setData(dataObject)方法,可以给页面data中的数据重新赋值,示例如下:
1 | //页面的 .js文件 |
事件传参与数据同步
小程序中的事件传参比较特殊,不能在绑定事件的同时为事件处理函数传递参数。例如,下面的代码将不能正常工作:
1 | <button type="primary" bindtap='btnHandler(123)'>事件传参</button> |
因为小程序会把bindtap的属性值,同一当作事件名称来处理,相当于要调用一个名称为btnHandler(123)的事件处理函数。
可以为组件提供data-*自定义属性传参,其中*
代表的是参数的名字,示例代码如下:
1 | <button bindtap="btnHandler" data-info="{{2}}">事件传参</button> |
最终:
1、info会解析为参数的名字
2、数值2会被解析为参数的值
在事件处理函数中,通过event.target.dataset.参数名 即可获取到具体参数的值,示例代码如下:
1 | btnHandler(event) { |
条件渲染
wx:if
在小程序中,使用wx:if=”“ True
1 | <view wx:if="{{condition}}"}> True </view> |
也可以用wx:elif和wx:else来添加else判断:
1 | <view wx:if={{type === 1}}> 男 </view> |
注意:此处和其他编程语言使用if 和 else 方法一样。
结合<block>
使用wx:if
如果要一次性控制多个组件的展示与隐藏,可以使用一个
<block></block>
标签将多个组件包装起来,并在<block>
标签上使用wx:if控制属性,示例如下:
1 | <block wx:if="{{true}}> |
注意:
<block>
并不是一个组件,它只是一个包裹性质的容器,不会再页面中做任何渲染
hidden
在小程序中,直接使用hidden=”“也能控制元素的显示与隐藏
1 | <view hidden="{{condition}}"> 条件为true隐藏,条件为false显示 </view> |
wx:if 与 hidden 的对比
1、运行方式不同
wx:if 以动态创建和移除元素的方式,控制元素的展示与隐藏
hidden以切换样式的方式(display: none/block;),控制样式的显示与隐藏
2、使用建议:
频繁切换时,建议使用hidden
控制条件复杂时,建议使用wx:if搭配wx:elif、wx:else进行展示与隐藏的切换
列表渲染
wx:for
通过wx:for可以根据指定的数组,循环渲染重复的组件结构,语法示例如下:
1 | <view wx:for="{{array}}"> |
默认情况下,当前循环项的索引用index表示;当前循环项用item表示
手动指定索引和当前项的变量名
使用wx:for-index 可以指定当前循环项的索引的变量名
使用wx:for-item 可以指定当前项的变量名
示例代码如下:
1 | <view wx:for="{{array}}" wx:for-index= |
wx:key的使用
类似于Vue列表渲染中的:key,小程序在实现列表渲染时,也建议为渲染出来的列表项指定唯一的key值,从而提高渲染的效率,示例代码如下:
1 | //data 数据 |
wxss
wxss具有css大部分特性,同时,wxss还对css进行了扩充以及修改,以适应微信小程序的开发。与css相比,wxss扩展的特性有:
rpx尺寸单位
@import样式导入
wxss中的rpx单位
rpx(responsive pixel) 时微信小程序独有的,用来解决屏幕适配的尺寸单位
实现原理
rpx的实现原理非常简单:鉴于不同设备屏幕的大小不同,为了实现屏幕的自动适配,rpx吧所有设备的屏幕,在宽度上等分为750份(即:当前屏幕的总宽度为750rpx)
在较小的设备上,1rpx所代表的宽度较小
在较大的设备上,1rpx所代表的宽度较大
小程序在不同的设备上运行的时候,会自动把rpx的样式单位换算成对应的像素单位来渲染,从而实现屏幕的适配
px与px之间的单位换算
在iPhone6上,屏幕宽度为375px,共有750个物理像素,等分为750rpx。则:750rpx = 375px = 750 物理像素
设备 | 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 |
官方建议:开发微信小程序时,设计师可以用iPhone6作为视觉稿的标准。
wxss中的样式导入
使用WXSS提供的@import语法,可以导入外联的样式表
@import后跟需要导入的外联样式表的相对路径,用;表示语句结束。示例如下:
common.wxss:
1 | .small-p { |
app.wxss
1 | @import "common.wxss"; |
wxss全局样式与局部样式
1.局部样式
定义在app.wxss中的样式为全局样式,作用于每一个页面
2.局部样式
在页面的.wxss文件中定义的样式为局部样式,只作用于当前页面。
注意:
1、当局部样式和全局样式冲突时,根据就近原则,局部样式会覆盖全局样式
2、当局部样式的权重大于或等于全局样式的权重时,才会覆盖全局的样式
全局配置
小程序根目录下的app.json文件是小程序的全局配置文件。常用的配置项如下:
pages 记录当前小程序所有页面的存放路径 window 全局设置小程序窗口的外观 tabBar 设置小程序底部的tabBar效果 style 是否启用新版的组件样式
了解window结点常用的配置项
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
navigationBarTitleText | String | 字符串 | 导航栏标题文字内容 |
navigationBarBackgroundColor | HexColor | #000000 | 导航栏背景颜色,如#000000(不能这样写:red) |
navigationBarTextStyle | String | white | 导航栏标题颜色,仅支持black/white |
backgroundColor | HexColor | #ffffff | 下拉刷新时,显示出来的窗口的背景色 |
backgroundTextStyle | String | dark | 下拉loading的样式,仅支持dark/light(三个小圆点的颜色) |
enablePullDownRefresh | Boolean | false | 是否全局开启下拉刷新 |
onReachBottomDistance | Number | 50 | 页面上拉触底事件触发时距页面底部距离,单位为px |
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 | 否 | 未选中时的图标路径;当position为top时,不显示icon |
selectedIconPath | String | 否 | 选中时的图标路径;当position为top时,不显示icon |
1 | "tabBar": { |
页面配置和全局配置的关系
小程序中,app.json中的window结点,可以全局配置小程序中每个页面的窗口表现。如果某些小程序页面想要拥有特殊的窗口表现,此时,“页面级别的.json配置文件”就可以实现这种需求。
注意:当页面配置与全局配置冲突时,根据就近原则,最终的效果以页面配置为准。
小程序中网络数据请求的限制
出于安全性方面的考虑,小程序官方对数据接口的请求做出了如下两个限制:
1、只能请求HTTPS类型的接口
2、必须将接口的域名添加到信任列表中
配置request合法域名的步骤:
登录微信小程序管理后台—>开发—>开发设置—>服务器域名—>修改request合法域名
发起GET/POST请求
调用微信小程序提供的wx.request()方法,可以发起GET数据请求,示例代码如下:
1 | wx.request({ |
在页面刚加载时请求数据
将写好的请求数据的方法写在对应页面的js文件中的onLoad: function(options) {}中
1 | onLoad: function (options) { |
跳过request合法域名校验
注意:跳过request合法域名校验的选项,仅限在开发与调试阶段使用
步骤:微信开发工具中: 详情—>本地设置—>勾选上不校验合法域名、web-view(业务域名)、TLS版本以及HTTPS证书
然后就可以不在域名列表中添加需要发起请求的域名了,而且还可以使用http协议的接口
关于跨域和Ajax的说明
跨域问题只存在于基于浏览器的Web开发中。由于小程序的宿主环境不是浏览器,而是微信客户端,所以小程序中不存在跨域的问题。
Ajax技术的核心是依赖于 浏览器中的XMLHttpRequest这个对象,由于小程序的宿主环境是微信客户端,所以小程序中不能叫做”发起Ajax请求”,而是叫做“发起网络数据请求”。
页面导航
声明式导航
导航到tabBar页面:
tabBar页面指的是被配置为tabBar的页面。
在使用<navigator>
组件跳转到指定的tabBar页面时,需要指定url属性和open-type属性,其中:
url: 表示要跳转的页面的地址,必须为switchTab
open-type表示跳转的方式,必须为switchTab
示例代码如下:
1 | <navigator url="/pages/message/message" open-type="switchTab">导航到消息页面</navigator> |
导航到非tabBar页面:
非tabBar页面指的是没有被配置为tabBar的页面。
在使用
url: 表示要跳转的页面的地址,必须以/
开头
open-type: 表示跳转的方式,必须为navigate
示例代码如下:
1 | <navigator url="/pages/info/info" open-type="navigate">导航到info页面</navigator> |
后退导航:
如果要后退到上一页面或多级页面,则需要指定open-type属性和delta属性,其中:
open-type
的值必须是navigateBack
,表示要进行后退导航
delat
的值必须是数字,表示要后退的层级
示例代码如下:
1 | <navigator open-type="navigateBack" delta="1">返回上一页</navigator> |
注意:为了简便,如果只是后退到上一页面,则可以省略delta属性,因为其默认值就是1。
编程式导航
导航到tabBar页面:
调用wx.switchTab(Object object)方法,可以跳转到tabBar页面。其中Object参数对象的属性列表如下:
属性 | 类型 | 是否必选 | 说明 |
---|---|---|---|
url | string | 是 | 需要跳转的tabBar页面的路径,路径后不能带参数 |
success | function | 否 | 接口调用成功的回调函数 |
fail | function | 否 | 接口调用失败的回调函数 |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
示例代码如下:
1 | <button bindtap="gotoMessage">跳转到消息页面</button> |
1 | gotoMessage() { |
导航到非tabBar页面:
调用wx.navigateTo(Object object)方法,可以跳转到tabBar页面。其中Object参数对象的属性列表如下:
属性 | 类型 | 是否必选 | 说明 |
---|---|---|---|
url | string | 是 | 需要跳转的tabBar页面的路径,路径后不能带参数 |
success | function | 否 | 接口调用成功的回调函数 |
fail | function | 否 | 接口调用失败的回调函数 |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
示例代码如下:
1 | <button bindtap="gotoInfo">跳转到info页面</button> |
1 | gotoInfo() { |
后退导航:
调用wx.navigateBack(Object object)方法,可以返回上一页面或多级页面。其中Object参数对象的属性列表如下:
属性 | 类型 | 默认值 | 是否必选 | 说明 |
---|---|---|---|---|
delta | number | 1 | 否 | 返回的页面数,如果delta大于现有页面数,则返回到首页 |
success | function | 否 | 接口调用成功的回调函数 | |
fail | function | 否 | 接口调用失败的回调函数 | |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
示例代码如下:
1 | <button bindtap="gotoBack">后退</button> |
1 | gotoBack() { |
导航传参
声明式导航传参
navigator组件的url属性用来指定将要跳转到的页面的路径。同时,路径的后面还可以携带参数:
1、参数与路径之间 ? 分隔
2、参数键与参数值用 = 相连
3、不同参数用 & 分隔
代码示例如下:
1 | <navigator url="/pages/info/info?name=zs&age=20">跳转到info页面</navigator> |
编程式导航传参
调用wx.navigateTo(Object object)方法跳转页面时,也可以携带参数,代码示例如下:
1 | <button bindtap="gotoInfo2">跳转到info页面</button> |
1 | gotoInfo2() { |
在onLoad中接收导航参数
通过声明式导航传参或编程式导航传参所携带的参数,可以直接在onLoad事件中直接获取到,示例代码如下:
1 | onLoad: function(options) { |
下拉刷新
启用下拉刷新的两种方式:
1、全局开启下拉刷新
在app.json的window结点中,将enablePullDownRefresh设置为true
2、局部开启下拉刷新
在页面的.json配置文件中,将enablePullDownRefresh设置为true
在实际开发中,推荐是以哦那个第2中方式,为需要的也买你单独开启下拉刷新的效果。
配置下拉刷新窗口的样式
在全局或页面的.json配置文件中,通过backgroundColor和backgroundTextStyle来配置下拉刷新窗口的样式,其中:
backgroundColor用来配置下拉刷新窗口的背景颜色,仅支持16进制的颜色值
backgroundTextStyle用来配置下拉刷新loading(3个小圆点)的样式,仅支持dark和light
1 | { |
监听页面的下拉刷新事件
在页面的.js文件中,通过onPullDownRefresh()函数即可监听当前页面的下拉刷新事件。
例如,在页面的wxml中有如下的UI结构,点击按钮可以让count值自增+1,当下拉刷新的时候,count值重置为0
1 | <view>count值为:{{count}}</view> |
1 | countAdd() { |
监听页面的上拉触底事件
在页面的.js文件中,通过onReachBottom()函数即可监听当前页面的上拉触底事件。示例如下:
1 | onReachBottom: function() { |
注意:在上拉触底事件中发请求的时候,我们需要注意
节流
处理,防止在上一个请求没有处理完时,又发出下一个请求。
配置上拉处理距离
在对应页面的.json文件中做相应的配置
上拉距离默认是50
1 | { |
小程序的生命周期函数
应用的生命周期函数
小程序的应用生命周期函数需要在app.js中进行声明,示例代码如下:
1
2
3
4
5
6
7
8
9 //app.js文件
App({
//小程序初始化完成时,执行此函数,全局只触发一次。可以做一些初始化的工作。
onLaunch: function(options) { },
//小程序启动,或从后台进入前台显示时触发。
onShow: function(options) { },
//小程序从前台进入后台时触发。
onHide: function() { }
})
页面的生命周期函数
小程序的页面生命周期函数需要在页面的.js文件中进行声明,示例代码如下:
1 | //页面的.js文件 |
WXS脚本
wxs的应用场景:wxml中无法调用在页面的.js中定义的函数,但是,wxml中可以调用wxs中定义的函数。因此,小程序中wxs的典型应用场景就是“过滤器”。
wxs又自己的数据类型
number数值类型、string字符串类型、boolean布尔类型、object对象类型、function函数类型、array数组类型、date日期类型、regexp正则
wxs不支持类似于ES6即以上的语法形式
不支持: let、const、解构赋值、展开运算符、箭头函数、对象属性简写、etc…
支持:var定义变量、普通function函数等类似于ES5的语法
wxs遵循CommonJS规范
module对象
require()函数
module.exports对象
内嵌wxs脚本
wxs代码可以编写在wxml文件中的
<wxs>
标签内,就像javascript代码可以编写在html文件中的<script>
标签内一样。wxml文件中的每个
<wxs></wxs>
标签,必须提供module属性,用来指定当前wxs的模快名称,方便在wxml中访问模块中的成员:
1 | <view>{{m1.toUpper(username)}}</view> |
定义外联的wxs脚本
可以在utils文件夹下创建一个
tools.wxs
wxs代码还可以编写在以.wxs为后缀名的文件内,就像javascript代码可以编写在以.js为后缀名的文件中一样。示例代码如下:
1 | function toLower(str) { |
使用外联的wxs脚本
在wxml中引入外联的wxs脚本时,必须为
<wxs>
标签添加module和src属性,其中:
module用来指定模块的名称
src用来指定要引入的脚本的路径,且必须是相对路径
示例代码如下:
1 | <!-- 调用m2模块中的方法 --> |
wxs的特点
不能作为组件的事件回调:
wxs典型的应用场景就是“过滤器”,经常配合Mustache语法进行使用,例如:
1 | <view>{{m2.toLower(country)}}</view> |
但是,在wxs中定义的函数不能作为组件的事件回调函数。例如,下面的用法是
错误的
1 | <button bindtap="m2.toLower">按钮</button> |
隔离性:
隔离性指的是wxs的运行环境和其他JavaScript代码是隔离的。体现在如下两方面:
wxs不能调用js中定义的函数
wxs不能调用小程序提供的API
性能好:
在IOS设备上,小程序内的WXS会比JavaScript代码快2~20倍
在android设备上,二者的运行效率无差异
自定义组件
创建组件
1、在项目的根目录中,鼠标右键,创建components->test文件夹 (其中test为组件名)
2、在新建的components->test文件夹上,鼠标右键,点击“新建Component”
3、键入组件的名称之后回车,会自动生成组件对应的4个文件,后缀名分别为.js, .json , .wxml 和 .wxss
注意:为了保证目录结构的清晰,建议把不同的组件,存放到单独目录中
引用组件
组件的引用方式分为“局部引用”和“全局引用”
局部引用:组件只能在当前被引用的页面内使用
全局引用:组件可以在每个小程序页面中使用
局部引用组件
在
页面的
.json配置文件中引用组件的方式,叫做“局部引用”。示例代码如下:
1
2
3
4
5
6 //在页面的.json文件中,引入组件
{
"usingComponents": {
"my-test": "/components/test/test"
}
}在页面的.wxml文件中,使用组件
1 <my-test1></my-test1>
全局引用组件
在app.json全局配置文件中引用组件的方式,叫做“全局引用”。示例代码如下:
1
2
3
4
5
6 //在app.json文件中,引入组件
{
"usingComponents:" {
"my-test": "/components/test/test"
}
}在任意一个页面中的.wxml文件中,使用该组件
1 <my-test></my-test>
组件和页面的区别
从表面来看,组件和页面都是由.js、.json、.wxml和.wxss这四个文件组成的。但是,组件和页面的.js与.json文件有明显的不同:
组件的.json文件中需要声明“component”: true属性
组件的.js文件中调用的是Component()函数
组件的事件处理函数需要定义到methods节点中
自定义组件样式
组件样式隔离
默认情况下,自定义组件的样式只对当前组件生效,不会影响到组件之外的UI结构。
好处:1、防止外界的样式影响组件内部的样式 2、防止组件的样式破坏外界的样式
组件样式隔离的注意点
app.wxss中的全局样式对对组件无效
只有class选择器会有样式隔离效果,id选择器、属性选择器、标签选择器不受样式隔离的影响
建议:在组件的引用组件的页面中建议使用class选择器,不要使用id、属性、标签选择器!
修改组件的样式隔离选项
默认情况下,自定义组件的样式隔离特性能够防止组件内外样式互相干扰的问题。但有时,我们希望在外界能够控制组件内部的样式,此时,可以通过styleIsolation修改组件的样式隔离选项,用法如下:
styleIsolation的可选值:
可选值 | 默认值 | 描述 |
---|---|---|
isolated | 是 | 表示启用样式隔离,在自定义组件内外,使用class指定的样式将不会互相影响 |
apply-shared | 否 | 表示页面wxss样式将影响到自定义组件,但自定义组件wxss中指定的样式不会影响页面 |
shared | 否 | 表示页面wxss样式将影响到自定义组件,自定义组件wxss中指定的样式也会影响页面和其他设置了apply-shared或shared的自定义组件 |
1
2
3
4
5
6 //在组件的.js文件中新增如下配置
Component({
options: {
styleIsolation: 'isolated'
}
})
1
2
3
4 //或在组件的.json文件中新增如下配置
{
"styleIsolation": 'isolated'
}
自定义组件中的methods方法
在小程序组件中,事件处理函数 和自定义方法需要定义到methods结点中,示例代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14 Components({
methods: { //组件的方法列表[包含事件处理函数和自定义方法]
addCount() {// 事件处理函数
this.setData({count: this.data.count + 1})
this._showCount() //通过this直接调用自定义方法
},
_showCount() {//自定义方法建议以 _ 开头
wx.showToast({
title: 'count值为:' + this.data.count,
icon: 'none'
})
}
}
})
自定义组件的properties属性
在小程序组件中,properties是组件的对外属性,用来接收外界传递到组件中的数据,示例代码如下:
1
2
3
4
5
6
7
8
9
10 Component({
//属性定义
properties: {
max: {//完整定义属性的方式【当需要指定属性默认值时,建议使用此方式】
type: Number,//属性值的数据类型
value: 10//属性默认值
},
max: Number//简化定义属性的方式【不需指定属性默认值,可以使用简化方式】
}
})
1 <my-test1 max="10"></my-test1>
data和properties的区别
在小程序的组件中,properties属性和data数据的用法相同,它们都是可读可写的,只不过:
data更倾向于存储组件的私有数据
properties更倾向于存储外界传递到组件中的数据
由于data数据和properties属性在本质上没有任何区别,因此properties属性的值也可以用于页面渲染,也可以使用setData为properties中的属性重新赋值,示例代码如下:
1
2 //在组件的.wxml文件中使用properties属性的值
<view>max属性的值为:{{max}}</view>
1
2
3
4
5
6
7
8
9
10 Component({
properties: {max: Number},//定义属性
methods: {
addCount() {
this.setData({
max: this.properties.max + 1
})//使用setData修改属性的值
}
}
})
自定义组件的事件监听器
数据监听器用于监听和响应任何属性和数据字段的变化,从而执行特定的操作。它的作用类似于vue中的watch侦听器。在小程序组件中,数据监听器的基本语法格式如下:
1
2
3
4
5
6
7 Component({
observers: {
'字段A, 字段B': function(字段A的新值, 字段B的新值) {
//do something
}
}
})
数据监听器的基本用法
组件的UI结构如下:
1 | // 组件的UI结构如下 |
组件的.js文件代码如下:
1 | Component({ |
监听对象属性的变化
数据监听器支持监听对象中单个或多个属性的变化,示例代码如下:
1 | Component({ |
纯数据字段
纯数据字段指的是哪些不用于界面渲染的data字段
应用场景:例如有些情况下,某些data种的字段既不会展示到界面上,也不会传递给其他组件,仅仅在当前组件内部使用。带有这种特性的data字段适合被设置为纯数据字段
好处:纯数据字段有助于提升页面更新的性能。
使用规则
在Component构造器的options结点中,指定pureDataPattern为一个正则表达式,字段名符合这个正则表达式的字段将成为纯数据字段,示例代码如下:
1 | Component({ |
自定义组件的声明周期函数
生命周期函数 | 参数 | 描述说明 |
---|---|---|
created | 无 | 在组件实例刚刚被创建时执行 |
attached | 无 | 在组件实例进入页面结点树时执行 |
ready | 无 | 在组件在视图层布局完成后执行 |
moved | 无 | 在组件实例被移动到结点树另一个位置时执行 |
detached | 无 | 在组件实例被从页面结点树移除时执行 |
error | Object Error | 每当组件方法抛出错误时执行 |
自定义组件主要的生命周期函数
在小程序组件中,最重要的生命周期函数有3个,分别是created、attached、detached。它们各自的特点如下:
组件实例刚被创建好的时候,created生命周期函数会被触发
此时还不能调用setData
通常在这个生命周期函数中,只应该用于给组件的this添加一些自定义的属性字段
在组件完全初始化完毕、进入页面结点树后,attached生命周期函数会被触发
此时,this.data已被初始化完毕
这个生命周期很有用,绝大多数初始化的工作可以在这个时机进行(例如发请求获取初始数据)
在组件离开页面结点树后,detached生命周期函数会被触发
退出一个页面时,会触发页面内每个自定义组件的detached生命周期函数
此时适合做一些清理性质的工作
自定义组件生命周期函数的使用
在小程序组件中,生命周期函数可以直接定义在Component构造器的第一级参数中,可以在
lifetimes
字段内进行声明(这是推荐的方式,其优先级最高)。示例代码如下:
1
2
3
4
5
6
7
8
9
10 Component({
//推荐用法
lifetimes: {
attached() { }, //在组件实例进入页面结点树时执行
detached() { }, //在组件实例被从页面结点树移除时执行
},
//以下是旧式的定义方式
attached() { }, // 在组件实例进入页面结点树时执行
detached() { } //在组件实例被从页面结点树移除时执行
})
组件所在页面的生命周期
有时,自定义组件的行为依赖于页面状态的变化,此时就需要用到组件所在页面的生命周期。
例如:每当触发页面的show生命周期函数的时候,我们希望能够重新生成一个随机的RGB颜色值。
在自定义组件中,组件所在页面的生命周期函数 有如下3个,分别是:
生命周期函数 参数 描述 show 无 组件所在的页面被展示时执行 hide 无 组件所在的页面被隐藏时执行 resize Object Size 组件所有的页面尺寸变化时执行
pageLifetimes结点
组件所在页面的生命周期函数,需要定义在pageLifetimes结点中,示例代码如下:
1
2
3
4
5
6
7 Component({
pageLifetimes: {
show: function() { }, // 页面被展示
hide: function() { }, //页面被隐藏
resize: function(size) { } //页面尺寸变化
}
})
插槽
在自定义组件的wxml结构中,可以提供应给
<slot>
结点(插槽),用于承载组件使用者提供的wxml结构。
单个插槽
在小程序中,默认每个组定义组件中只允许使用一个
<slot>
进行占位,这种个数上的限制叫做单个插槽。
1 | <!-- 组件的封装者 --> |
1 | <!-- 组件的使用者 --> |
启用多个插槽
在小程序的自定义组件中,需要使用多
<slot>
插槽时,可以在组件的.js文件中,通过如下方式进行启用。
示例代码如下:
1 | Component({ |
定义多个插槽
可以在组件的.wxml中使用多个
<slot>
标签,以不同的name来区分不同的插槽。示例代码如下:
1 | <!-- 组件模板 --> |
父子组件之间的通信
3种通信方式
1、属性绑定
用于父组件向子组件的指定属性设置数据,仅能设置JSON兼容的数据(只能传递数据,不能传递方法)
2、事件绑定
用于子组件向父组件传递数据,可以传递任意数据
3、获取组件实例
父组件还可以通过this.selectComponent()
获取子组件实例对象
这样就可以直接访问子组件的任意数据和方法
属性绑定
属性绑定用于实现父向子传值,而且只能传递普通类型的数据,无法将方法传递给子组件。父组件的示例代码如下:
1 | //父组件的data结点 |
1 | //父组件的wxml结构 |
子组件在properties结点中声明对应的属性并使用。示例代码如下:
1 | //子组件的properties结点 |
1 | //子组件的wxml结构 |
事件绑定
事件绑定用于实现子向父传值,可以传递任何类型的数据。使用步骤如下:
1、在父组件的.js中,定义一个函数,这个函数即将通过自定义事件的形式,传递给子组件
2、在父组件的wxml中,通过自定义事件的形式,将步骤1中定义的函数引用,传递给子组件
3、在子组件的js中,通过调用
this.triggerEvent('自定义事件名称', {/* 参数对象 */})
,将数据发送到父组件4、在父组件的js中,通过e.detail获取到子组件传递过来的数据
每个步骤的具体操作:
步骤1:在父组件的js中,定义一个函数,这个函数即将通过自定义事件的形式,传递给子组件。
1 | //在父组件中定义syncCount方法 |
步骤2:在父组件的wxml中,通过自定义事件的形式,将步骤1中定义的函数引用,传递给子组件
1 | <!-- 使用bind:自定义事件名称(推荐:结构清晰) --> |
步骤3:在子组件的js中,通过调用
this.triggerEvent('自定义事件名称', {/* 参数对象 */})
,将数据发送到父组件。
1 | //子组件的wxml结构 |
1 | //子组件的js代码 |
步骤4:在父组件的js中,通过e.detail获取到子组件传递过来的数据。
1 | syncCount(e) { |
获取组件实例
可在父组件里调用this.selectComponent(“id或class选择器”),获取子组件的实例对象,从而直接访问子组件的任意数据和方法。调用时需要传入一个选择器,例如this.selectComponent(“.my-component”)。
1 | <!-- wxml结构 --> |
1 | getChild() { //按钮的tap事件处理函数 |
behaviors的使用
behaviors是小程序中,用于实现组件间代码共享的特性,类似于Vue.js中的“ mixins ”
behaviors的工作方式
每个behavior可以包含一组属性、数据、生命周期函数和方法。组件引用它时,它的属性、数据和方法会被合并到组件中。每个组件可以引用多个behavior, behavior也可以引用其它behavior。
创建behavior
调用Behavior(Object object)方法即可创建一个共享的behavior实例对象,供所有的组件使用:
1 | //调用Behavior() 方法,创建实例对象 |
导入并使用behavior
在组件中,使用require()方法导入需要的behavior,挂载后即可访问behavior中的数据或方法,示例代码如下:
1 | //1、使用require()导入需要的自定义behavior模块 |
behavior中所有可用的结点
可用的结点 | 类型 | 是否必填 | 描述 |
---|---|---|---|
properties | Object Map | 否 | 同组件的属性 |
data | Object | 否 | 同组件的数据 |
methods | Object | 否 | 同自定义组件的方法 |
behaviors | String Array | 否 | 引入其它的behavior |
created | Function | 否 | 生命周期函数 |
attached | Function | 否 | 生命周期函数 |
ready | Function | 否 | 生命周期函数 |
moved | Function | 否 | 生命周期函数 |
detached | Function | 否 | 生命周期函数 |
同名字段的覆盖和组合规则
https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/behaviors.html
使用npm包
小程序对npm的支持与限制
目前,小程序中已经支持使用npm安装第三方包,从而来提高小程序的开发效率。但是,在小程序中使用npm包有如下3个限制:
- 不支持依赖于 Node.js 内置库的包
- 不支持依赖于浏览器内置对象的包
- 不支持依赖于 C++ 插件的包
总结:虽然npm上的包有千千万,但是能供小程序使用的包却不多
Vant Weapp
Vant Weapp是有赞前端团队开源的一套小程序UI组件库,阻力开发者快速搭建小程序引用。他所使用的是MIT开源许可协议,对商业使用比较友好。
官方文档地址:https://youzan.github.io/vant-weapp
安装Vant组件库
在小程序项目中,安装Vant组件库主要分为如下3步:
- 通过npm安装(建议指定版本为@1.3.3)
- 构建npm包
- 修改app.json
详细操作步骤,可参考Vant官方提供的快速上手教程:快速上手 - Vant Weapp (youzan.github.io)
如果项目目录中没有包管理配置文件package.json
,我们需要执行 npm init -y
使用Vant组件
安装完Vant组件库之后,可以在app.json的usingComponents结点中引入需要的组件,即可在wxml中直接使用组件。示例代码如下:
1 | //app.json |
1 | //页面的.wxml结构 |
CSS变量的使用
例如在.html中写如下代码:
1 | html{ |
解释:在作用域为html中定义一个CSS变量
定制全局主题样式
Vant Weapp使用CSS变量来实现定制主题。关于CSS变量的基本用法,请参考MDN文档:https://developer.mozilla.org/zh-CN/docs/Web/CSS/Using_CSS_custom_properties
在app.wxss中,写入CSS变量,即可对全局生效
1 | /*app.wxss*/ |
解释:因为每个页面的根标签都是
<page>
所以将CSS变量配置到page中每个页面都可访问到这些变量了
小程序API的promise化
基于回调函数的异步API的缺点
默认情况下,小程序官方提供的异步API都是基于回调函数实现的,例如,网络请求的API需要按照如下的方式调用:
1 | wx.request({ |
什么是API Promise化
API Promise化,指的是通过额外的配置,将官方提供的、基于回调函数的异步API,升级改造为基于Promise的异步API,从而提高代码的可读性、维护性,避免回调地狱的问题。
实现API Promise化
在小程序中,实现API Promise化主要依赖于miniprogram-api-promise这个第三方的npm包。它的安装和使用步骤如下:
1 | npm install --save miniprogram-api-promise@1.0.4 |
注意事项:(重要)
然后找到项目的根目录,删除
miniprogram_npm
文件夹;然后点击工具
=>构建npm
1 | //在小程序入口文件中(app.js),只需调用一次promisifyAll()方法, |
调用Promise化之后的异步API
1 | //页面的.wxml结构 |
1 | //在页面的.js文件中,定义对应的tap事件处理函数 |
全局数据共享
全局数据共享(状态管理)是为了解决组件之间数据共享的问题
开发中常用的全局数据共享方案有:Vuwx、Redux、Mobx等。
安装MobX相关的包
在项目中运行如下的命令,安装MobX相关的包:
1 | npm install --save mobx-miniprogram@4.13.2 mobx-miniprogram-bindings@1.2.1 |
注意:MobX相关的包安装完毕之后,记得删除miniprogram_npm目录后,重新构建npm
小程序中的全局数据共享方案
在小程序中,可使用mobx-miniprogram配合mobx-miniprogram-bindings实现全局数据共享。其中:
- mobx-miniprogram用来创建Store实例对象
- mobx-miniprogram-bindings用来把Store中的共享数据或方法,绑定到组件或页面中使用
先在项目目录下创建一个store文件夹,然后在该文件夹下创建一个store.js
store.js:
1 | //在这个JS文件中,专门来创建Store的实例对象 |
将Store中的成员绑定到页面中
1 | //页面的.js文件 |
在页面上使用Store中的成员
1 | //页面的.wxml结构 |
1 | //按钮tap事件的处理函数 |
将Store中的成员绑定到组件中
1 | import { createStoreBindings } from 'mobx-miniprogram-binddings' |
分包
分包指的是把一个完整的小程序项目,按照需求划分为不同的子包,在构建时打包成不同的分包,用户在使用时按需进行加载。
分包的好处:
对小程序进行分包的好处主要有以下两点:
- 可以优化小程序首次启动的下载时间
- 在多团队共同开发时可以更好的解耦协作
分包前项目的构成
分包前,小程序项目中所有的页面和资源都被打包到了一起,导致整个项目体积过大,影响小程序首次启动的下载时间。
分包后项目的构成
分包后,小程序项目由1个主包+多个分包组成:
- 主包:一般只包含项目的启动页面或TabBar页面、以及所有分包都需要用到的一些公共资源
- 分包:只包含和当前分包有关的页面和私有资源
分包的加载规则
在小程序启动时,默认会下载主包并启动主包内页面
- tabBar页面需要放到主包中
当用户进入分包内某个页面时,客户端会把对应分包下载下来,下载完成后再进行展示
- 非tabBar页面可以按照功能的不同,划分为不同的分包之后,进行按需下载
分包的体积限制
目前,小程序分包的大小有以下两个限制:
- 整个小程序所有分包大小不超过16M(主包+所有分包)
- 单个分包/主包大小不能超过2M
分包的使用
在app.json的subpackages结点中声明分包的结构
1 | { |
打包原则
- 小程序会按subpackages的配置进行分包,subpackages之外的目录将被打包到主包中
- 主包也可以有自己的pages(即最外层的pages字段)
- tabBar页面必须在主包内
- 分包之间不能互相嵌套
引用原则
- 主包无法引用分包内的私有资源
- 分包之间不能相互引用私有资源
- 分包可以引用
主包内的
公共资源
独立分包
独立分包本质上也是分包,只不过它比较特殊,可以独立于主包和其它分包而单独运行
独立分包和普通分包的区别:
最主要的区别:是否依赖于主包才能运行
- 普通分包必须依赖于主包才能运行
- 独立分包可以在不下载主包的情况下,独立运行
独立分包的应用场景:
开发者可以按需将某些具有一定功能独立性的页面配置到独立分包中。原因如下:
- 当小程序从普通的分包页面启动时,需要首先下载主包
- 而独立分包不依赖主包即可运行,可以很大程度上提升分包页面的启动速度
注意:一个小程序中可以有多个独立分包
独立分包的配置方法:
在分包的配置中添加一个配置:
"independent": true
1 | { |
引用原则:
独立分包和普通分包以及主包之间是相互隔绝的,不能相互引用彼此的资源!例如:
- 主包无法引用独立分包内的私有资源
- 独立分包之间,不能相互引用私有资源
- 独立分包和普通分包之间,不能相互引用私有资源
特别注意:独立分包中不能引用主包内的公共资源
分包预下载:
分包预下载指的是:在进入小程序的某个页面时,由框架自动与下载可能需要的分包,从而提升进入后续分包页面时的启动速度。
配置分包的预下载:
预下载分包的行为,会在进入指定的页面时触发。在app.json中,使用preloadRule结点定义分包的预下载规则,示例代码如下:
1 | { |
分包预下载的限制:
同一个分包中页面享有共同的预下载大小限额2M
自定义tabBar
自定义tabBar分为3大步骤,分别是:
- 配置信息
- 添加tabBar代码文件
- 编写tabBar代码
具体操作:
- 在
app.json
中的tabBar配置项:"custom": true
- 在项目的根目录中创建一个文件夹命名为
custom-tab-bar
- 然后在该文件夹下创建一个component组件名为
index
详细步骤,可以参考小程序官方给出的文档:https://developers.weixin.qq.com/miniprogram/dev/framework/ability/custom-tabbar.html
使用vant中的组件来自定义tabBar:
官方文档地址:https://youzan.github.io/vant-weapp/#/tabbar
基本使用:
按照官方文档操作
常见问题:
徽标溢出:
数字小图标超出了tabBar的范围
原因:有一个外边距magin-bottom
解决方法:
由于此处给magin-bottom赋值用的是CSS变量,所以我们只需要去修改对应变量的值就行了,具体操作如下:
1
2
3
4//在custom-tab-bar/index.wxss中
.van-tabbar-item {
--tabbar-item-margin-bottom: 0;
}1
2
3
4
5
6//在custom-tab-bar/index.js中
Component({
options: {
styleIsolation: 'shared'
}
})在组件中使用store里面的数据:
进行数据的绑定,将store里面的数据绑定到组件中进行使用
1 | //store.js在这个JS文件中,专门来创建Store的实例对象 |
1 | <!--custom-tab-bar/index.wxml--> |
1 | //custom-tab-bar/index.js |