WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构
WXML 中的动态数据均来自对应 Page 的 data。
数据绑定使用 Mustache 语法(双大括号)将变量包起来,可以作用于:
<!--wxml-->
// 输出内容
<view> {{message}} </view>
// 组件属性
<view id="item-{{id}}"> </view>
// 控制属性
<view wx:if="{{condition}}">显示</view>
// 关键字
<checkbox checked="{{false}}"> </checkbox>
<checkbox checked="{{true}}"> </checkbox>
// 特别注意:不要直接写 checked="false",其计算结果是一个字符串,转成 boolean 类型后代表真值。
// page.js
Page({
data: {
message: 'Hello MINA!',
id: 5,
condition: true
}
})
<!--wxml-->
<view hidden="{{flag ? true : false}}"> Hidden </view>
<view wx:if="{{true}}">显示</view>
<view wx:if="{{false}}">不显示</view>
<view wx:if="{{3<5}}">3小于5为真</view>
<view wx:if="{{length > 5}}"> 1 </view>
<view wx:elif="{{length > 2}}"> 2 </view>
<view wx:else> 3 </view>
// page.js
Page({
data: {
length: 4
}
})
<!--wxml-->
<template name="staffName">
<view>
FirstName: {{firstName}}, LastName: {{lastName}}
</view>
</template>
<template is="staffName" data="{{...staffA}}"></template>
<template is="staffName" data="{{...staffB}}"></template>
<template is="staffName" data="{{...staffC}}"></template>
// page.js
Page({
data: {
staffA: {firstName: 'Hulk', lastName: 'Hu'},
staffB: {firstName: 'Shang', lastName: 'You'},
staffC: {firstName: 'Gideon', lastName: 'Lin'}
}
})
<!--wxml-->
<view wx:for="{{array}}" wx:key="index">{{index}}--{{item}} </view>
<view wx:for="{{array}}" wx:key="index" wx:for-item="v" wx:for-index="k">{{k}}--{{v}} </view>
// page.js
Page({
data: {
array: ['html', 'css','js', 'es', 'vue','php','tp']
}
})
因为 wx:if
是一个控制属性,需要将它添加到一个标签上。如果要一次性判断多个组件标签,可以使用一个 <block/>
标签将多个组件包装起来,并在上边使用 wx:if
控制属性。
<block wx:if="{{true}}">
<view> view1 </view>
<view> view2 </view>
</block>
注意: <block/>
并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。
block标签包裹渲染列表,该标签不会渲染出来,只渲染其中的内容。如果不想用标签包裹渲染的列表,可以使用block,他会直接输入其中的内容。
<block wx:for="{{list}}" wx:key="index">
<text>{{item.id}}--{{item.name}}--{{item.age}}</text>
</block>
Page({
data: {
list: [
{id:'001',name:"zhang",age:18},
{id:'002',name:"peter",age:40},
{id:'003',name:"ouyangke",age:35},
{id:'004',name:"miemie",age:23}
]
}
})
动态添加删除数据操作
<view class="container">
<view class="page-body">
<view class="page-section page-section-spacing">
<view class="text-box" scroll-y="true" scroll-top="{{scrollTop}}">
<text>{{text}}</text>
</view>
<button disabled="{{!canAdd}}" bindtap="add">add line</button>
<button disabled="{{!canRemove}}" bindtap="remove">remove line</button>
</view>
</view>
</view>
const texts = [
'2011年1月,微信1.0发布',
'同年5月,微信2.0语音对讲发布',
'10月,微信3.0新增摇一摇功能',
'2012年3月,微信用户突破1亿',
'4月份,微信4.0朋友圈发布',
'同年7月,微信4.2发布公众平台',
'2013年8月,微信5.0发布微信支付',
'2014年9月,企业号发布',
'同月,发布微信卡包',
'2015年1月,微信第一条朋友圈广告',
'2016年1月,企业微信发布',
'2017年1月,小程序发布',
'......'
]
Page({
onShareAppMessage() {
return {
title: 'text',
path: 'page/component/pages/text/text'
}
},
data: {
text: '',
canAdd: true,
canRemove: false
},
extraLine: [],
add() {
this.extraLine.push(texts[this.extraLine.length % 12])
this.setData({
text: this.extraLine.join('\n'),
canAdd: this.extraLine.length < 12,
canRemove: this.extraLine.length > 0
})
setTimeout(() => {
this.setData({
scrollTop: 99999
})
}, 0)
},
remove() {
if (this.extraLine.length > 0) {
this.extraLine.pop()
this.setData({
text: this.extraLine.join('\n'),
canAdd: this.extraLine.length < 12,
canRemove: this.extraLine.length > 0,
})
}
setTimeout(() => {
this.setData({
scrollTop: 99999
})
}, 0)
}
})
首先,我们来简单了解下小程序的运行环境。小程序的运行环境分成渲染层和逻辑层,其中 WXML 模板和 WXSS 样式工作在渲染层,JS 脚本工作在逻辑层。
小程序的渲染层和逻辑层分别由2个线程管理:渲染层的界面使用了WebView 进行渲染;逻辑层采用JsCore线程运行JS脚本。一个小程序存在多个界面,所以渲染层存在多个WebView线程,这两个线程的通信会经由微信客户端(下文中也会采用Native来代指微信客户端)做中转,逻辑层发送网络请求也经由Native转发,小程序的通信模型下图所示。
注:UI 界面的程序需要和用户互动,例如用户可能会点击你界面上某个按钮,又或者长按某个区域,这类反馈应该通知给开发者的逻辑层,需要将对应的处理状态呈现给用户,称为事件
bindtap
在组件中绑定一个事件处理函数data-
自定义传值如bindtap
,当用户点击该组件的时候会在该页面对应的Page中找到相应的事件处理函数。
<view id="tapTest" data-hi="Weixin" bindtap="tapName">{{msg}}</view>
Page({
data: {
msg: "Click me! "
},
tapName: function(event) {
this.setData({
msg: '已被点击'
});
console.log(event);
}
})
input
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
value | string | 输入框的初始内容 | |
type | string | text | input 的类型 |
password | boolean | false | 是否是密码类型 |
placeholder | string | 输入框为空时占位符 | |
placeholder-style | string | 指定 placeholder 的样式 | |
placeholder-class | string | input-placeholder | 指定 placeholder 的样式类 |
disabled | boolean | false | 是否禁用 |
maxlength | number | 140 | 最大输入长度,设置为 -1 的时候不限制最大长度 |
cursor-spacing | number | 0 | 指定光标与键盘的距离,取 input 距离底部的距离和 cursor-spacing 指定的距离的最小值作为光标与键盘的距离 |
auto-focus | boolean | false | (即将废弃,请直接使用 focus )自动聚焦,拉起键盘 |
focus | boolean | false | 获取焦点 |
confirm-type | string | done | 设置键盘右下角按钮的文字,仅在 type=’text’时生效 |
confirm-hold | boolean | false | 点击键盘右下角按钮时是否保持键盘不收起 |
cursor | number | 指定 focus 时的光标位置 | |
selection-start | number | -1 | 光标起始位置,自动聚集时有效,需与 selection-end 搭配使用 |
selection-end | number | -1 | 光标结束位置,自动聚集时有效,需与 selection-start 搭配使用 |
adjust-position | boolean | true | 键盘弹起时,是否自动上推页面 |
hold-keyboard | boolean | false | focus 时,点击页面的时候不收起键盘 |
bindinput | eventhandle | 键盘输入时触发,event.detail = {value, cursor, keyCode},keyCode 为键值,2.1.0 起支持,处理函数可以直接 return 一个字符串,将替换输入框的内容。 | |
bindfocus | eventhandle | 输入框聚焦时触发,event.detail = { value, height },height 为键盘高度,在基础库 1.9.90 起支持 | |
bindblur | eventhandle | 输入框失去焦点时触发,event.detail = {value: value} | |
bindconfirm | eventhandle | 点击完成按钮时触发,event.detail = {value: value} | |
bindkeyboardheightchange | eventhandle | 键盘高度发生变化的时候触发此事件,event.detail = {height: height, duration: duration} |
<input bindinput="func" style="margin:20rpx;border:1px solid red;" value="输入时触发"></input>
<input bindfocus="func" style="margin:20rpx;border:1px solid red;" value="聚焦时触发"></input>
<input bindconfirm="func" style="margin:20rpx;border:1px solid red;" value="完成时触发"></input>
Page({
function func(event) {
console.log('tap Weixin', JSON.stringify(event))
}
});
编号 | 属性 | 类型 | 说明 |
---|---|---|---|
1 | id | String | 事件源组件的 id |
2 | dataset | Object | 事件源组件上由 data-开头的自定义属性组成的集合 |
编号 | 属性 | 类型 | 说明 |
---|---|---|---|
1 | id | String | 事件源组件的 id |
2 | dataset | Object | 事件源组件上由 data-开头的自定义属性组成的集合 |
<view bindtap="func" id="aaa">点击执行one事件,带id,带传值</view>
<view bindtap="func" id="ccc">点击执行two事件,id是ccc
<view id="eee">点击执行three事件,id是eee</view>
</view>
简单的说,currentTarget 是事件的绑定着,谁绑定的这个事件,由于事件冒泡或者捕获,触发者可能不是自身,是其他子元素或者父元素,target 是事件的实际触发者。
事件代理机制就是这样实现的,我们将事件只绑定给父元素一个人,通过子元素的事件冒泡机制,依然会触发父元素的事件函数,我们通过判断target 的值,知道是谁触发了该事件,从而执行相应的动作代码。
WXML 的冒泡事件列表
编号 | 类型 | 触发条件 |
---|---|---|
1 | touchstart | 手指触摸动作开始 |
2 | touchmove | 手指触摸后移动 |
3 | touchcancel | 手指触摸动作被打断,如来电提醒,弹窗 |
4 | touchend | 手指触摸动作结束 |
5 | tap | 手指触摸后马上离开 |
6 | longpress | 手指触摸后,超过 350ms 再离开,如果指定了事件回调函数并触发了这个事件,tap 事件将不被触发 |
7 | longtap | 手指触摸后,超过 350ms 再离开(推荐使用 longpress 事件代替) |
8 | transitionend | 会在 WXSS transition 或 wx.createAnimation 动画结束后触发 |
9 | animationstart | 会在一个 WXSS animation 动画开始时触发 |
10 | animationiteration | 会在一个 WXSS animation 一次迭代结束时触发 |
11 | animationend | 会在一个 WXSS animation 动画完成时触发 |
12 | touchforcechange | 在支持 3D Touch 的 iPhone 设备,重按时会触发 |
注:除上表之外的其他组件自定义事件如无特殊声明都是非冒泡事件,如 form 的submit
事件,input 的input
事件,scroll-view 的scroll
事件,(详见各个组件)
事件绑定的写法类似于组件的属性,如:
<view bindtap="handleTap">
Click here!
</view>
如果用户点击这个 view ,则页面的 handleTap
会被调用。
事件绑定函数可以是一个数据绑定,如:
<view bindtap="{{ handlerName }}">
Click here!
</view>
此时,页面的 this.data.handlerName
必须是一个字符串,指定事件处理函数名;如果它是个空字符串,则这个绑定会失效(可以利用这个特性来暂时禁用一些事件)。
除 bind
外,也可以用 catch
来绑定事件。与 bind
不同, catch
会阻止事件向上冒泡。
例如在下边这个例子中,点击 inner view 会先后调用handleTap3
和handleTap2
(因为tap事件会冒泡到 middle view,而 middle view 阻止了 tap 事件冒泡,不再向父节点传递),点击 middle view 会触发handleTap2
,点击 outer view 会触发handleTap1
。
<view id="outer" bindtap="handleTap1">
outer view
<view id="middle" catchtap="handleTap2">
middle view
<view id="inner" bindtap="handleTap3">
inner view
</view>
</view>
</view>
自基础库版本 2.8.2 起,除 bind
和 catch
外,还可以使用 mut-bind
来绑定事件。一个 mut-bind
触发后,如果事件冒泡到其他节点上,其他节点上的 mut-bind
绑定函数不会被触发,但 bind
绑定函数和 catch
绑定函数依旧会被触发。
换而言之,所有 mut-bind
是“互斥”的,只会有其中一个绑定函数被触发。同时,它完全不影响 bind
和 catch
的绑定效果。
例如在下边这个例子中,点击 inner view 会先后调用 handleTap3
和 handleTap2
,点击 middle view 会调用 handleTap2
和 handleTap1
。
<view id="outer" mut-bind:tap="handleTap1">
outer view
<view id="middle" bindtap="handleTap2">
middle view
<view id="inner" mut-bind:tap="handleTap3">
inner view
</view>
</view>
</view>
自基础库版本 1.5.0 起,触摸类事件支持捕获阶段。捕获阶段位于冒泡阶段之前,且在捕获阶段中,事件到达节点的顺序与冒泡阶段恰好相反。需要在捕获阶段监听事件时,可以采用capture-bind
、capture-catch
关键字,后者将中断捕获阶段和取消冒泡阶段。
在下面的代码中,点击 inner view 会先后调用handleTap2
、handleTap4
、handleTap3
、handleTap1
。
<view id="outer" bind:touchstart="handleTap1" capture-bind:touchstart="handleTap2">
outer view
<view id="inner" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4">
inner view
</view>
</view>
如果将上面代码中的第一个capture-bind
改为capture-catch
,将只触发handleTap2
。
<view id="outer" bind:touchstart="handleTap1" capture-catch:touchstart="handleTap2">
outer view
<view id="inner" bind:touchstart="handleTap3" capture-bind:touchstart="handleTap4">
inner view
</view>
</view>
bind绑定的事件会依次冒泡到最外层,点击three会依次执行到one
Page({
one() {
console.log(e);
},
two(e) {
console.log(e);
},
three(e) {
console.log(e);
},
});
<view id="one" bindtap="one">
第一级
<view id="two" bindtap="two">
第二级
<view id="three" bindtap="three">
第三级
</view>
</view>
</view>
<view id="one" bindtap="one">
第一级
<view id="two" catchtap="two">
第二级
<view id="three" bindtap="three">
第三级
</view>
</view>
</view>
如无特殊说明,当组件触发事件时,逻辑层绑定该事件的处理函数会收到一个事件对象。
BaseEvent 基础事件对象属性列表:
属性 | 类型 | 说明 | 基础库版本 |
---|---|---|---|
type | String | 事件类型 | |
timeStamp | Integer | 事件生成时的时间戳 | |
target | Object | 触发事件的组件的一些属性值集合 | |
currentTarget | Object | 当前组件的一些属性值集合 | |
mark | Object | 事件标记数据 | 2.7.1 |
CustomEvent 自定义事件对象属性列表(继承 BaseEvent):
属性 | 类型 | 说明 |
---|---|---|
detail | Object | 额外的信息 |
TouchEvent 触摸事件对象属性列表(继承 BaseEvent):
属性 | 类型 | 说明 |
---|---|---|
touches | Array | 触摸事件,当前停留在屏幕中的触摸点信息的数组 |
changedTouches | Array | 触摸事件,当前变化的触摸点信息的数组 |
特殊事件: canvas 中的触摸事件不可冒泡,所以没有 currentTarget
API
API
按照功能主要分为几大类:网络、媒体、文件、数据缓存、位置、设备、界面、界面节点信息还有一些特殊的开放接口为了让开发者可以很方便的调起微信提供的能力,例如获取用户信息、微信支付等等,小程序提供了很多 API 给开发者去使用。
要获取用户的地理位置时,只需要:
wx.getLocation({
type: 'wgs84',
success: (res) => {
var latitude = res.latitude // 纬度
var longitude = res.longitude // 经度
}
})
调用微信扫一扫能力,只需要:
wx.scanCode({
success: (res) => {
console.log(res)
}
})
需要注意的是:多数 API 的回调都是异步,你需要处理好代码逻辑的异步问题。
通常,在小程序 API 有以下几种类型:
API
on
开头的 API 用来监听某个事件是否触发,如:wx.onSocketOpen,wx.onCompassChange 等API
接受一个回调函数作为参数,当事件触发时会调用这个回调函数,并将相关数据以参数形式传入wx.onAppShow 监听小程序切前台事件
wx.onAppHide 监听小程序切后台事件
Page({
onLoad: function (options) {
// 监听小程序切前台事件
wx.onAppShow(function () {
console.log("切换前台");
});
//监听小程序切后台事件
wx.onAppHide(function () {
console.log("切换后台");
});
},
});
API
我们约定,以 Sync
结尾的 API 都是同步 API, 如 wx.setStorageSync,wx.getSystemInfoSync 等。此外,也有一些其他的同步 API,如 wx.createWorker,wx.getBackgroundAudioManager 等,详情参见 API 文档中的说明。
try {
wx.setStorageSync('key', 'value')
} catch (e) {
console.error(e)
}
wx.getSystemInfoSync 获取系统信息
Page({
onLoad: function (options) {
console.log(wx.getSystemInfoSync());
var sync = wx.getSystemInfoSync();
console.log(sync.model);
},
});
API
大多数 API 都是异步 API,如 wx.request,wx.login 等。这类 API 接口通常都接受一个 Object
类型的参数,这个参数都支持按需指定以下字段来接收接口调用结果:
编号 | 参数名 | 类型 | 必填 | 说明 |
---|---|---|---|---|
1 | success | function | 否 | 接口调用成功的回调函数 |
2 | fail | function | 否 | 接口调用失败的回调函数 |
3 | complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
4 | 其他 | Any | - | 接口定义的其他参数 |
编号 | 属性 | 类型 | 说明 |
---|---|---|---|
1 | errMsg | string | 错误信息,如果调用成功返回 ${apiName}:ok |
2 | errCode | number | 错误码,仅部分 API 支持,具体含义请参考对应 API 文档,成功时为 0。 |
3 | 其他 | Any | 接口返回的其他数据 |
异步 API 的执行结果需要通过 Object
类型的参数中传入的对应回调函数获取。部分异步 API 也会有返回值,可以用来实现更丰富的功能,如 wx.request,wx.connectSocket 等。
wx.login({
success(res) {
console.log(res.code)
}
})
异步 API 支持 callback & promise 两种调用方式。当接口参数 Object 对象中不包含 success/fail/complete 时将默认返回 promise,否则仍按回调方式执行,无返回值。
// callback 形式调用
wx.chooseImage({
success(res) {
console.log('res:', res)
}
})
// promise 形式调用
wx.chooseImage().then(res => console.log('res: ', res))
云开发 API
wx.getSystemInfo 获取系统信息
Page({
onLoad: function (options) {
wx.getSystemInfo({
success(res) {
console.log(res);
console.log(res.model);
console.log("成功执行");
},
fail(res) {
console.log("失败执行");
},
complete(res) {
console.log("不管成功失败都执行");
},
});
},
});
wx.showToast 显示消息提示框
属性 | 类型 | 必填 | 描述 |
---|---|---|---|
title | string | 是 | 提示的内容 |
icon | string | 否 | 图标 |
image | string | 否 | 自定义图标的本地路径,image 的优先级高于 icon |
duration | number | 否 | 提示的延迟时间 |
mask | boolean | 否 | 是否显示透明蒙层,防止触摸穿透 |
success | function | 否 | 接口调用成功的回调函数 |
fail | function | 否 | 接口调用失败的回调函数 |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
icon 合法值:
属性 | 描述 |
---|---|
success | 显示成功图标,此时 title 文本最多显示 7 个汉字长度 |
loading | 显示加载图标,此时 title 文本最多显示 7 个汉字长度 |
none | 不显示图标,此时 title 文本最多可显示两行 |
Page({
onLoad: function (options) {
wx.showToast({
title: "成功",
icon: "success",
duration: 1000,
mask: true,
success() {
console.log("成功");
},
fail() {
console.log("失败");
},
complete() {
console.log("成功或失败");
},
});
},
});
API
名称 | 功能说明 |
---|---|
wx.getSystemInfoSync | wx.getSystemInfo 的同步版本 |
wx.getSystemInfoAsync | 异步获取系统信息 |
wx.getSystemInfo | 获取系统信息 |
Page({
onLoad(){
// 同步调用系统信息API
wx.getSystemInfo({
success (res) {
console.log(res.model)
console.log(res.pixelRatio)
console.log(res.windowWidth)
console.log(res.windowHeight)
console.log(res.language)
console.log(res.version)
console.log(res.platform)
}
});
// 异步调用系统信息API
wx.getSystemInfo({
success (res) {
console.log(res.model)
console.log(res.pixelRatio)
console.log(res.windowWidth)
console.log(res.windowHeight)
console.log(res.language)
console.log(res.version)
console.log(res.platform)
}
});
}
});
返回系统信息如下:
属性 | 说明 |
---|---|
brand | 设备品牌 |
model | 设备型号。新机型刚推出一段时间会显示unknown,微信会尽快进行适配。 |
pixelRatio | 设备像素比 |
screenWidth | 屏幕宽度,单位px |
screenHeight | 屏幕高度,单位px |
windowWidth | 可使用窗口宽度,单位px |
windowHeight | 可使用窗口高度,单位px |
statusBarHeight | 状态栏的高度,单位px |
language | 微信设置的语言 |
version | 微信版本号 |
system | 操作系统及版本 |
platform | 客户端平台 |
fontSizeSetting | 用户字体大小(单位px)。以微信客户端「我-设置-通用-字体大小」中的设置为准 |
SDKVersion | 客户端基础库版本 |
benchmarkLevel | 设备性能等级(仅 Android)。取值为:-2 或 0(该设备无法运行小游戏),-1(性能未知),>=1(设备性能值,该值越高,设备性能越好,目前最高不到50) |
albumAuthorized | 允许微信使用相册的开关(仅 iOS 有效) |
cameraAuthorized | 允许微信使用摄像头的开关 |
locationAuthorized | 允许微信使用定位的开关 |
microphoneAuthorized | 允许微信使用麦克风的开关 |
notificationAuthorized | 允许微信通知的开关 |
notificationAlertAuthorized | 允许微信通知带有提醒的开关(仅 iOS 有效) |
notificationBadgeAuthorized | 允许微信通知带有标记的开关(仅 iOS 有效) |
notificationSoundAuthorized | 允许微信通知带有声音的开关(仅 iOS 有效) |
bluetoothEnabled | 蓝牙的系统开关 |
locationEnabled | 地理位置的系统开关 |
wifiEnabled | Wi-Fi 的系统开关 |
safeArea | 在竖屏正方向下的安全区域 |
locationReducedAccuracy | true 表示模糊定位,false 表示精确定位,仅 iOS 支持 |
theme | 系统当前主题,取值为light 或dark ,全局配置"darkmode":true 时才能获取,否则为 undefined (不支持小游戏) |
host | 当前小程序运行的宿主环境 |
enableDebug | 是否已打开调试。可通过右上角菜单或 wx.setEnableDebug 打开调试。 |
deviceOrientation | 设备方向 |
API
名称 | 功能说明 |
---|---|
wx.showActionSheet | 显示操作菜单 |
wx.showModal | 显示模态对话框 |
wx.showLoading | 显示加载提示框 |
wx.hideLoading | 隐藏加载提示框 |
wx.showToast | 显示消息提示框 |
wx.hideToast | 隐藏消息提示框 |
显示操作菜单
属性 | 类型 | 说明 |
---|---|---|
alertText | string | 警示文案 |
itemList | Array.<string> | 按钮的文字数组,数组长度最大为 6 |
itemColor | string | 按钮的文字颜色 |
success | function | 接口调用成功的回调函数 |
fail | function | 接口调用失败的回调函数 |
complete | function | 接口调用结束的回调函数(调用成功、失败都会执行) |
Page({
show(){
wx.showActionSheet({
itemList: ['安徽', '安庆', '安阳'],
itemColor: '#aa33aa',
success (res) {
// 用户点击的按钮序号,从上到下的顺序,从0开始
console.log(res.tapIndex)
},
fail (res) {
console.log(res.errMsg)
}
})
}
});
<button bindtap="show">打开底部菜单</button>
显示模态对话框
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
title | string | 否 | 提示的标题 | |
content | string | 否 | 提示的内容 | |
showCancel | boolean | true | 否 | 是否显示取消按钮 |
cancelText | string | ‘取消’ | 否 | 取消按钮的文字,最多 4 个字符 |
cancelColor | string | #000000 | 否 | 取消按钮的文字颜色,必须是 16 进制格式的颜色字符串 |
confirmText | string | ‘确定’ | 否 | 确认按钮的文字,最多 4 个字符 |
confirmColor | string | #576B95 | 否 | 确认按钮的文字颜色,必须是 16 进制格式的颜色字符串 |
success | function | 否 | 接口调用成功的回调函数 | |
fail | function | 否 | 接口调用失败的回调函数 | |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
object.success 回调函数
属性 | 类型 | 说明 |
---|---|---|
content | string | editable 为 true 时,用户输入的文本 |
confirm | boolean | 为 true 时,表示用户点击了确定按钮 |
cancel | boolean | 为 true 时,表示用户点击了取消(用于 Android 系统区分点击蒙层关闭还是点击取消按钮关闭) |
Page({
onLoad(){
wx.showModal({
title: '提示',
content: '这是一个模态弹窗',
success (res) {
if (res.confirm) {
console.log('用户点击确定')
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
}
});
显示 loading 提示框
属性 | 类型 | 必填 | 说明 |
---|---|---|---|
title | string | 是 | 提示的内容 |
mask | boolean | 否 | 是否显示透明蒙层,防止触摸穿透 |
success | function | 否 | 接口调用成功的回调函数 |
fail | function | 否 | 接口调用失败的回调函数 |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
wx.showLoading({
title: '加载中',
mask: true,
})
// 需主动调用 wx.hideLoading 才能关闭提示框
setTimeout(function () {
wx.hideLoading()
}, 2000)
显示消息提示框
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
title | string | 是 | 提示的内容 | |
icon | string | ‘success’ | 否 | 图标 |
image | string | 否 | 自定义图标的本地路径,image 的优先级高于 icon | |
duration | number | 1500 | 否 | 提示的延迟时间 |
mask | boolean | false | 否 | 是否显示透明蒙层,防止触摸穿透 |
success | function | 否 | 接口调用成功的回调函数 | |
fail | function | 否 | 接口调用失败的回调函数 | |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
object.icon 的合法值
值 | 说明 |
---|---|
success | 显示成功图标,此时 title 文本最多显示 7 个汉字长度 |
error | 显示失败图标,此时 title 文本最多显示 7 个汉字长度 |
loading | 显示加载图标,此时 title 文本最多显示 7 个汉字长度 |
none | 不显示图标,此时 title 文本最多可显示两行,1.9.0及以上版本支持 |
wx.showToast({
title: '成功',
icon: 'success',
mask: true,
duration: 2000,
success(e){
console.log(e);
}
})
名称 | 功能说明 |
---|---|
wx.showNavigationBarLoading | 在当前页面显示导航条加载动画 |
wx.setNavigationBarTitle | 动态设置当前页面的标题 |
wx.setNavigationBarColor | 设置页面导航条颜色 |
wx.hideNavigationBarLoading | 在当前页面隐藏导航条加载动画 |
wx.hideHomeButton | 隐藏返回首页按钮 |
设置页面导航条颜色
属性 | 类型 | 必填 | 说明 |
---|---|---|---|
frontColor | string | 是 | 前景颜色值,包括按钮、标题、状态栏的颜色,仅支持 #ffffff 和 #000000 |
backgroundColor | string | 是 | 背景颜色值,有效值为十六进制颜色 |
animation | Object | 否 | 动画效果 |
success | function | 否 | 接口调用成功的回调函数 |
fail | function | 否 | 接口调用失败的回调函数 |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
object.animation 的结构
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
duration | number | 0 | 否 | 动画变化时间,单位 ms |
timingFunc | string | ‘linear’ | 否 | 动画变化方式 |
object.animation.timingFunc 的合法值
值 | 说明 |
---|---|
‘linear’ | 动画从头到尾的速度是相同的 |
‘easeIn’ | 动画以低速开始 |
‘easeOut’ | 动画以低速结束 |
‘easeInOut’ | 动画以低速开始和结束 |
Page({
show(){
wx.setNavigationBarColor({
backgroundColor: '#ff0000',
frontColor: '#ffffff',
animation: {
duration: 400,
timingFunc: "easeIn"
},
success(){
wx.showToast({
title: '导航条颜色修改成功',
icon: 'success',
mask: true,
duration: 2000,
success(e){
console.log(e);
}
});
}
});
}
});
<button bindtap="show">改变导航条颜色</button>
在当前页面显示导航条加载动画
属性 | 类型 | 必填 | 说明 |
---|---|---|---|
success | function | 否 | 接口调用成功的回调函数 |
fail | function | 否 | 接口调用失败的回调函数 |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行 |
在当前页面隐藏导航条加载动画
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
success | function | 否 | 接口调用成功的回调函数 | |
fail | function | 否 | 接口调用失败的回调函数 | |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行 |
Page({
show(){
// 改变导航条颜色
wx.setNavigationBarColor({
backgroundColor: '#ff0000',
frontColor: '#ffffff',
animation: {
duration: 400,
timingFunc: "linear"
}
});
// 显示导航条加载动画
wx.showNavigationBarLoading({
success(e){
console.log(e);
}
});
// 两秒后隐藏导航条加载动画
setTimeout(function () {
wx.hideNavigationBarLoading()
}, 2000)
}
});
动态设置当前页面的标题
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
title | string | 是 | 页面标题 | |
success | function | 否 | 接口调用成功的回调函数 | |
fail | function | 否 | 接口调用失败的回调函数 | |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
wx.setNavigationBarTitle({
title: '当前注册页面'
});
隐藏返回首页按钮
微信7.0.7版本起,当用户打开的小程序最底层页面是非首页时,默认展示“返回首页”按钮,开发者可在页面 onShow 中调用 hideHomeButton 进行隐藏
名称 | 功能说明 |
---|---|
wx.showTabBarRedDot | 显示 tabBar 某一项的右上角的红点 |
wx.showTabBar | 显示 tabBar |
wx.setTabBarStyle | 动态设置 tabBar 的整体样式 |
wx.setTabBarItem | 动态设置 tabBar 某一项的内容,2.7.0 起图片支持临时文件和网络文件 |
wx.setTabBarBadge | 为 tabBar 某一项的右上角添加文本 |
wx.removeTabBarBadge | 移除 tabBar 某一项右上角的文本 |
wx.hideTabBarRedDot | 隐藏 tabBar 某一项的右上角的红点 |
wx.hideTabBar | 隐藏 tabBar |
<!-- 显示 tabBar 某一项的右上角的红点 -->
<button bindtap="a">添加红点</button>
<!-- 隐藏 tabBar 某一项的右上角的红点 -->
<button bindtap="b">隐藏红点</button>
<!-- 隐藏底部 tabBar -->
<button bindtap="c">隐藏 tabBar</button>
<!-- 显示底部 tabBar -->
<button bindtap="d">显示 tabBar</button>
<!-- 为 tabBar 某一项的右上角添加文本 -->
<button bindtap="e">添加文本</button>
<!-- 移除 tabBar 某一项右上角的文本 -->
<button bindtap="f">移除文本</button>
<!-- 动态设置 tabBar 某一项的内容 -->
<button bindtap="g">设置某一项样式</button>
<!-- 动态设置 tabBar 的整体样式 -->
<button bindtap="h">设置整体样式</button>
Page({
a(){
wx.showTabBarRedDot({
index: 0,
});
},
b(){
wx.hideTabBarRedDot({
index: 0,
});
},
c(){
wx.hideTabBar({
animation: true,
success(e){
console.log(e);
}
})
},
d(){
wx.showTabBar({
animation: true,
success(e){
console.log(e);
}
})
},
e(){
wx.setTabBarBadge({
index: 0,
text: '新',
})
},
f(){
wx.removeTabBarBadge({
index: 0,
})
},
g(){
wx.setTabBarItem({
index: 0,
text:'新标签',
iconPath: 'http://ku.90sjimg.com/element_origin_min_pic/01/30/48/25573b15ce3e7f0.jpg',
success(){
wx.showToast({
title: '设置成功',
duration: 2000,
icon: "success"
})
}
})
},
h(){
wx.setTabBarStyle({
color: '#90CAF9',
selectedColor: '#8BC34A',
backgroundColor: '#FF9800',
borderStyle: 'black',
success(){
wx.showToast({
title: '设置成功',
duration: 2000,
icon: "success"
})
}
})
}
});
名称 | 功能说明 |
---|---|
wx.pageScrollTo | 将页面滚动到目标位置,支持选择器和滚动距离两种方式定位 |
属性 | 类型 | 说明 |
---|---|---|
scrollTop | number | 滚动到页面的目标位置,单位 px |
duration | number | 滚动动画的时长,单位 ms |
selector | string | 选择器 |
success | function | 接口调用成功的回调函数 |
fail | function | 接口调用失败的回调函数 |
complete | function | 接口调用结束的回调函数(调用成功、失败都会执行) |
GoTop(){
wx.pageScrollTo({
scrollTop: 0,
duration: 300,
success(){
wx.showToast({
title: '已返回顶部',
duration: 1000,
icon: "success"
})
}
})
}
<view style="height:500px;background-color: pink">1</view>
<view style="height:500px;background-color: green">2</view>
<view style="height:500px;background-color: yellow">3</view>
<button bindtap="GoTop">滚动到顶部</button>
名称 | 功能说明 |
---|---|
wx.stopPullDownRefresh | 停止当前页面下拉刷新 |
wx.startPullDownRefresh | 开始下拉刷新 |
startRefresh(){
// 开始下拉刷新。调用后触发下拉刷新动画,效果与用户手动下拉刷新一致。
wx.startPullDownRefresh({
success(){
wx.showLoading({
title: '正在刷新……',
mask: false,
success: (res) => {},
fail: (res) => {},
complete: (res) => {},
});
}
})
},
stopRefresh(){
// 停止当前页面下拉刷新
wx.stopPullDownRefresh({
success(){
wx.hideLoading({
success: (res) => {},
fail: (res) => {},
complete: (res) => {},
});
}
})
},
<button bindtap="startRefresh">开始刷新</button>
<button bindtap="stopRefresh">停止刷新</button>
API
每个微信小程序需要事先设置通讯域名,小程序只可以跟指定的域名进行网络通信。包括普通 HTTPS 请求(wx.request)、上传文件(wx.uploadFile)、下载文件(wx.downloadFile) 和 WebSocket 通信(wx.connectSocket)
名称 | 功能说明 |
---|---|
wx.request | 发起 HTTPS 网络请求 |
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
url | string | 开发者服务器接口地址 | |
data | string/object/ArrayBuffer | 请求的参数 | |
header | Object | 设置请求的 header,header 中不能设置 Referer。 content-type 默认为 application/json |
|
timeout | number | 超时时间,单位为毫秒 | |
method | string | GET | HTTP 请求方法 |
dataType | string | json | 返回的数据格式 |
responseType | string | text | 响应的数据类型 |
enableHttp2 | boolean | false | 开启 http2 |
enableQuic | boolean | false | 开启 quic |
enableCache | boolean | false | 开启 cache |
success | function | 接口调用成功的回调函数 | |
fail | function | 接口调用失败的回调函数 | |
complete | function | 接口调用结束的回调函数(调用成功、失败都会执行) |
object.method 的合法值
值 | 说明 |
---|---|
OPTIONS | HTTP 请求 OPTIONS |
GET | HTTP 请求 GET |
HEAD | HTTP 请求 HEAD |
POST | HTTP 请求 POST |
PUT | HTTP 请求 PUT |
DELETE | HTTP 请求 DELETE |
TRACE | HTTP 请求 TRACE |
CONNECT | HTTP 请求 CONNECT |
object.dataType 的合法值
值 | 说明 |
---|---|
json | 返回的数据为 JSON,返回后会对返回的数据进行一次 JSON.parse |
其他 | 不对返回的内容进行 JSON.parse |
object.responseType 的合法值
值 | 说明 |
---|---|
text | 响应的数据为文本 |
arraybuffer | 响应的数据为 ArrayBuffer |
wx.request({
url: 'https://baidu.com',
data: {
code: '百度一下'
},
header: {
'content-type': 'application/json'
},
success (res) {
console.log(res.data)
}
});
获取图片信息
wx.getImageInfo(Object object)
https://developers.weixin.qq.com/miniprogram/dev/api/media/image/wx.getImageInfo.html
属性 | 类型 | 必填 | 说明 |
---|---|---|---|
src | string | 是 | 图片的路径,支持网络路径、本地路径、代码包路径 |
success | function | 否 | 接口调用成功的回调函数 |
fail | function | 否 | 接口调用失败的回调函数 |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
从本地相册选择图片或使用相机拍照
wx.chooseImage(Object object)
https://developers.weixin.qq.com/miniprogram/dev/api/media/image/wx.chooseImage.html
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
count | number | 9 | 最多可以选择的图片张数 |
sizeType | Array.<string> | [‘original’, ‘compressed’] | 所选的图片的尺寸 |
sourceType | Array.<string> | [‘album’, ‘camera’] | 选择图片的来源 |
success | function | 接口调用成功的回调函数 | |
fail | function | 接口调用失败的回调函数 | |
complete | function | 接口调用结束的回调函数(调用成功、失败都会执行) |
属性 | 类型 | 说明 |
---|---|---|
width | number | 图片原始宽度,单位px。不考虑旋转。 |
height | number | 图片原始高度,单位px。不考虑旋转。 |
path | string | 图片的本地路径 |
orientation | string | 拍照时设备方向 |
type | string | 图片格式 |
Page({
/**
* 页面的初始数据
*/
data: {
future:[],
city: null
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
wx.getImageInfo({
src: 'https://img.php.cn/upload/article/000/000/001/6034a327aef30703.png',
success (res) {
console.log(res.width)
console.log(res.height)
}
})
},
getChoose(){
wx.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success (res) {
// tempFilePath可以作为img标签的src属性显示图片
const tempFilePaths = res.tempFilePaths
wx.getImageInfo({
src: res.tempFilePaths[0],
success (res) {
console.log(res.width)
console.log(res.height)
}
})
}
})
}
})
<button bindtap="getChoose">从相册获取图片</button>
在新页面中全屏预览图片
wx.previewImage(Object object)
预览的过程中用户可以进行保存图片、发送给朋友等操作
属性 | 类型 | 必填 | 说明 |
---|---|---|---|
urls | Array.<string> | 是 | 需要预览的图片链接列表。2.2.3 起支持云文件ID。 |
showmenu | boolean | 否 | 是否显示长按菜单 |
current | string | 否 | 当前显示图片的链接 |
success | function | 否 | 接口调用成功的回调函数 |
fail | function | 否 | 接口调用失败的回调函数 |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
previewImage(){
wx.previewImage({
// 当前显示图片的http链接
current: 'https://img.php.cn/upload/article/000/000/001/5fabba9a8557c153.jpg',
// 需要预览的图片http链接列表
urls: [
'https://img.php.cn/upload/article/000/000/003/6093abebf1766794.jpg',
'https://img.php.cn/upload/article/000/000/001/5fabba9a8557c153.jpg',
'https://img.php.cn/upload/article/000/000/001/6034a327aef30703.png',
'https://img.php.cn/upload/course/000/126/153/5aa23f0ded921649.jpg'
]
})
}
<button bindtap="previewImage">全屏预览图片</button>
压缩图片接口
wx.compressImage(Object object)
属性 | 类型 | 必填 | 说明 |
---|---|---|---|
src | string | 是 | 图片路径,图片的路径,支持本地路径、代码包路径 |
quality | number | 否 | 压缩质量,范围0~100,数值越小,质量越低,压缩率越高(仅对jpg有效)。 |
object.success 回调函数
属性 | 类型 | 说明 |
---|---|---|
tempFilePath | string | 压缩后图片的临时文件路径 (本地路径) |
Page({
data: {
img : '../../img/1.png'
},
compressImage(){
var that = this;
wx.compressImage({
src: '../../img/1.png', // 图片路径
quality: 20, // 压缩质量
success(res){
// 压缩后图片的临时文件路径 (本地路径)
console.log(res);
that.setData({
img: res.tempFilePath
})
}
})
}
})
<button bindtap="compressImage">压缩图片</button>
<image src="{{img}}"></image>
获取用户账号信息
名称 | 功能说明 |
---|---|
wx.getUserProfile | 获取用户信息 |
wx.getUserInfo | 获取用户信息 |
UserInfo | 用户信息 |
wx.getAccountInfoSync | 获取当前帐号信息 |
string nickName
用户昵称
string avatarUrl
用户头像图片的 URL。URL 最后一个数值代表正方形头像大小(有 0、46、64、96、132 数值可选,0 代表 640x640 的正方形头像,46 表示 46x46 的正方形头像,剩余数值以此类推。默认132),用户没有头像时该项为空。若用户更换头像,原有头像 URL 将失效。
number gender
用户性别
gender 的合法值
值 | 说明 | 最低版本 |
---|---|---|
0 | 未知 | |
1 | 男性 | |
2 | 女性 |
string country
用户所在国家
string province
用户所在省份
string city
用户所在城市
string language
显示 country,province,city 所用的语言
language 的合法值
值 | 说明 |
---|---|
en | 英文 |
zh_CN | 简体中文 |
获取用户信息。页面产生点击事件(例如
button
上bindtap
的回调中)后才可调用,每次请求都会弹出授权窗口,用户同意后返回userInfo
。该接口用于替换wx.getUserInfo
,详见 用户信息接口调整说明。
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
lang | string | en | 否 | 显示用户信息的语言 |
desc | string | 是 | 声明获取用户个人信息后的用途,不超过30个字符 |
Page({
data: {
userInfo: {},
hasUserInfo: false
},
onLoad() {
}
},
getUserProfile(e) {
// 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认,开发者妥善保管用户快速填写的头像昵称,避免重复弹窗
wx.getUserProfile({
desc: '展示用户信息', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
success: (res) => {
console.log(res)
this.setData({
userInfo: res.userInfo,
hasUserInfo: true
})
}
})
},
getUserInfo(e) {
// 不推荐使用getUserInfo获取用户信息,预计自2021年4月13日起,getUserInfo将不再弹出弹窗,并直接返回匿名的用户个人信息
console.log(e)
this.setData({
userInfo: e.detail.userInfo,
hasUserInfo: true
});
// 必须是在用户已经授权的情况下调用,否则获取的是匿名信息
wx.getUserInfo({
success: function(res) {
var userInfo = res.userInfo
console.log(userInfo);
var nickName = userInfo.nickName
var avatarUrl = userInfo.avatarUrl
var gender = userInfo.gender //性别 0:未知、1:男、2:女
var province = userInfo.province
var city = userInfo.city
var country = userInfo.country
}
});
}
})
<view class="container">
<view class="userinfo">
<block wx:if="{{!hasUserInfo}}">
<button bindtap="getUserProfile"> 获取头像昵称 </button>
<button open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button>
</block>
<block wx:else>
<image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
<text class="userinfo-nickname">{{userInfo.nickName}}</text>
</block>
</view>
</view>
.userinfo {
display: flex;
flex-direction: column;
align-items: center;
color: #aaa;
}
.userinfo-avatar {
overflow: hidden;
width: 128rpx;
height: 128rpx;
margin: 20rpx;
border-radius: 50%;
}
提前向用户发起授权请求
wx.authorize(Object object)
提前向用户发起授权请求。调用后会立刻弹窗询问用户是否同意授权小程序使用某项功能或获取用户的某些数据,但不会实际调用对应接口。如果用户之前已经同意授权,则不会出现弹窗,直接返回成功.更多用法详见 用户授权。
小程序插件可以使用 wx.authorizeForMiniProgram
属性 | 类型 | 必填 | 说明 |
---|---|---|---|
scope | string | 是 | 需要获取权限的 scope,详见 scope 授权列表 |
success | function | 否 | 接口调用成功的回调函数 |
fail | function | 否 | 接口调用失败的回调函数 |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
Page({
data: {
src: ''
},
a(){
// 可以通过 wx.getSetting 先查询一下用户是否授权了 "scope.record" 这个 scope
wx.getSetting({
success(res) {
if (!res.authSetting['scope.record']) {
wx.authorize({
scope: 'scope.record',
success (e) {
// 用户已经同意小程序使用录音功能,后续调用 wx.startRecord 接口不会弹窗询问
console.log(e);
}
})
}
}
})
},
b(){
wx.authorize({
scope: 'scope.userLocation',
success:(e)=>{
// 授权地理位置信息
console.log(e);
}
})
},
c(){
wx.authorize({
scope: 'scope.address',
success:(e)=>{
// 授权通讯地址
console.log(e);
wx.chooseAddress({
success: (result) => {
console.log(result);
},
});
}
})
},
d(){
wx.authorize({
scope: 'scope.werun',
success:(e)=>{
// 授权微信运动步数
console.log(e);
wx.getWeRunData({
success: (result) => {
console.log(result);
},
});
}
})
},
e(){
wx.authorize({
scope: 'scope.writePhotosAlbum',
success:(e)=>{
// 授权保存到相册
console.log(e);
}
})
},
f(){
wx.authorize({
scope: 'scope.camera',
success:(e)=>{
// 授权摄像头
console.log(e);
}
})
},
// 开始录音
startRecord(){
wx.startRecord({
success (res) {
const tempFilePath = res.tempFilePath
console.log(tempFilePath);
}
});
},
// 结束录音
stopRecord(){
wx.stopRecord() // 结束录音
},
// 拍照
takePhoto() {
const ctx = wx.createCameraContext()
ctx.takePhoto({
quality: 'high',
success: (res) => {
this.setData({
src: res.tempImagePath
})
}
})
},
})
<button bindtap="a">授权录音</button>
<button bindtap="startRecord">开始录音</button>
<button bindtap="stopRecord">结束录音</button>
<button bindtap="b">授权地理位置</button>
<button bindtap="c">授权通讯地址</button>
<button bindtap="d">授权微信步数</button>
<button bindtap="e">授权保存相册</button>
<button bindtap="f">授权摄像头</button>
<camera device-position="back" flash="off" binderror="error" style="width: 100%; height: 300px;"></camera>
<button type="primary" bindtap="takePhoto">拍照</button>
<view>拍照预览</view>
<image mode="widthFix" src="{{src}}"></image>
API
名称 | 功能说明 |
---|---|
wx.switchTab | 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面 |
wx.reLaunch | 关闭所有页面,打开到应用内的某个页面 |
wx.redirectTo | 关闭当前页面,跳转到应用内的某个页面 |
wx.navigateTo | 保留当前页面,跳转到应用内的某个页面 |
wx.navigateBack | 关闭当前页面,返回上一页面或多级页面 |
// pages/login/reg.js
Page({
a(){
// 关闭当前页面,返回上一页面或多级页面
// 可通过 getCurrentPages 获取当前的页面栈,决定需要返回几层
const page = getCurrentPages();
wx.navigateBack({
delta: 1
});
},
b(){
// 保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面。
// 使用 wx.navigateBack 可以返回到原页面。小程序中页面栈最多十层
wx.navigateTo({
url: '.../logs/logs',
});
},
c(){
// 关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面
wx.redirectTo({
url: '.../logs/logs'
});
},
d(){
// 关闭所有页面,打开到应用内的某个页面
wx.reLaunch({
url: '.../index/index'
});
},
e(){
// 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
wx.switchTab({
url: '.../index/index'
});
}
});
<!--pages/login/reg.wxml-->
<!--返回上一级页面-->
<button bindtap="a">返回上一级页面</button>
<!--保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面-->
<button bindtap="b">跳转至日志页面</button>
<!--关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面-->
<button bindtap="c">跳转至日志页面</button>
<!--关闭所有页面,打开到应用内的某个页面-->
<button bindtap="d">跳转至首页</button>
<!--跳转到 tabBar 页面,并关闭所有非 tabBar 页面-->
<button bindtap="e">跳转至首页</button>
<!--pages/login/login.wxml-->
<navigator url="reg">跳转到注册页面</navigator>
navigateBack 关闭当前页面 返回上一页面或多级页面
navigateTo 保留当前页面 不能跳到 tabbar 页面
redirectTo 关闭当前页面 不能跳到 tabbar 页面
reLaunch 关闭所有页面 可以跳转至任意页面
switchTab 关闭所有非 tabBar 页面 只能跳转到 tabBar 页面
名称 | 功能说明 |
---|---|
clearInterval | 取消由 setInterval 设置的定时器 |
clearTimeout | 取消由 setTimeout 设置的定时器 |
setInterval | 设定一个定时器,定时到期以后执行回调函数 |
setTimeout | 设定一个定时器,按照指定周期执行回调函数 |
// pages/nav/3.js
Page({
/**
* 页面的初始数据
*/
data: {
num: 1,
myInter: null
},
timeout(){
// 两秒后执行
setTimeout(()=>{
wx.showToast({
title: '成功',
icon: "success",
duration: 2000
})
},2000);
},
startTime(){
// 设置定时器每隔一秒执行一次
this.data.myInter = setInterval(() => {
this.data.num++;
console.log(this.data.num);
}, 1000);
},
stopTime(){
// 清除定时器
clearInterval(this.data.myInter);
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
})
<button bindtap="timeout">两秒后提示成功</button>
<button bindtap="startTime">开启定时器,每个一秒执行一次</button>
<button bindtap="stopTime">关闭定时器</button>
路由方式 | 触发时机 |
---|---|
初始化 | 小程序打开的第一个页面 |
打开新页面 | 调用 API wx.navigateTo 使用组件 <navigator open-type="navigateTo"/> |
页面重定向 | 调用 API wx.redirectTo 使用组件 <navigator open-type="redirectTo"/> |
页面返回 | 调用 API wx.navigateBack 使用组件<navigator open-type="navigateBack"> 用户按左上角返回按钮 |
Tab 切换 | 调用 API wx.switchTab 使用组件 <navigator open-type="switchTab"/> 用户切换 Tab |
重启动 | 调用 API wx.reLaunch 使用组件 <navigator open-type="reLaunch"/> |
navigator
页面链接编号 | 属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|---|
1 | target | string | self | 否 | 在哪个目标上发生跳转,默认当前小程序 |
1 | url | string | 否 | 当前小程序内的跳转链接 | |
2 | open-type | string | navigate | 否 | 跳转方式 |
3 | delta | number | 1 | 否 | 当 open-type 为 ‘navigateBack’ 时有效,表示回退的层数 |
4 | app-id | string | 否 | 当 target=”miniProgram”时有效,要打开的小程序 | |
5 | path | string | 否 | 当 target=”miniProgram”时有效,打开的页面路径,如果为空则打开首页 | |
6 | extra-data | object | 否 | 当 target=”miniProgram”时有效,需要传递给目标小程序的数据,目标小程序可在 App.onLaunch(),App.onShow() 中获取到这份数据。 | |
7 | version | string | release | 否 | 当 target=”miniProgram”时有效,要打开的小程序版本 |
8 | hover-class | string | navigator-hover | 否 | 指定点击时的样式类,当 hover-class=”none”时,没有点击态效果 |
9 | hover-stop-propagation | boolean | false | 否 | 指定是否阻止本节点的祖先节点出现点击态 |
10 | hover-start-time | number | 50 | 否 | 按住后多久出现点击态,单位毫秒 |
11 | hover-stay-time | number | 600 | 否 | 手指松开后点击态保留时间,单位毫秒 |
12 | bindsuccess | string | 否 | 当 target=”miniProgram”时有效,跳转小程序成功 | |
13 | bindfail | string | 否 | 当 target=”miniProgram”时有效,跳转小程序失败 | |
14 | bindcomplete | string | 否 | 当 target=”miniProgram”时有效,跳转小程序完成 |
target
的合法值编号 | 值 | 说明 |
---|---|---|
1 | self | 当前小程序 |
2 | miniProgram | 其它小程序 |
open-type
的合法值编号 | 值 | 说明 |
---|---|---|
1 | switchTab | 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面 |
2 | reLaunch | 关闭所有页面,打开到应用内的某个页面 |
3 | redirect | 关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面 |
4 | navigate | 保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面 |
5 | navigateBack | 关闭当前页面,返回上一页面或多级页面 |
6 | exit | 退出小程序,target=”miniProgram”时生效 |
先配置页面和按钮
"pages":[
"pages/nav/1",
"pages/nav/2",
"pages/nav/3",
"pages/nav/4",
"pages/nav/5",
"pages/nav/6",
"pages/nav/7"
],
"tabBar":{
"color":"#000000",
"selectedColor":"#aa33aa",
"backgroundColor":"#ffffff",
"borderStyle":"black",
"list":[
{
"pagePath":"pages/nav/1",
"text":"1号页面"
},
{
"pagePath":"pages/nav/2",
"text":"2号页面"
},
{
"pagePath":"pages/nav/3",
"text":"3号页面"
}
]
},
<!-- pages/nav/1.wxml -->
<view>这是1页面</view>
<navigator url="2" open-type="switchTab">跳转2页面,tabBar页面,关闭其他页面,除tabBar</navigator>
<!-- pages/nav/2.wxml -->
<navigator url="3" open-type="reLaunch">跳转3页面,tabBar页面,关闭所有页面</navigator>
<!-- pages/nav/3.wxml -->
<navigator url="4" open-type="redirect">跳转4页面,不能跳到tabBar页面</navigator>
<!-- pages/nav/4.wxml -->
<navigator url="5" open-type="navigate">跳转5页面,不能跳到tabBar页面</navigator>
<!-- pages/nav/7.wxml -->
<view>这是7页面</view>
<!--注意:navigateBack只能返回navigate跳转的页面,其他跳转都关闭了当前页面,返回不回去了-->
<navigator delta="10" open-type="navigateBack">返回之前页面,最多返回10层</navigator>
<!-- pages/nav/5.wxml -->
<navigator url="6?name=zhang" open-type="navigate">跳转6页面</navigator>
Page({
onLoad(e){
console.log(e);
}
});
API
编号 | 属性 | 说明 |
---|---|---|
1 | wx.switchTab | 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面 |
2 | wx.reLaunch | 关闭所有页面,打开到应用内的某个页面,可以跳转任意页面 |
3 | wx.redirectTo | 关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面 |
4 | wx.navigateTo | 保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面 |
5 | wx.navigateBack | 关闭当前页面,返回上一页面或多级页面 |
wx.switchTab
跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面编号 | 属性 | 类型 | 必填 | 说明 |
---|---|---|---|---|
1 | url | string | 是 | 需要跳转的 tabBar 页面的路径 (代码包路径)(需在 app.json 的 tabBar 字段定义的页面),路径后不能带参数。 |
2 | success | function | 否 | 接口调用成功的回调函数 |
3 | fail | function | 否 | 接口调用失败的回调函数 |
4 | complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行 |
<view>这是1页面</view>
<view bindtap="switchTab">跳转2页面,tabBar按钮,关闭其他页面,除tabBar</view>
Page({
switchTab() {
wx.switchTab({
url: "2",
success() {
console.log("跳转成功");
},
fail() {
console.log("跳转失败");
},
complete() {
console.log("跳转成功和成功");
},
});
},
});
wx.reLaunch
关闭所有页面,打开到应用内的某个页面编号 | 属性 | 类型 | 必填 | 说明 |
---|---|---|---|---|
1 | url | string | 是 | 需要跳转的应用内页面路径 (代码包路径),路径后可以带参数。参数与路径之间使用?分隔,参数键与参数值用=相连,不同参数用&分隔;如 ‘path?key=value&key2=value2’ |
2 | success | function | 否 | 接口调用成功的回调函数 |
3 | fail | function | 否 | 接口调用失败的回调函数 |
4 | complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行 |
<view>这是1页面</view>
<view bindtap="reLaunch">跳转3页面,tabBar按钮,关闭所有页面</view>
Page({
reLaunch() {
wx.reLaunch({
url: "3",
success() {
console.log("跳转成功");
},
fail() {
console.log("跳转失败");
},
complete() {
console.log("跳转成功和成功");
},
});
},
});
wx.redirectTo
关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面编号 | 属性 | 类型 | 必填 | 说明 |
---|---|---|---|---|
1 | url | string | 是 | 需要跳转的应用内页面路径 (代码包路径),路径后可以带参数。参数与路径之间使用?分隔,参数键与参数值用=相连,不同参数用&分隔;如 ‘path?key=value&key2=value2’ |
2 | success | function | 否 | 接口调用成功的回调函数 |
3 | fail | function | 否 | 接口调用失败的回调函数 |
4 | complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行 |
<view>这是1页面</view>
<view bindtap="redirectTo">跳转4页面</view>
Page({
redirectTo() {
wx.redirectTo({
url: "4",
success() {
console.log("跳转成功");
},
fail() {
console.log("跳转失败");
},
complete() {
console.log("跳转成功和成功");
},
});
},
});
wx.navigateTo
保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面编号 | 属性 | 类型 | 必填 | 说明 |
---|---|---|---|---|
1 | url | string | 是 | 需要跳转的应用内非 tabBar 的页面的路径 (代码包路径), 路径后可以带参数。参数与路径之间使用 ? 分隔,参数键与参数值用 = 相连,不同参数用 & 分隔;如 ‘path?key=value&key2=value2’ |
2 | events | Object | 否 | 页面间通信接口,用于监听被打开页面发送到当前页面的数据。基础库 2.7.3 开始支持。 |
3 | success | function | 否 | 接口调用成功的回调函数 |
4 | fail | function | 否 | 接口调用失败的回调函数 |
5 | complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行 |
<view>这是1页面</view>
<view bindtap="navigateTo">跳转5页面</view>
<view bindtap="navigateToTwo" data-name="zhang">跳转6页面</view>
Page({
navigateTo() {
wx.navigateTo({
url: "5",
success() {
console.log("跳转成功");
},
fail() {
console.log("跳转失败");
},
complete() {
console.log("跳转成功和成功");
},
});
},
navigateToTwo(e) {
console.log(e);
wx.navigateTo({
url: "6?name=" + e.target.dataset.name,
success() {
console.log("跳转成功");
},
fail() {
console.log("跳转失败");
},
complete() {
console.log("跳转成功和成功");
},
});
},
});
App({
data: "全局变量",
globalData: {
userInfo: "zhangshuai"
},
});
// 获取到小程序全局唯一的 App 实例
const app = getApp();
console.log(app.data);
console.log(app.globalData.userInfo);
const app = getApp();
app.data = "改变全局变量";
var
和 let
,在当前文件的任何位置都可以使用、更改
var name = "灭绝师太";
let gender = "女";
Page({
onLoad() {
console.log(name);
console.log(gender);
name = "zhangshuai";
gender = "男";
},
onShow() {
// 注意:不能在下面重新定义,只能修改值,如果重新声明,前面的都会获取不到这个变量
// var name = 'zhang'
console.log(name);
console.log(gender);
},
});
Page({
onLoad() {
// 变量只能在onLoad方法中使用
var name = "天蓬老师";
let gender = "男";
},
onShow() {
// 函数具有私有作用域,在这个方法体中获取不到onLoad方法中变量
// 这里会报错,找不到变量
console.log(name);
console.log(gender);
},
});
API
有独立的作用域
Page({
data: {
name: "zhangshuai",
},
onLoad() {
// 在当前方法里,this代表本页面,是可以调用data数据或者方法的
wx.getSystemInfo({
success(res) {
// 在api里使用 文件this就会报错
// 在异步API里面,this就不代表本页面了,代表异步API自身
console.log(this.data.name);
},
});
},
onShow() {
// 先把文件this存到新变量中
var that = this;
wx.getSystemInfo({
success(res) {
// 异步API中也有自己的this,他会优先访问自身的this变量指向
console.log(that.data.name);
that.getInfo();
},
});
},
getInfo() {
console.log("hhhhhhh");
},
});
function fun1() {
console.log("方法1");
}
function fun2(num) {
console.log("方法" + num);
}
function fun3() {
wx.getSystemInfo({
success(res) {
console.log(res);
},
});
}
// 格式化时间
const formatTime = date => {
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const hour = date.getHours()
const minute = date.getMinutes()
const second = date.getSeconds()
return `${[year, month, day].map(formatNumber).join('/')} ${[hour, minute, second].map(formatNumber).join(':')}`
}
const formatNumber = n => {
n = n.toString()
return n[1] ? n : `0${n}`
}
// module.exports 后面的名称 是给外部调用时 使用的名称
// =号后面的名称是本文件 创建的方法名称
module.exports.fun1 = fun1;
exports.fun2 = fun2;
// 可以一次性导出多个
module.exports = {
formatTime,
fun3
}
exports 是 module.exports 的一个引用
require
引入模块
// ES5
var common = require("../../utils/common.js");
// ES6
import common from "../../utils/common.js";
// 也可以只导入部分
import {formatTime} from "../../utils/common.js";
Page({
onLoad: function () {
common.fun1();
common.fun2(3);
common.fun3();
console.log(formatTime(new Date));
},
});
当然我们在测试开发的时候不必这么麻烦,我们可以通过开发工具设置不校验域名
wx.request
编号 | 属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|---|
1 | url | string | 是 | 开发者服务器接口地址 | |
2 | data | string/object/ArrayBuffer | 否 | 请求的参数 | |
3 | header | Object | 否 | 设置请求的 header,header 中不能设置 Referer。content-type 默认为 application/json | |
4 | timeout | number | 否 | 超时时间,单位为毫秒 | |
5 | method | string | GET | 否 | HTTP 请求方法 |
6 | dataType | string | json | 否 | 返回的数据格式 |
7 | responseType | string | text | 否 | 响应的数据类型 |
8 | success | function | 否 | 接口调用成功的回调函数 | |
9 | fail | function | 否 | 接口调用失败的回调函数 | |
10 | complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
编号 | 属性 | 类型 | 说明 |
---|---|---|---|
1 | data | string/Object/Arraybuffer | 开发者服务器返回的数据 |
2 | statusCode | number | 开发者服务器返回的 HTTP 状态码 |
3 | header | Object | 开发者服务器返回的 HTTP Response Header |
4 | cookies | Array. | 开发者服务器返回的 cookies,格式为字符串数组 |
Page({
/**
* 页面的初始数据
*/
data: {
future:[],
city: null
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
var that = this;
wx.request({
url: "http://apis.juhe.cn/simpleWeather/query",
data: {
city: "合肥",
key: "abc4b64ae7656b460723402175a5650b",
},
success(res) {
console.log(res);
that.setData({
city: res.data.result.city,
future: res.data.result.future
});
},
});
}
})
<view>{{city}}</view>
<view wx:for="{{future}}" wx:key="index">
<text>日期:{{item.date}}</text>
<text>温度:{{item.temperature}}</text>
<text>天气:{{item.weather}}</text>
<text>风向:{{item.direct}}</text>
</view>
method 的合法值
编号 | 值 | 说明 |
---|---|---|
1 | GET | HTTP 请求 GET |
2 | POST | HTTP 请求 POST |
3 | HEAD | HTTP 请求 HEAD |
4 | PUT | HTTP 请求 PUT |
5 | DELETE | HTTP 请求 DELETE |
6 | TRACE | HTTP 请求 TRACE |
7 | CONNECT | HTTP 请求 CONNECT |
8 | OPTIONS | HTTP 请求 OPTIONS |
dataType 的合法值
编号 | 值 | 说明 |
---|---|---|
1 | json | 返回的数据为 JSON,返回后会对返回的数据进行一次 JSON.parse |
2 | 其他 | 不对返回的内容进行 JSON.parse |
responseType 的合法值
编号 | 值 | 说明 |
---|---|---|
1 | text | 响应的数据为文本 |
2 | arraybuffer | 响应的数据为 ArrayBuffer |
Page({
onShow() {
wx.request({
url: "http://apis.juhe.cn/simpleWeather/query",
data: {
city: "合肥",
key: "abc4b64ae7656b460723402175a5650b",
},
header: {
"content-type": "application/x-www-form-urlencoded",
},
method: "POST",
dataType: "json",
responseType: "text",
success(res) {
console.log(res);
},
});
},
});
微信客户端在打开小程序之前,会把整个小程序的代码包下载到本地。
紧接着通过 app.json
的 pages
字段就可以知道你当前小程序的所有页面路径:
{
"pages":[
"pages/index/index",
"pages/logs/logs"
]
}
这个配置说明在 QuickStart 项目定义了两个页面,分别位于 pages/index/index
和 pages/logs/logs
。而写在 pages
字段的第一个页面就是这个小程序的首页(打开小程序看到的第一个页面)。
于是微信客户端就把首页的代码装载进来,通过小程序底层的一些机制,就可以渲染出这个首页。
小程序启动之后,在 app.js
定义的 App
实例的 onLaunch
回调会被执行:
App({
onLaunch: function () {
// 小程序启动之后 触发
}
})
整个小程序只有一个 App 实例,是全部页面共享的,更多的事件回调参考文档 注册程序 App 。
接下来我们简单看看小程序的一个页面是怎么写的。
你可以观察到 pages/logs/logs
下其实是包括了4种文件的,微信客户端会先根据 logs.json
配置生成一个界面,顶部的颜色和文字你都可以在这个 json
文件里边定义好。紧接着客户端就会装载这个页面的 WXML
结构和 WXSS
样式。最后客户端会装载 logs.js
,你可以看到 logs.js
的大体内容就是:
Page({
data: { // 参与页面渲染的数据
logs: []
},
onLoad: function () {
// 页面渲染后 执行
}
})
Page
是一个页面构造器,这个构造器就生成了一个页面。在生成页面的时候,小程序框架会把 data
数据和 index.wxml
一起渲染出最终的结构,于是就得到了你看到的小程序的样子。
在渲染完界面之后,页面实例就会收到一个 onLoad
的回调,你可以在这个回调处理你的逻辑。
有关于 Page
构造器更多详细的文档参考 注册页面 Page 。