微信小程序
概述
项目结构
小程序的项目结构
- 目录pages:存放所有小程序的页面
- 目录utils:用来存放工具性质的模块(如格式化时间的自定义模块)
- app.js :小程序项目的入口文件
- app.json:小程序项目的全局配置文件
- app.wxss:全局样式文件
- project.config.json:配置文件
- sitemap.json:配置小程序页面是否允许被微信索引。
存放在pages目录下的每个页面,都由四个基本文件组成:
- .js文件 —— 存放页面的数据,事件处理函数等
- .json文件 —— 配置文件,配置窗口外观等
- .wxml文件 —— 结构文件
- .wxss文件 —— 样式表文件
app.json
app.json 是当前小程序的全局配置,包括了小程序的所有页面路径、窗口外观、界面表现、底部 tab 等。
- pages:用来记录当前小程序所有页面的路径,首页为排第一位的页面。
- window:全局定义小程序所有页面的背景色、文字颜色等
- style:全局定义小程序组件所使用的样式版本
- sitemapLocation:用来指明 sitemap.json 的位置
- tabbar:定义底部tab,设置页面路径,名字,选中与未选中样式图表
1 | { |
project.config.json
project.config.json 是项目配置文件,用来记录我们对小程序开发工具所做的个性化配置,例如:
- setting 中保存了编译相关的配置
- projectname 中保存的是项目名称
- appid 中保存的是小程序的账号 ID
sitemap.json
sitemap.json 文件用来配置小程序页面是否允许 微信索引。
当开发者允许微信索引时,微信会通过爬虫的形式,为小程序的页面内容建立索引。当用户的搜索关键字和页 面的索引匹配成功的时候,小程序的页面将可能展示在搜索结果中。
1 | { |
注意:sitemap 的索引提示是默认开启的,如需要关闭 sitemap 的索引提示,可在小程序项目配置文件 project.config.json 的 setting 中配置字段 checkSiteMap 为 false
WXML模板
WXML(WeiXin Markup Language)是小程序框架设计的一套标签语言,类似于HTML。
区别:
- 标签名称不同
- HTML (div, span, img, a)
- WXML(view, text, image, navigator)
- 属性节点不同
- <a href=”#”>超链接</a>
- <navigator url=”#”></navigator>
- 提供了类似于 Vue 中的模板语法
- 数据绑定
- 列表渲染
- 条件渲染
WXSS样式
是一套样式语言,与CSS的区别:
- 新增rpx尺寸单位: rpx能在不同大小屏幕上的小程序自动进行换算。
- 提供全局的样式和局部样式
- 项目根目录的app.wxss会作用于所有小程序页面。
- 局部页面的 .wxss样式仅对当前页面生效。
- WXSS仅支持部分CSS选择器
- .class 和 #id
- element
- 并集选择器
选择器1,选择器2{css}、后代选择器选择器1 选择器2 {css} - ::after 和 ::before 等伪类选择器
宿主环境
宿主环境指的是程序运行所必须的依赖环境。微信是小程序的宿主程序,借助微信,小程序可以:微信扫码、微信支付、微信登录、地理定位、etc…
小程序宿主环境包含:通信模型,运行机制,组件,API
通信模型
小程序通信的主体是渲染层和逻辑层。
- WXML模板和WXSS样式工作在渲染层;
- JS脚本工作在逻辑层
渲染层与逻辑层之间,逻辑层与第三方服务器间的通信,都是由微信帮忙转发的。
运行机制
小程序启动过程:
- 把小程序的代码包下载到本地
- 解析 app.json 全局配置文件
- 执行 app.js 小程序入口文件,调用 App() 创建小程序实例
- 渲染小程序首页
- 小程序启动完成
页面渲染过程:
- 加载解析页面的 .json 配置文件
- 加载页面的 .wxml 模板和 .wxss 样式
- 执行页面的 .js 文件,调用 Page() 创建页面实例
- 页面渲染完成
组件
小程序组件由宿主环境提供,有9大类:
- 视图容器
- 基础内容
- 表单组件
- 导航组件
- 媒体组件
- map地图组件
- canvas画布组件
- 开放能力
- 无障碍访问
视图容器
view
- 普通视图区域,类似HTML的div,是块级元素。
scroll-view
可滚动的视图区域,可实现滚动列表
```html
A B C 1
2
3
4
5
6
7
8
9
10
11
```css
.view3 {
border: 1px solid red;
height: 100px;
width: 220px;
white-space: nowrap; /* scroll-x生效需要的样式,-y不用 */
}
.view3 view{
display: inline-block;/* scroll-x生效需要的样式,-y不用 */
}
swiper和swiper-item
轮播图组件,和其中的 item组件
常用属性:
属性 类型 默认值 说明 indicator-dots boolean false 是否显示面板指示点 indicator-color color rgba(0,0,0,3) 指示点颜色 indecator-active-color color #000000 当前选中的指示点颜色 autoplay boolean false 是否自动切换 interval number 5000 自动切换时间间隔 circular boolean false 是否采用衔接滑动 1
2
3
4
5
6
7
8
9
10
11<swiper class="swiper1" indicator-dots>
<swiper-item>
<view>A</view>
</swiper-item>
<swiper-item>
<view>B</view>
</swiper-item>
<swiper-item>
<view>B</view>
</swiper-item>
</swiper>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17.swiper1 {
height: 150px;
}
.swiper1 view{
height: 100%;
line-height: 150px;
text-align: center;
}
swiper-item:nth-child(1) {
background-color: lightgreen;
}
swiper-item:nth-child(2) {
background-color: lightskyblue;
}
swiper-item:nth-child(3) {
background-color: lightcoral
}
基础内容
text
文本组件,类似HTML的span标签,是行内元素。
加上selectable元素,可以让文本能被长按选中。
1
<text selectable>长按选中</text>
rich-text
富文本组件,通过nodes属性,能把HTML字符串渲染为WXML结构。
1
<rich-text nodes="<h1>标题</h1>"></rich-text></rich-text>
其他常用组件
button
按钮组件
1
2
3
4
5
6
7
8
9
10
11
12<!-- 通过type指定类型 -->
<button>默认按钮</button>
<button type="primary">主色调按钮</button>
<button type="warn">警告按钮</button>
<!-- size="mini" 小尺寸按钮 -->
<button size="mini">默认小尺寸</button>
<button type="primary" size="mini">主色调小尺寸</button>
<button type="warn" size="mini">警告小尺寸</button>
<!-- plain 镂空按钮 -->
<button size="mini" plain>默认镂空按钮</button>
<button type="primary" size="mini" plain>主色调镂空按钮</button>
<button type="warn" size="mini" plain>警告镂空按钮</button>
image
图片组件,默认宽300px,高240px
1
<image src="/images/1.png"></image>
image组件的mode属性可以指定图片的裁剪和缩放模式:
mode值 说明 scaleToFill (默认值)缩放模式,不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素 aspectFit 缩放模式,保持纵横比缩放图片,使图片的长边能完全显示出来。也就是说,可以完整地将图片显示出来。 aspectFill 缩放模式,保持纵横比缩放图片,只保证图片的短边能完全显示出来。也就是说,图片通常只在水平或垂直方 向是完整的,另一个方向将会发生截取。 widthFix 缩放模式,宽度不变,高度自动变化,保持原图宽高比不变 heightFix 缩放模式,高度不变,宽度自动变化,保持原图宽高比不变
navigator
- 页面导航组件,相当于HTML的a链接
API
分为3类:
事件监听api
特点:以on开头,用来监听某些事件的触发。
同步api:以Sync结尾的api,可以通过函数返回值直接获取,如果执行出错会抛出异常。
异步api:类似 JQuery 中的 $.ajax(options) 函数,需要通过success,fail,complete接收调用
模板与配置
WXML模板语法
事件绑定
数据绑定的基本原则:
在data中定义数据;
1
2
3
4
5
6
7Page({
// 页面的初始数据
data: {
info: 'init data',
msgList: [{msg: 'hello'}, {msg: 'world'}]
}
})在WXML中使用数据;
1
<view>{{ 要绑定的数据名称 }}</view>
关于Mustache语法,即 { { } }:
绑定内容
1
2
3
4
5Page({
data: {
info: 'init data'
}
})1
<view>{{ info }}</view>
绑定属性
1
2
3
4
5Page({
data: {
imgSrc: 'www.baidu.com/images/logo.png'
}
})1
<image src="{{imgSrc}}"></image>
运算
1
2
3
4
5Page({
data: {
randomNum: Math.random * 10
}
})1
<view>{{ randomNum > 5 ? '大于5' : '小于5' }}</view>
事件绑定
常用的事件:
类型 绑定方式 事件描述 tap bindtap 或 bind:tap 手指触摸后离开,类似于HTML的click input bindinput 或 bind:input 文本框的输入事件 change bindchange 或 bind:change 状态改变时触发 事件对象的属性列表:
属性 类型 说明 type String 事件类型 timeStamp Integer 页面打开到触发所要经过的毫秒数 target Object 触发事件的组件的一些属性值集合 currentTarget Object 当前组件的一些属性值集合 detail Object 额外的信息 touches Array 触摸事件,当前停留在屏幕中的触摸点信息的数组 changedTouches Array 触摸事件,当前变化的触摸点信息的数组 target 和 currentTarget:
- target是触发该事件的源头组件,currentTarget则是当前事件所绑定的组件。
- 当点击内部的按钮时,事件会以冒泡的方式向外扩散, e.target是内部被点击的按钮组件, e.currentTarget 外部正在触发事件的那个组件。
bindtap
点击事件
1
<button bindtap="btnTapHandler">按钮</button>
在js中对应的事件处理函数:
1
2
3
4
5Page({
btnTapHandler(e){
console.log(e)
}
})事件处理中为data中的数据赋值:
要调用this.setData()
1
2
3
4
5
6
7
8
9
10Page({
data: {
count: 0
}
changeCount(){
this.setData({
count: this.data.count + 1
})
}
})*事件传参 data-:
小程序中,不能在绑定事件的同时为函数传参。 要使用 data-* 自定义属性来传参,其中 * 号是参数的名字。
1
<button bindtap="btnTapHandler" data-count="{{2}}">按钮</button>
count会被解析为参数的名字,数值2为参数的值。
函数接收:通过 event.target.dataset.参数名 即可获取具体参数的值。
1
2
3
4
5btnTapHandler(e){
//event.target.dataset 是一个对象,包含了所有 data-* 传递的参数项
console.log(event.target.dataset)
console.log(event.target.dataset.count)
}bindinput
文本框输入事件
1
<input bindinput="inputHandler"><input>
1
2
3inputHandler(e){
console.log(e.detail.value)
}实现文本框和data之间的数据同步:
1
<input value="{{msg}}" bindinput="inputHandler"><input>
1
2
3
4
5inputHandler(e){
this.setData({
mag: e.detail.value
})
}
条件渲染
- wx:if
使用 wx:if=”“ 来判断是否需要渲染该代码块。
1 | <view wx:if="{{type === 1}}">男</view> |
结合 <block> 使用 wx:if
如果要一次性控制多个组件的展示/隐藏,可以用 <block> 包起来。
1
2
3
4<block wx:if="{{true}}">
<view>xx</view>
<view>zz</view>
</block><block> 不是组件,只起包裹作用,不会被渲染。
hidden
使用 hidden=”“ 也能控制元素的显示与隐藏
1
<view hidden="{{条件}}">true隐藏,false显示</view>
不同之处:
- wx:if 以动态创建和移除元素的方式,控制元素的展示与隐藏 。
- hidden 以切换样式的方式(display: none/block;)控制元素的显示与隐藏。
建议:
- 频繁切换时,建议使用 hidden
- 控制条件复杂时,建议使用 wx:if 搭配 wx:elif、wx:else 进行展示与隐藏的切换
wx:for
指定数组,然后循环渲染重复的组件结构
1
<view wx:for="{{array}}"></view>
默认情况下,当前的索引用index表示,当前循环项用item表示。
也可以指定index和item:
1
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName"></view>
wx:key —— 实现列表渲染时,建议为列表项指定唯一的key值,能提高渲染效率。
1
2
3
4
5
6
7data: {
userList: [
{id: 1, name: 'tom'},
{id: 2, name: 'army'},
{id: 3, name: 'jack'},
]
}1
<view wx:for="{{userList}}" wx:key="id">{{item.name}}</view>
WXSS模板
与css的区别:
rpx尺寸单位
—— 将所有设备屏幕从宽度上等分为750份,一份即为1rpx;
@import 样式导入
1
@import "外联样式表的路径";
全局配置
app.json 是小程序的全局配置文件,常见配置如下:
- pages:用来记录当前小程序所有页面的路径,首页为排第一位的页面。
- window:全局定义小程序所有页面的背景色、文字颜色等。
- style:是否启用新版的组件样式。
- sitemapLocation:用来指明 sitemap.json 的位置。
- tabbar:定义顶部或底部的tabBar,用于多页面的快速切换,最少设置2个,最多5个,设置页面路径,名字,选中与未选中样式图表。
window节点常用配置项:
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| navigationBarTitleText | String | 字符串 | 导航栏标题文字内容 |
| navigationBarBackgroundColor | HexColor | #000000 | 导航栏背景颜色 |
| navigationBarTextStyle | String | white | 导航栏标题颜色,仅可用blcak和white |
| backgroundColor | HexColor | #fffff | 窗口的背景色 |
| backgroundTextStyle | String | dark | 下拉loading的样式,仅可用dark和light |
| enablePullDownRefresh | Boolean | false | 是否全局开启下拉刷新 |
| onReachBottomDistance | Number | 50 | 页面上拉触底事件触发时据页面底部距离,单位为px |
1 | { |
网络数据请求
处于安全考虑,小程序对数据接口的请求有以下限制:
只能请求HTTPS类型的接口;
必须将接口域名添加到信任列表;
需要登录到小程序后台管理界面, 在开发—开发设置—服务器域名—修改request合法域名(只支持https,不能用ip,需经过ICP备案)
GET请求 —— 调用 wx.request()
1 | wx.request({ |
POST请求 —— 调用 wx.request()
1 | wx.request({ |
在页面刚加载时就请求数据: onLoad事件
1 | Page({ |
视图逻辑
页面导航
页面导航: 页面间的相互跳转。小程序实现页面导航有两种方式:
- 声明式导航: 通过<navigator>导航组件实现跳转。
- 编程式导航:调用导航API。
声明式导航
导航到 tabBar页面:
<navigator>需要指定url和open-type属性。其中 url 以 / 开头, oprn-type 只能指定switchTab为跳转方式。
1
<navigator url="/pages/message/message" open-type="switchTab">导航到消息页面</navigator>
导航到 非tabBar页面:
<navigator>需要指定url和open-type属性。open-type 只能指定navigate为跳转方式。(open-type属性可省略)
1
<navigator url="/pages/info/info" open-type="navigate">导航到info页面</navigator>
后退导航
<navigator>需要指定open-type和delta属性。 其中open-type必须为 navigateBack,delta的值为后退的层级。(如果只退1级,delta可省略)
1
<navigator open-type="navigateBack" delta='1'>返回上一页</navigator>
编程式导航
导航到 tabBar页面
调用 wx.switchTab(Object o) 方法,可跳转到 tabBar页面。参数对象的属性如下:
属性 类型 时候必选 说明 url string 是 需要跳转的tabBar页面路径,路径不能带参数 success function 否 接口调用成功的回调函数 fail function 否 失败时的回调函数 compiete function 否 结束时的回调函数(一定会执行) 1
2
3<button bindtap="gotoMessage">
跳转到消息页面
</button>1
2
3
4
5gotoMessage(){
wx.switchTab({
url: '/pages/message/message'
})
}导航到非tabBar页面
调用 wx.navigateTo(Object o) ,参数对象的属性与 wx.switchTab() 一样,不过url属性能携带参数。
1
2
3<button bindtap="gotoInfo">
跳转到info页面
</button>1
2
3
4
5gotoInfo(){
wx.navigateTo({
url: '/pages/info/info'
})
}后退导航
调用 wx.navigateBack(Object o)方法。
1
2
3<button bindtap="goBack">
后退
</button>1
2
3
4
5goBack(){
wx.navigateBack({
delta: 1
})
}
导航传参
- navigator组件的 url 的路径后可以携带参数。
1 | <navigator url="/pages/info/info?name=Tom&age=20">跳到info页面</navigator> |
- 调用 wx.navigateTo(Object o) 时,url属性也能携带参数。
页面事件
下拉刷新:
- 全局开启:在app.json 的window节点中, 将enablePullDownRefresh 设置为 true。
- 局部开启:页面的 .json文件中,同样将window节点中的 enablePullDownRefresh 设置为 true。
还可以通过 backgroundColor 配置下拉刷新窗口颜色,和 backgroundTextStyle 配置下来刷新loadin的样式(dark和light)
监听:通过 onPullDownRefresh() 可监听当前页面的下拉刷新事件。
停止下拉属性效果: 刷新结束后,下拉的loading效果仍会一直闲置,需要调用 wx.stopPullDownRefresh() 来停止刷新效果。
1
2
3
4onPullDownRefresh: function () {
....
wx.stopPullDownRefresh()
},上拉触底
通过上拉滑动,而加载更多数据。
监听:通过 onReachBottom() 函数可监听页面的上拉触底事件。
上拉触底距离: 在.json文件中,通过 onReachBottomDistance 属性来设置,默认为50px;
生命周期
应用生命周期函数,在app.js中声明:
1 | App({ |
页面声明周期函数,在页面的 .js文件中声明:
1 | Page({ |
WXS脚本
WXS(WeiXin Script)是小程序独有的一套脚本语言。
自定义组件
创建和引用
创建组件: 在根目录的components下,新建组件文件夹。
引用组件:局部引用 / 全局引用,都是在 .json 文件中进行引用:
1 | { |
在 .wxml 中使用
1 | <my-test1></my-test1> |
组件和页面的区别:
- 组件的 .json文件 中需要声明 “component”: true
- 组件的 .js文件中调用的是Component()函数
- 组件的事件处理函数需要定义到methods节点中。
样式隔离
组件的样式隔离:
默认情况下,不同组件间、组件与调用者间的样式不会相互影响;
app.wxss中的全局样式对组件无效;
只有class选择器会有样式隔离效果, 而 id选择器、属性选择器、标签选择器不受样式隔离的影响。
建议在组件和引用组件的页面中使用class选择器,不要用其他选择器,以避免干扰。
修改组件的隔离性:在组件的 .js文件或 .jsonwen文件中通过 styleIsolation修改组件的样式隔离选项。
1
2
3
4
5Component({
options: {
styleIsolation: 'isolated'
}
})1
2
3{
"styleIsolation": "isolated"
}styleIsolation的可选值:
可选值 默认值 描述 isolated 是 启动隔离样式,组件内外,使用class指定的样式不会相互影响 apply-shared 否 页面的样式将影响自定义组件,而组件不会影响页面 shared 否 会相互影响,也会影响其他设置了apply-shared或shared的组件
组成
data数据:组件的私有数据;
1
2
3
4
5component({
data: {
count: 0
}
})methods方法 :事件处理函数和自定义方法需要定义到methods节点中;
1
2
3
4
5
6
7
8
9
10Component({
methods:{
addCount(){ //事件处理函数
},
_showCount(){ //自定义函数,建议以 _ 开头
}
}
})properties属性 :用来接收外界传递进来的数据;
properties属性和data数据本质是一样的,只是用途不一样。 properties中的属性同样可用 setData 重新赋值。
1
2
3
4
5
6
7
8
9
10
11Component({
properties: {
//完整定义属性的方式(需要默认值时)
max: {
type: Number, //数据类型
value: 10 //默认值
},
//简化定义(不需要默认值时)
max: Number
}
})
数据监听器
数据监听器:监听和响应任何属性和数据的变化,并执行操作。
1 | Component({ |
用法例子:
1 | <view>{{n1}}+{{n2}}-{{sum}}</view> |
1 | Component({ |
数据监听器还支持监听对象中单个或多个属性的变化,语法如下:
1 | Component({ |
纯数据字段
纯数据字段:指那些不用于界面渲染的data字段。(即不展现在界面上,也不传递给其他组件,仅仅在组件内部使用)
优势:纯数据字段有助于提升页面更新的性能。
使用规则:在 Component 构造器的 options 节点中,指定 pureDataPattern 为一个正则表达式,字段名符合这个正则表达式的字段将成为纯数据字段
1 | Component({ |
组件的生命周期
| 生命周期函数 | 参数 | 描述说明 |
|---|---|---|
| created | 无 | 在组件实例刚刚被创建时执行 |
| attached | 无 | 组件实例进入页面节点时执行 |
| ready | 无 | 组件在视图层布局完成后执行 |
| moved | 无 | 组件实例被移动到节点树另一个位置时执行 |
| datached | 无 | 在组件实例从页面节点数移除时执行 |
| error | Object Error | 每当组件方法抛出错误时执行 |
重要的三个生命函数:
组件实例刚被创建好的时候,created 生命周期函数会被触发
此时还不能调用 setData
通常在这个生命周期函数中,只应该用于给组件的 this 添加一些自定义的属性字段
在组件完全初始化完毕、进入页面节点树后, attached 生命周期函数会被触发
- 此时, this.data 已被初始化完毕
- 这个生命周期很有用,绝大多数初始化的工作可以在这个时机进行(例如发请求获取初始数据)
在组件离开页面节点树后, detached 生命周期函数会被触发
- 退出一个页面时,会触发页面内每个自定义组件的 detached 生命周期函数
- 此时适合做一些清理性质的工作
定义: 在 lifetimes 内定义生命周期函数(推荐,lifetimes优先级最高)
1 | Component({ |
组件所在页面的生命周期
当自定义组件的行为依赖于页面状态的变化时,就需要用到组件所在页面的生命周期。
组件所在页面的生命周期有三种:
| 生命周期函数 | 参数 | 描述 |
|---|---|---|
| show | 无 | 组件所在页面 被展示时执行 |
| hide | 无 | 组件所在页面 被隐藏时执行 |
| resize | Object Size | 组件所在页面 尺寸变化时执行 |
定义在 pageLifetimes 节点:
1 | Component({ |
插槽
在组件的wxml结构中,可以提供一个 <slot>节点(即 插槽),用于承载组件使用者提供的wxml结构。
也就是,使用者可以将自定义的wxml结构插入组件的<slot>节点位置。
语法:
单个插槽: 默认每个组件只能使用一个<slot>
1
2
3
4
5
6
7
8
9
10
11
12<!-- 组件 -->
<view class="wrapper">
<view>组件内容</view>
<!-- 对于不确定的内容,使用插槽占位,实际内容由使用者决定 -->
<slot></slot>
</view>
<!-- 组件的使用者 -->
<component-tag-name>
<!-- 定义slot处的内容 -->
<view>这里的内容是要插入到slot位置处的</view>
</component-tag-name>多个插槽: 需在.js文件中启用配置。
1
2
3
4
5
6Component({
options: {
multipleSlots: true //启用多slot支持
},
...
})1
2
3
4
5
6
7
8
9
10
11
12
13
14<!-- 组件 -->
<view class="wrapper">
<!-- 使用name属性区分不同slot -->
<slot name="slot1"></slot>
<view>组件内容</view>
<slot name="slot2"></slot>
</view>
<!-- 组件的使用者 -->
<component-tag-name>
<!-- 定义slot处的内容 -->
<view slot="slot1">内容1</view>
<view slot="slot2">内容2</view>
</component-tag-name>
父子组件间的通信
父子组件之间通信的3种方式
属性绑定 —— 父向子传值,向子组件的指定属性设置数据。只能传递普通类型数据,无法传递方法。
例子:父组件:
1
2
3data: {
count: 0
}1
2<my-test count="{{count}}"></my-test>
<view>父组件中,count值为:{{count}}</view>子组件:
1
2
3
4// 子组件的properties节点
properties: {
count: Number
}1
<text>子组件中,count值为{{count}}</text>
事件绑定 —— 子向父传值,可以传递任何类型数据。
父组件的js中,定义一个要传给子组件的函数;
1
2
3syncCount(){
}父组件的wxml中,通过自定义事件将函数传给子组件;
1
2
3
4<!-- bind: 后写自定义事件名称 -->
<my-test bind:sync="syncCount"></my-test>
<!-- 或在bind后直接写事件名称 -->
<my-test bindsync="syncCount"></my-test>子组件的js中,通过 this.triggerEvent(‘事件名’, {参数对象}),将数据发给父组件;
1
2
3
4
5
6
7
8methods: {
addCount(){
this.setData({
count: this.properties.count + 1
})
this.triggerEvent('sync',{value:this.properties.count})
}
}父组件的js中,在那个函数中通过e.detail获取数据;
1
2
3
4
5syncCount(){
this.setData({
count: e.detail.value
})
}
获取组件实例
在父组件里调用 this.selectComponent(“id/class选择器”),获取子组件的实例对象,从而直接访问子组件的任何数据和方法。 调用时需要传入一个选择器。
1
2
3
4<my-test class="customA" id="cA"></my-test>
<button bindtap="getChild">
获取子组件实例
</button>1
2
3
4
5
6
7
8
9getChild(){
const child = this.selectComponent('.customA') //也可以传递id选择器 #cA
//调用子组件的setData方法
child.setData({
count: child.properties.count + 1
})
//调用子组件的addCount方法
child.addCount()
}
behaviors
behaviors 用于实现组件间代码共享。
每个 behavior 可以包含一组属性、数据、生命周期函数和方法。组件引用它时,它的属性、数据和方法会被合并到组件中。
每个组件可以引用多个 behavior,behavior 也可以引用其它 behavior。
使用:
创建behavior
1
2
3
4
5
6
7
8
9
10
11//调用Behavior()方法,创建实例对象
//使用module.exports将对象共享出去
module.exports = Behavior({
//属性节点
properties: {},
//私有数据节点
data: { username: 'zs'},
//事件处理函数和自定义方法节点
methods: {},
//其他节点...
})导入并使用behavior
在组件中,使用require()方法导入需要的behavior,挂在后就可以访问了。
1
2
3
4
5
6const myBehavior = require("../../behaviors/my-behavior")
Component({
behaviors: [myBehavior],
....
})
behaviors中所有可用的节点:
| 可用的节点 | 类型 | 描述 |
|---|---|---|
| properties | Object Map | 属性 |
| data | Object | 数据 |
| methods | Object | 方法 |
| behaviors | String Array | 引入其他的behavior |
| created | Function | 生命周期函数 |
| attached | Function | 生命周期函数 |
| ready | Function | 生命周期函数 |
| moved | Function | 生命周期函数 |
| detached | Function | 生命周期函数 |
同名字段的覆盖规则:
- 使用者的字段 > 当前behavior > 调用的 behavior
npm包
能用,但大部分都不能用。因为小程序的限制:
- 不支持依赖于 Node.js 内置库的包
- 不支持依赖于浏览器内置对象的包
- 不支持依赖于 C++ 插件的包
Vant Weapp
Vant Weapp是一套小程序UI组件库,使用的是MIT开源许可协议,对商业使用较友好。
官方文档地址: https://vant-contrib.gitee.io/vant-weapp/0.x/#/intro
安装Vant组件库:
通过npm安装:npm i @vant/weapp@1.3.3 -S –production
需要先使用 npm init -y 初始化一个包管理配置文件package.json
构建npm包:点击工具-构建npm
使用:
在app.json的usingComponents节点中,引入需要的组件,即可在wxml中直接使用组件。
1 | "usingComponents": { |
1 | <van-button type="primary">按钮</van-button> |
Vant Weapp 使用CSS变量来实现定制主体,在app.wxss中,写入CSS变量,对全局生效:
定义:
1 | page { |
使用:
1 | .e1 { |
如果CSS变量写在其他选择器下,就只在那个选择器范围内生效。
API Promise化
问题:默认情况下,小程序提供的异步API都是基于回调函数实现的。缺点在于,冗余造成回调地狱,代码可读性,可维护性差。
API Promise化,指的是通过额外的配置,将官方提供的异步API,升级为基于Promise的异步API。
实现:
安装:npm install –save miniprogram-api-promise@1.0.4
使用:
1
2
3
4
5//在小程序的入口文件(app.js)中,只需调用一次promisifyAll()方法,即可实现异步API的Promise化
import { promisifyAll } from 'minigrogram-api-promise'
const wxp = wx.p = {}
promisifyAll(wx, wxp)调用Promise化后的异步API:
1
<van-button bindtap="getInfo"></van-button>
1
2
3
4
5
6
7
8async getInfo(){
const {data: res} = await wx.p.request({
method: 'GET',
url: 'https://www.xxxx'
data:{name:'Tom', age:20}
})
console.log(res)
}
全局数据共享
全局数据共享,是为了解决组件间数据共享的问题。开发中常用的方案有:Vuex,Redux,Mobx等。
小程序中,可使用 mobx-miniprogram 配合 mobx-miniprogram-bindings 实现全局数据共享。
- mobx-miniprogram 用于创建Store实例对象;
- mobx-miniprogram-bindings 用于把Store中的共享数据或方法,绑定到组件或页面中使用;
分包
普通分包
分包指把一个完整的小程序项目,按需求划分为不同的子包,使用时按需加载。
好处:优化首次加载时间,多团队开发时更好解耦。
分包后的项目构成:1个主包 + 多个分包。
- 主包:一般只包含启动页面和TabBar页面,以及所有分包都要的公共资源;
- 分包:只包含和当前分包有关的页面和私有资源;
分包大小的限制: 主包+分包不超过16M, 单个包不超过2M
使用分包:在app.json中的 subpackages节点中声明分包的结构。
1 | { |
引用原则:
- 主包无法引用分包内的私有资源 ;
- 分包之间不能相互引用私有资源 ;
- 分包可以引用主包内的公共资源 ;
独立分包
独立分包 能独立于主包和其他分包而单独运行。 可以在不下载主包的情况下,独立运行。
因此,独立分包不能引用其他包的资源,包括主包的公共资源。
使用场景:让小程序从某一分包页面启动时,不用先下载主包。
1 | { |
分包预下载
分包预下载:在进入某页面时,自动下载之后可能需要的分包,从而提升进入其他分包页面的启动速度。
使用:
预下载的行为会在进入指定页面时触发。在app.json中,使用preloadRule节点定义分包的规则。
1 | { |
限制: 一个分包的预下载份额不超过2M,即预下载的分包加起来不能超过2M;
