w3cschool-微信小程序开发文档-框架

https://www.w3cschool.cn/weixinapp/1g7f1q8l.html

MINA文件结构

文件结构

MINA程序包含一个描述整体程序的app和多个描述各自页面的page。

一个MINA程序主体部分由三个文件组成,必须放在项目的根目录,如下:

文件必需作用
app.js 小程序逻辑
app.json 小程序公共设置
app.wxss 小程序公共样式表

一个MINA页面由四个文件组成,分别是:

文件类型必须作用
wxml 页面结构
wxss 页面样式表
json 页面配置
js 页面逻辑

注意:为了方便开发者减少配置项,我们规定描述页面的这四个文件必须具有相同的路径与文件名。

微信小程序 全局配置

2020-07-29 10:26 更新

全局配置

小程序根目录下的 app.json 文件用来对微信小程序进行全局配置。文件内容为一个 JSON 对象,有以下属性:

配置项

属性类型必填描述最低版本
entryPagePath string 小程序默认启动首页  
pages string[] 页面路径列表  
window Object 全局的默认窗口表现  
tabBar Object 底部 tab 栏的表现  
networkTimeout Object 网络超时时间  
debug boolean 是否开启 debug 模式,默认关闭  
functionalPages boolean 是否启用插件功能页,默认关闭 2.1.0
subpackages Object[] 分包结构配置 1.7.3
workers string Worker 代码放置的目录 1.9.90
requiredBackgroundModes string[] 需要在后台使用的能力,如「音乐播放」  
plugins Object 使用到的插件 1.9.6
preloadRule Object 分包预下载规则 2.3.0
resizable boolean PC 小程序是否支持用户任意改变窗口大小(包括最大化窗口);iPad 小程序是否支持屏幕旋转。默认关闭 2.3.0
usingComponents Object 全局自定义组件配置 开发者工具 1.02.1810190
permission Object 小程序接口权限相关设置 微信客户端 7.0.0
sitemapLocation string 指明 sitemap.json 的位置  
style string 指定使用升级后的weui样式 2.8.0
useExtendedLib Object 指定需要引用的扩展库 2.2.1
entranceDeclare Object 微信消息用小程序打开 微信客户端7.0.9
darkmode boolean 小程序支持 DarkMode 2.11.0
themeLocation string 指明 theme.json 的位置,darkmode为true为必填 开发者工具 1.03.2004271
lazyCodeLoading string 配置自定义组件代码按需注入 2.11.1
singlePage Object 单页模式相关配置 2.12.0

entryPagePath

指定小程序的默认启动路径(首页),常见情景是从微信聊天列表页下拉启动、小程序列表启动等。如果不填,将默认为 pages 列表的第一项。不支持带页面路径参数。

{
  "entryPagePath": "pages/index/index"
}

pages

用于指定小程序由哪些页面组成,每一项都对应一个页面的 路径(含文件名) 信息。文件名不需要写文件后缀,框架会自动去寻找对应位置的 .json, .js, .wxml, .wxss 四个文件进行处理。

未指定 entryPagePath 时,数组的第一项代表小程序的初始页面(首页)。

小程序中新增/减少页面,都需要对 pages 数组进行修改。

如开发目录为:

├── app.js
├── app.json
├── app.wxss
├── pages
│   │── index
│   │   ├── index.wxml
│   │   ├── index.js
│   │   ├── index.json
│   │   └── index.wxss
│   └── logs
│       ├── logs.wxml
│       └── logs.js
└── utils

则需要在 app.json 中写

{
  "pages": ["pages/index/index", "pages/logs/logs"]
}

window

用于设置小程序的状态栏、导航条、标题、窗口背景色。

属性类型默认值描述最低版本
navigationBarBackgroundColor HexColor #000000 导航栏背景颜色,如 #000000  
navigationBarTextStyle string white 导航栏标题颜色,仅支持 black / white  
navigationBarTitleText string   导航栏标题文字内容  
navigationStyle string default 导航栏样式,仅支持以下值:
default 默认样式
custom 自定义导航栏,只保留右上角胶囊按钮。参见注 2。
微信客户端 6.6.0
backgroundColor HexColor #ffffff 窗口的背景色  
backgroundTextStyle string dark 下拉 loading 的样式,仅支持 dark / light  
backgroundColorTop string #ffffff 顶部窗口的背景色,仅 iOS 支持 微信客户端 6.5.16
backgroundColorBottom string #ffffff 底部窗口的背景色,仅 iOS 支持 微信客户端 6.5.16
enablePullDownRefresh boolean false 是否开启全局的下拉刷新。
详见 Page.onPullDownRefresh
 
onReachBottomDistance number 50 页面上拉触底事件触发时距页面底部距离,单位为 px。
详见 Page.onReachBottom
 
pageOrientation string portrait 屏幕旋转设置,支持 auto / portrait / landscape
详见 响应显示区域变化
2.4.0 (auto) / 2.5.0 (landscape)
  • 注 1:HexColor(十六进制颜色值),如"#ff00ff"
  • 注 2:关于navigationStyle客户端 7.0.0 以下版本,navigationStyle 只在 app.json 中生效。客户端 6.7.2 版本开始,navigationStyle: custom 对 web-view 组件无效开启 custom 后,低版本客户端需要做好兼容。开发者工具基础库版本切到 1.7.0(不代表最低版本,只供调试用)可方便切到旧视觉

如:

{
  "window": {
    "navigationBarBackgroundColor": "#ffffff",
    "navigationBarTextStyle": "black",
    "navigationBarTitleText": "微信接口功能演示",
    "backgroundColor": "#eeeeee",
    "backgroundTextStyle": "light"
  }
}

tabBar

如果小程序是一个多 tab 应用(客户端窗口的底部或顶部有 tab 栏可以切换页面),可以通过 tabBar 配置项指定 tab 栏的表现,以及 tab 切换时显示的对应页面。

属性类型必填默认值描述最低版本
color HexColor   tab 上的文字默认颜色,仅支持十六进制颜色  
selectedColor HexColor   tab 上的文字选中时的颜色,仅支持十六进制颜色  
backgroundColor HexColor   tab 的背景色,仅支持十六进制颜色  
borderStyle string black tabbar 上边框的颜色, 仅支持 black / white  
list Array   tab 的列表,详见 list 属性说明,最少 2 个、最多 5 个 tab  
position string bottom tabBar 的位置,仅支持 bottom / top  
custom boolean false 自定义 tabBar,见详情 2.5.0

其中 list 接受一个数组,只能配置最少 2 个、最多 5 个 tab。tab 按数组的顺序排序,每个项都是一个对象,其属性值如下:

属性类型必填说明
pagePath string 页面路径,必须在 pages 中先定义
text string tab 上按钮文字
iconPath string 图片路径,icon 大小限制为 40kb,建议尺寸为 81px * 81px,不支持网络图片。
当 position 为 top 时,不显示 icon。
selectedIconPath string 选中时的图片路径,icon 大小限制为 40kb,建议尺寸为 81px * 81px,不支持网络图片。
当 position 为 top 时,不显示 icon。

networkTimeout

各类网络请求的超时时间,单位均为毫秒。

属性类型必填默认值说明
request number 60000 wx.request 的超时时间,单位:毫秒。
connectSocket number 60000 wx.connectSocket 的超时时间,单位:毫秒。
uploadFile number 60000 wx.uploadFile 的超时时间,单位:毫秒。
downloadFile number 60000 wx.downloadFile 的超时时间,单位:毫秒。

debug

可以在开发者工具中开启 debug 模式,在开发者工具的控制台面板,调试信息以 info 的形式给出,其信息有 Page 的注册,页面路由,数据更新,事件触发等。可以帮助开发者快速定位一些常见的问题。

functionalPages

基础库 2.1.0 开始支持,低版本需做兼容处理。

插件所有者小程序需要设置这一项来启用插件功能页。

subpackages

微信客户端 6.6.0 ,基础库 1.7.3 及以上版本支持

启用分包加载时,声明项目分包结构。

写成 subPackages 也支持。

workers

基础库 1.9.90 开始支持,低版本需做兼容处理。

使用 Worker 处理多线程任务时,设置 Worker 代码放置的目录

requiredBackgroundModes

微信客户端 6.7.2 及以上版本支持

申明需要后台运行的能力,类型为数组。目前支持以下项目:

  • audio: 后台音乐播放
  • location: 后台定位

如:

{
  "pages": ["pages/index/index"],
  "requiredBackgroundModes": ["audio", "location"]
}

注:在此处申明了后台运行的接口,开发版和体验版上可以直接生效,正式版还需通过审核。

plugins

基础库 1.9.6 开始支持,低版本需做兼容处理。

声明小程序需要使用的插件。

preloadRule

基础库 2.3.0 开始支持,低版本需做兼容处理。

声明分包预下载的规则。

resizable

基础库 2.3.0 开始支持,低版本需做兼容处理。

在 iPad 上运行的小程序可以设置支持屏幕旋转。

在 PC 上运行的小程序,用户可以按照任意比例拖动窗口大小,也可以在小程序菜单中最大化窗口

usingComponents

开发者工具 1.02.1810190 及以上版本支持

在此处声明的自定义组件视为全局自定义组件,在小程序内的页面或自定义组件中可以直接使用而无需再声明。

permission

微信客户端 7.0.0 及以上版本支持

小程序接口权限相关设置。字段类型为 Object,结构为:

属性类型必填默认值描述
scope.userLocation PermissionObject   位置相关权限声明

PermissionObject 结构

属性类型必填默认值说明
desc string   小程序获取权限时展示的接口用途说明。最长 30 个字符

如:

{
  "pages": ["pages/index/index"],
  "permission": {
    "scope.userLocation": {
      "desc": "你的位置信息将用于小程序位置接口的效果展示" // 高速公路行驶持续后台定位
    }
  }
}

sitemapLocation

指明 sitemap.json 的位置;默认为 'sitemap.json' 即在 app.json 同级目录下名字的 sitemap.json 文件

配置示例

{
  "pages": ["pages/index/index", "pages/logs/index"],
  "window": {
    "navigationBarTitleText": "Demo"
  },
  "tabBar": {
    "list": [
      {
        "pagePath": "pages/index/index",
        "text": "首页"
      },
      {
        "pagePath": "pages/logs/logs",
        "text": "日志"
      }
    ]
  },
  "networkTimeout": {
    "request": 10000,
    "downloadFile": 10000
  },
  "debug": true,
}

style

基础库 2.8.0 开始支持,低版本需做兼容处理。

微信客户端 7.0 开始,UI 界面进行了大改版。小程序也进行了基础组件的样式升级。app.json 中配置 "style": "v2"可表明启用新版的组件样式。

本次改动涉及的组件有 button icon radio checkbox switch slider。可前往小程序示例进行体验。

useExtendedLib

基础库 2.2.1 开始支持,低版本需做兼容处理。
最新的 nightly 版开发者工具开始支持,同时基础库从支持 npm 的版本(2.2.1)起支持

指定需要引用的扩展库。目前支持以下项目:

  • kbone: 多端开发框架
  • weui: WeUI 组件库

指定后,相当于引入了对应扩展库相关的最新版本的 npm 包,同时也不占用小程序的包体积。目前暂不支持在分包中引用。用法如下:

{
  "useExtendedLib": {
    "kbone": true,
    "weui": true
  }
}

entranceDeclare

微信客户端 7.0.9 及以上版本支持,iOS 暂不支持

聊天位置消息用打车类小程序打开,详情参考。

"entranceDeclare": {
    "locationMessage": {
        "path": "pages/index/index",
        "query": "foo=bar"
    }
}

darkmode

开发者工具 1.03.2004271 及以上版本支持,基础库 2.11.0 及以上版本支持

微信iOS客户端 7.0.12 版本、Android客户端 7.0.13 版本正式支持 DarkMode,可通过配置"darkmode": true表示当前小程序可适配 DarkMode,所有基础组件均会根据系统主题展示不同的默认样式,navigation bar 和 tab bar 也会根据开发者的配置自动切换。

配置后,请根据DarkMode 适配指南自行完成基础样式以外的适配工作。

{
  "darkmode": true
}

themeLocation

自定义 theme.json 的路径,当配置"darkmode":true时,当前配置文件为必填项。

{
  "themeLocation": "/path/to/theme.json"
}

lazyCodeLoading

基础库 2.11.1 及以上版本支持,2.11.1 以下兼容但无优化效果

通常情况下,在小程序启动期间,所有页面及自定义组件的代码都会进行注入,当前页面没有使用到的自定义组件和页面在注入后其实并没有被使用。

自基础库版本 2.11.1 起,小程序支持有选择地注入必要的代码,以降低小程序的启动时间和运行时内存。

{
  "lazyCodeLoading": "requiredComponents"
}

当配置了这一项时,小程序仅注入当前页面需要的自定义组件和页面代码,在页面中必然不会用到的自定义组件不会被加载和初始化。

注意:添加这项配置后,未使用到的代码文件将不被执行。

singlePage

基础库 2.11.3 及以上版本支持,目前分享到朋友圈 (Beta) 后打开会进入单页模式

单页模式相关配置

属性类型必填默认值描述
navigationBarFit String 默认自动调整,若原页面是自定义导航栏,则为 float,否则为 squeezed 导航栏与页面的相交状态,值为 float 时表示导航栏浮在页面上,与页面相交;值为 squeezed 时表示页面被导航栏挤压,与页面不相交

微信小程序 页面配置

页面配置

每一个小程序页面也可以使用 .json 文件来对本页面的窗口表现进行配置。页面中配置项在当前页面会覆盖 app.json 的 window 中相同的配置项。文件内容为一个 JSON 对象,有以下属性:

配置项

属性类型默认值描述最低版本
navigationBarBackgroundColor HexColor #000000 导航栏背景颜色,如 #000000  
navigationBarTextStyle string white 导航栏标题颜色,仅支持 black / white  
navigationBarTitleText string   导航栏标题文字内容  
navigationStyle string default 导航栏样式,仅支持以下值:
default 默认样式
custom 自定义导航栏,只保留右上角胶囊按钮
微信客户端 7.0.0
backgroundColor HexColor #ffffff 窗口的背景色  
backgroundTextStyle string dark 下拉 loading 的样式,仅支持 dark / light  
backgroundColorTop string #ffffff 顶部窗口的背景色,仅 iOS 支持 微信客户端 6.5.16
backgroundColorBottom string #ffffff 底部窗口的背景色,仅 iOS 支持 微信客户端 6.5.16
enablePullDownRefresh boolean false 是否开启当前页面下拉刷新。
详见 Page.onPullDownRefresh
 
onReachBottomDistance number 50 页面上拉触底事件触发时距页面底部距离,单位为px。
详见 Page.onReachBottom
 
pageOrientation string portrait 屏幕旋转设置,支持 auto / portrait / landscape
详见 响应显示区域变化
2.4.0 (auto) / 2.5.0 (landscape)
disableScroll boolean false 设置为 true 则页面整体不能上下滚动。
只在页面配置中有效,无法在 app.json 中设置
 
usingComponents Object 页面自定义组件配置 1.6.3
style string default 启用新版的组件样式 2.10.2
singlePage Object 单页模式相关配置 2.12.0
页面配置中只能设置 app.json 中 window 对应的配置项,以决定本页面的窗口表现,所以无需写 window 这个属性。

singlePage

基础库 2.11.3 及以上版本支持,目前分享到朋友圈 (Beta) 后打开会进入单页模式

单页模式相关配置

属性类型必填默认值描述
navigationBarFit String 默认自动调整,若原页面是自定义导航栏,则为 float,否则为 squeezed 导航栏与页面的相交状态,值为 float 时表示导航栏浮在页面上,与页面相交;值为 squeezed 时表示页面被导航栏挤压,与页面不相交

配置示例

{
  "navigationBarBackgroundColor": "#ffffff",
  "navigationBarTextStyle": "black",
  "navigationBarTitleText": "微信接口功能演示",
  "backgroundColor": "#eeeeee",
  "backgroundTextStyle": "light"
}

微信小程序 sitemap配置

微信现已开放小程序内搜索,开发者可以通过 sitemap.json 配置,或者管理后台页面收录开关来配置其小程序页面是否允许微信索引。当开发者允许微信索引时,微信会通过爬虫的形式,为小程序的页面内容建立索引。当用户的搜索词条触发该索引时,小程序的页面将可能展示在搜索结果中。 爬虫访问小程序内页面时,会携带特定的 user-agent:mpcrawler 及场景值:1129。需要注意的是,若小程序爬虫发现的页面数据和真实用户的呈现不一致,那么该页面将不会进入索引中。

sitemap 配置

小程序根目录下的 sitemap.json 文件用于配置小程序及其页面是否允许被微信索引,文件内容为一个 JSON 对象,如果没有 sitemap.json ,则默认为所有页面都允许被索引;sitemap.json 有以下属性:

配置项

属性类型必填描述
rules Object[] 索引规则列表

rules

rules 配置项指定了索引规则,每项规则为一个JSON对象,属性如下所示:

属性类型必填默认值取值取值说明
action string "allow" "allow"、"disallow" 命中该规则的页面是否能被索引
page string   "*"、页面的路径 * 表示所有页面,不能作为通配符使用
params string[] []   当 page 字段指定的页面在被本规则匹配时可能使用的页面参数名称的列表(不含参数值)
matching string "inclusive" 参考 matching 取值说明 当 page 字段指定的页面在被本规则匹配时,此参数说明 params 匹配方式
priority Number     优先级,值越大则规则越早被匹配,否则默认从上到下匹配

matching 取值说明

说明
exact 当小程序页面的参数列表等于 params 时,规则命中
inclusive 当小程序页面的参数列表包含 params 时,规则命中
exclusive 当小程序页面的参数列表与 params 交集为空时,规则命中
partial 当小程序页面的参数列表与 params 交集不为空时,规则命中

配置示例

示例1

{
  "rules":[{
    "action": "allow",
    "page": "path/to/page",
    "params": ["a", "b"],
    "matching": "exact"
  }, {
    "action": "disallow",
    "page": "path/to/page"
  }]
}
  • path/to/page?a=1&b=2 => 优先索引
  • path/to/page => 不被索引
  • path/to/page?a=1 => 不被索引
  • path/to/page?a=1&b=2&c=3 => 不被索引
  • 其他页面都会被索引

示例2

{
  "rules":[{
    "action": "allow",
    "page": "path/to/page",
    "params": ["a", "b"],
    "matching": "inclusive"
  }, {
    "action": "disallow",
    "page": "path/to/page"
  }]
}
  • path/to/page?a=1&b=2 => 优先索引
  • path/to/page?a=1&b=2&c=3 => 优先索引
  • path/to/page => 不被索引
  • path/to/page?a=1 => 不被索引
  • 其他页面都会被索引

示例3

{
  "rules":[{
    "action": "allow",
    "page": "path/to/page",
    "params": ["a", "b"],
    "matching": "exclusive"
  }, {
    "action": "disallow",
    "page": "path/to/page"
  }]
}
  • path/to/page => 优先索引
  • path/to/page?c=3 => 优先索引
  • path/to/page?a=1 => 不被索引
  • path/to/page?a=1&b=2 => 不被索引
  • 其他页面都会被索引

示例4

{
  "rules":[{
    "action": "allow",
    "page": "path/to/page",
    "params": ["a", "b"],
    "matching": "partial"
  }, {
    "action": "disallow",
    "page": "path/to/page"
  }]
}
  • path/to/page?a=1 => 优先索引
  • path/to/page?a=1&b=2 => 优先索引
  • path/to/page => 不被索引
  • path/to/page?c=3 => 不被索引
  • 其他页面都会被索引

注:没有 sitemap.json 则默认所有页面都能被索引

注:{"action": "allow", "page": "*"} 是优先级最低的默认规则,未显式指明 "disallow" 的都默认被索引

微信小程序 小程序APP

2020-07-28 16:47 更新

App(Object object)

注册小程序。接受一个 Object 参数,其指定小程序的生命周期回调等。

App() 必须在 app.js 中调用,必须调用且只能调用一次。不然会出现无法预期的后果。

参数

Object object
属性类型默认值必填说明最低版本
onLaunch function   生命周期回调——监听小程序初始化。  
onShow function   生命周期回调——监听小程序启动或切前台。  
onHide function   生命周期回调——监听小程序切后台。  
onError function   错误监听函数。  
onPageNotFound function   页面不存在监听函数。 1.9.90
onUnhandledRejection function   未处理的 Promise 拒绝事件监听函数。 2.10.0
onThemeChange function   监听系统主题变化 2.11.0
其他 any   开发者可以添加任意的函数或数据变量到 Object 参数中,用 this 可以访问  
关于小程序前后台的定义和小程序的运行机制,请参考运行机制章节。

示例代码

App({
  onLaunch (options) {
    // Do something initial when launch.
  },
  onShow (options) {
    // Do something when show.
  },
  onHide () {
    // Do something when hide.
  },
  onError (msg) {
    console.log(msg)
  },
  globalData: 'I am global data'
})

onLaunch(Object object)

小程序初始化完成时触发,全局只触发一次。参数也可以使用 wx.getLaunchOptionsSync 获取。

参数:与 wx.getLaunchOptionsSync 一致

onShow(Object object)

小程序启动,或从后台进入前台显示时触发。也可以使用 wx.onAppShow 绑定监听。

参数:与 wx.onAppShow 一致

onHide()

小程序从前台进入后台时触发。也可以使用 wx.onAppHide 绑定监听。

onError(String error)

小程序发生脚本错误或 API 调用报错时触发。也可以使用 wx.onError 绑定监听。

参数:与 wx.onError 一致

onPageNotFound(Object object)

基础库 1.9.90 开始支持,低版本需做兼容处理。

小程序要打开的页面不存在时触发。也可以使用 wx.onPageNotFound 绑定监听。注意事项请参考 wx.onPageNotFound。

参数:与 wx.onPageNotFound 一致

示例代码:

App({
  onPageNotFound(res) {
    wx.redirectTo({
      url: 'pages/...'
    }) // 如果是 tabbar 页面,请使用 wx.switchTab
  }
})

onUnhandledRejection(Object object)

基础库 2.10.0 开始支持,低版本需做兼容处理。

小程序有未处理的 Promise 拒绝时触发。也可以使用 wx.onUnhandledRejection 绑定监听。注意事项请参考 wx.onUnhandledRejection。

参数:与 wx.onUnhandledRejection 一致

onThemeChange(Object object)

基础库 2.11.0 开始支持,低版本需做兼容处理。

系统切换主题时触发。也可以使用 wx.onThemeChange 绑定监听。

参数:与 wx.onThemeChange 一致


AppObject getApp(Object object)

获取到小程序全局唯一的 App 实例。

参数

Object object
属性类型默认值必填说明最低版本
allowDefault boolean false 在 App 未定义时返回默认实现。当App被调用时,默认实现中定义的属性会被覆盖合并到App中。一般用于独立分包 2.2.4

示例代码

// other.js
var appInstance = getApp()
console.log(appInstance.globalData) // I am global data

注意

  • 不要在定义于 App() 内的函数中,或调用 App 前调用 getApp() ,使用 this 就可以拿到 app 实例。
  • 通过 getApp() 获取实例之后,不要私自调用生命周期函数。

微信小程序 页面

 

Page(Object object)

注册小程序中的一个页面。接受一个 Object 类型参数,其指定页面的初始数据、生命周期回调、事件处理函数等。

参数

Object object
属性类型默认值必填说明
data Object     页面的初始数据
onLoad function     生命周期回调—监听页面加载
onShow function     生命周期回调—监听页面显示
onReady function     生命周期回调—监听页面初次渲染完成
onHide function     生命周期回调—监听页面隐藏
onUnload function     生命周期回调—监听页面卸载
onPullDownRefresh function     监听用户下拉动作
onReachBottom function     页面上拉触底事件的处理函数
onShareAppMessage function     用户点击右上角转发
onShareTimeline function     用户点击右上角转发到朋友圈
onAddToFavorites function     用户点击右上角收藏
onPageScroll function     页面滚动触发事件的处理函数
onResize function     页面尺寸改变时触发,详见 响应显示区域变化
onTabItemTap function     当前是 tab 页时,点击 tab 时触发
其他 any     开发者可以添加任意的函数或数据到 Object 参数中,在页面的函数中用 this 可以访问

示例代码

//index.js
Page({
  data: {
    text: "This is page data."
  },
  onLoad: function(options) {
    // Do some initialize when page load.
  },
  onShow: function() {
    // Do something when page show.
  },
  onReady: function() {
    // Do something when page ready.
  },
  onHide: function() {
    // Do something when page hide.
  },
  onUnload: function() {
    // Do something when page close.
  },
  onPullDownRefresh: function() {
    // Do something when pull down.
  },
  onReachBottom: function() {
    // Do something when page reach bottom.
  },
  onShareAppMessage: function () {
    // return custom share data when user share.
  },
  onPageScroll: function() {
    // Do something when page scroll
  },
  onResize: function() {
    // Do something when page resize
  },
  onTabItemTap(item) {
    console.log(item.index)
    console.log(item.pagePath)
    console.log(item.text)
  },
  // Event handler.
  viewTap: function() {
    this.setData({
      text: 'Set some data for updating view.'
    }, function() {
      // this is setData callback
    })
  },
  customData: {
    hi: 'MINA'
  }
})

data

data 是页面第一次渲染使用的初始数据。

页面加载时,data 将会以JSON字符串的形式由逻辑层传至渲染层,因此data中的数据必须是可以转成JSON的类型:字符串,数字,布尔值,对象,数组。

渲染层可以通过 WXML 对数据进行绑定。

示例代码:

在开发者工具中预览效果

<view>{{text}}</view>
<view>{{array[0].msg}}</view>
Page({
  data: {
    text: 'init data',
    array: [{msg: '1'}, {msg: '2'}]
  }
})

生命周期回调函数

生命周期的触发以及页面的路由方式详见

onLoad(Object query)

页面加载时触发。一个页面只会调用一次,可以在 onLoad 的参数中获取打开当前页面路径中的参数。

参数:

名称类型说明
query Object 打开当前页面路径中的参数

onShow()

页面显示/切入前台时触发。

onReady()

页面初次渲染完成时触发。一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。

注意:对界面内容进行设置的 API 如wx.setNavigationBarTitle,请在onReady之后进行。详见生命周期

onHide()

页面隐藏/切入后台时触发。 如 wx.navigateTo 或底部 tab 切换到其他页面,小程序切入后台等。

onUnload()

页面卸载时触发。如wx.redirectTo或wx.navigateBack到其他页面时。

页面事件处理函数

onPullDownRefresh()

监听用户下拉刷新事件。

  • 需要在app.json的window选项中或页面配置中开启enablePullDownRefresh。
  • 可以通过wx.startPullDownRefresh触发下拉刷新,调用后触发下拉刷新动画,效果与用户手动下拉刷新一致。
  • 当处理完数据刷新后,wx.stopPullDownRefresh可以停止当前页面的下拉刷新。

onReachBottom()

监听用户上拉触底事件。

  • 可以在app.json的window选项中或页面配置中设置触发距离onReachBottomDistance。
  • 在触发距离内滑动期间,本事件只会被触发一次。

onPageScroll(Object object)

监听用户滑动页面事件。

参数 Object object:

属性类型说明
scrollTop Number 页面在垂直方向已滚动的距离(单位px)

注意:请只在需要的时候才在 page 中定义此方法,不要定义空方法。以减少不必要的事件派发对渲染层-逻辑层通信的影响。 注意:请避免在 onPageScroll 中过于频繁的执行 setData 等引起逻辑层-渲染层通信的操作。尤其是每次传输大量数据,会影响通信耗时。

onAddToFavorites(Object object)

本接口为 Beta 版本,安卓 7.0.15 版本起支持,暂只在安卓平台支持

监听用户点击右上角菜单“收藏”按钮的行为,并自定义收藏内容。

参数 Object object:

参数类型说明
webviewUrl String 页面中包含web-view组件时,返回当前web-view的url

此事件处理函数需要 return 一个 Object,用于自定义收藏内容:

字段说明默认值
title 自定义标题 页面标题或账号名称
imageUrl 自定义图片,显示图片长宽比为 1:1 页面截图
query 自定义query字段 当前页面的query

示例代码

Page({
  onAddToFavorites(res) {
    // webview 页面返回 webviewUrl
    console.log('WebviewUrl: ', res.webviewUrl)
    return {
      title: '自定义标题',
      imageUrl: 'http://demo.png',
      query: 'name=xxx&age=xxx',
    }
  }
})

onShareAppMessage(Object object)

监听用户点击页面内转发按钮(button 组件 open-type="share")或右上角菜单“转发”按钮的行为,并自定义转发内容。

注意:只有定义了此事件处理函数,右上角菜单才会显示“转发”按钮

参数 Object object:

参数类型说明最低版本
from String 转发事件来源。
button:页面内转发按钮;
menu:右上角转发菜单
1.2.4
target Object 如果 from 值是 button,则 target 是触发这次转发事件的 button,否则为 undefined 1.2.4
webViewUrl String 页面中包含web-view组件时,返回当前web-view的url 1.6.4

此事件处理函数需要 return 一个 Object,用于自定义转发内容,返回内容如下:

自定义转发内容 基础库 2.8.1 起,分享图支持云图片。

字段说明默认值最低版本
title 转发标题 当前小程序名称  
path 转发路径 当前页面 path ,必须是以 / 开头的完整路径  
imageUrl 自定义图片路径,可以是本地文件路径、代码包文件路径或者网络图片路径。支持PNG及JPG。显示图片长宽比是 5:4。 使用默认截图 1.5.0

示例代码

在开发者工具中预览效果

Page({
  onShareAppMessage: function (res) {
    if (res.from === 'button') {
      // 来自页面内转发按钮
      console.log(res.target)
    }
    return {
      title: '自定义转发标题',
      path: '/page/user?id=123'
    }
  }
})

onShareTimeline()

基础库 2.11.3 开始支持,低版本需做兼容处理。
本接口为 Beta 版本,暂只在 Android 平台支持,详见分享到朋友圈 (Beta)

监听右上角菜单“分享到朋友圈”按钮的行为,并自定义发享内容。

注意:只有定义了此事件处理函数,右上角菜单才会显示“分享到朋友圈”按钮

自定义转发内容

事件处理函数返回一个 Object,用于自定义分享内容,不支持自定义页面路径,返回内容如下:

字段说明默认值最低版本
title 自定义标题,即朋友圈列表页上显示的标题 当前小程序名称  
query 自定义页面路径中携带的参数,如 path?a=1&b=2 的 “?” 后面部分 当前页面路径携带的参数  
imageUrl 自定义图片路径,可以是本地文件或者网络图片。支持 PNG 及 JPG,显示图片长宽比是 1:1。 默认使用小程序 Logo  

onResize(Object object)

基础库 2.4.0 开始支持,低版本需做兼容处理。

小程序屏幕旋转时触发。详见 响应显示区域变化

onTabItemTap(Object object)

基础库 1.9.0 开始支持,低版本需做兼容处理。

点击 tab 时触发

Object 参数说明:

参数类型说明最低版本
index String 被点击tabItem的序号,从0开始 1.9.0
pagePath String 被点击tabItem的页面路径 1.9.0
text String 被点击tabItem的按钮文字 1.9.0

示例代码:

Page({
  onTabItemTap(item) {
    console.log(item.index)
    console.log(item.pagePath)
    console.log(item.text)
  }
})

组件事件处理函数

Page 中还可以定义组件事件处理函数。在渲染层的组件中加入事件绑定,当事件被触发时,就会执行 Page 中定义的事件处理函数。

示例代码:

在开发者工具中预览效果

<view bindtap="viewTap"> click me </view>
Page({
  viewTap: function() {
    console.log('view tap')
  }
})

Page.route

基础库 1.2.0 开始支持,低版本需做兼容处理。

到当前页面的路径,类型为String。

Page({
  onShow: function() {
    console.log(this.route)
  }
})

Page.prototype.setData(Object data, Function callback)

setData 函数用于将数据从逻辑层发送到视图层(异步),同时改变对应的 this.data 的值(同步)。

参数说明

字段类型必填描述最低版本
data Object 这次要改变的数据  
callback Function setData引起的界面更新渲染完毕后的回调函数 1.5.0

Object 以 key: value 的形式表示,将 this.data 中的 key 对应的值改变成 value。

其中 key 可以以数据路径的形式给出,支持改变数组中的某一项或对象的某个属性,如 array[2].message,a.b.c.d,并且不需要在 this.data 中预先定义。

注意:

  1. 直接修改 this.data 而不调用 this.setData 是无法改变页面的状态的,还会造成数据不一致。
  2. 仅支持设置可 JSON 化的数据。
  3. 单次设置的数据不能超过1024kB,请尽量避免一次设置过多的数据。
  4. 请不要把 data 中任何一项的 value 设为 undefined ,否则这一项将不被设置并可能遗留一些潜在问题。

示例代码:

在开发者工具中预览效果

<!--index.wxml-->
<view>{{text}}</view>
<button bindtap="changeText"> Change normal data </button>
<view>{{num}}</view>
<button bindtap="changeNum"> Change normal num </button>
<view>{{array[0].text}}</view>
<button bindtap="changeItemInArray"> Change Array data </button>
<view>{{object.text}}</view>
<button bindtap="changeItemInObject"> Change Object data </button>
<view>{{newField.text}}</view>
<button bindtap="addNewField"> Add new data </button>
// index.js
Page({
  data: {
    text: 'init data',
    num: 0,
    array: [{text: 'init data'}],
    object: {
      text: 'init data'
    }
  },
  changeText: function() {
    // this.data.text = 'changed data' // 不要直接修改 this.data
    // 应该使用 setData
    this.setData({
      text: 'changed data'
    })
  },
  changeNum: function() {
    // 或者,可以修改 this.data 之后马上用 setData 设置一下修改了的字段
    this.data.num = 1
    this.setData({
      num: this.data.num
    })
  },
  changeItemInArray: function() {
    // 对于对象或数组字段,可以直接修改一个其下的子字段,这样做通常比修改整个对象或数组更好
    this.setData({
      'array[0].text':'changed data'
    })
  },
  changeItemInObject: function(){
    this.setData({
      'object.text': 'changed data'
    });
  },
  addNewField: function() {
    this.setData({
      'newField.text': 'new data'
    })
  }
})

页面间通信

基础库 2.7.3 开始支持,低版本需做兼容处理。

如果一个页面由另一个页面通过 wx.navigateTo 打开,这两个页面间将建立一条数据通道:

  • 被打开的页面可以通过 this.getOpenerEventChannel() 方法来获得一个 EventChannel 对象;
  • wx.navigateTo 的 success 回调中也包含一个 EventChannel 对象。

这两个 EventChannel 对象间可以使用 emit 和 on 方法相互发送、监听事件。


PageObject[] getCurrentPages()

获取当前页面栈。数组中第一个元素为首页,最后一个元素为当前页面。

注意:

  • 不要尝试修改页面栈,会导致路由以及页面状态错误。
  • 不要在 App.onLaunch 的时候调用 getCurrentPages(),此时 page 还没有生成 

微信小程序 自定义组件

Component(Object object)

创建自定义组件,接受一个 Object 类型的参数。

参数

Object object

定义段类型是否必填描述最低版本
properties Object Map 组件的对外属性,是属性名到属性设置的映射表  
data Object 组件的内部数据,和 properties 一同用于组件的模板渲染  
observers Object 组件数据字段监听器,用于监听 properties 和 data 的变化,参见 数据监听器 2.6.1
methods Object 组件的方法,包括事件响应函数和任意的自定义方法,关于事件响应函数的使用,参见 组件间通信与事件  
behaviors String Array 类似于mixins和traits的组件间代码复用机制,参见 behaviors  
created Function 组件生命周期函数-在组件实例刚刚被创建时执行,注意此时不能调用 setData )  
attached Function 组件生命周期函数-在组件实例进入页面节点树时执行)  
ready Function 组件生命周期函数-在组件布局完成后执行)  
moved Function 组件生命周期函数-在组件实例被移动到节点树另一个位置时执行)  
detached Function 组件生命周期函数-在组件实例被从页面节点树移除时执行)  
relations Object 组件间关系定义,参见 组件间关系  
externalClasses String Array 组件接受的外部样式类,参见 外部样式类  
options Object Map 一些选项(文档中介绍相关特性时会涉及具体的选项设置,这里暂不列举)  
lifetimes Object 组件生命周期声明对象,参见 组件生命周期 2.2.3
pageLifetimes Object 组件所在页面的生命周期声明对象,参见 组件生命周期 2.2.3
definitionFilter Function 定义段过滤器,用于自定义组件扩展,参见 自定义组件扩展 2.2.3

生成的组件实例可以在组件的方法、生命周期函数和属性 observer 中通过 this 访问。组件包含一些通用属性和方法。

属性名类型描述
is String 组件的文件路径
id String 节点id
dataset String 节点dataset
data Object 组件数据,包括内部数据和属性值
properties Object 组件数据,包括内部数据和属性值(与 data 一致)
方法名参数描述最低版本
setData Object newData 设置data并执行视图层渲染  
hasBehavior Object behavior 检查组件是否具有 behavior (检查时会递归检查被直接或间接引入的所有behavior)  
triggerEvent String name, Object detail, Object options 触发事件,参见 组件间通信与事件  
createSelectorQuery   创建一个 SelectorQuery 对象,选择器选取范围为这个组件实例内  
createIntersectionObserver   创建一个 IntersectionObserver 对象,选择器选取范围为这个组件实例内  
createMediaQueryObserver   创建一个 MediaQueryObserver 对象 2.11.1
selectComponent String selector 使用选择器选择组件实例节点,返回匹配到的第一个组件实例对象(会被 wx://component-export 影响)  
selectAllComponents String selector 使用选择器选择组件实例节点,返回匹配到的全部组件实例对象组成的数组(会被 wx://component-export 影响)  
selectOwnerComponent   选取当前组件节点所在的组件实例(即组件的引用者),返回它的组件实例对象(会被 wx://component-export 影响) 2.8.2
getRelationNodes String relationKey 获取这个关系所对应的所有关联节点,参见 组件间关系  
groupSetData Function callback 立刻执行 callback ,其中的多个 setData 之间不会触发界面绘制(只有某些特殊场景中需要,如用于在不同组件同时 setData 时进行界面绘制同步) 2.4.0
getTabBar   返回当前页面的 custom-tab-bar 的组件实例,详见自定义 tabBar 2.6.2
getPageId   返回页面标识符(一个字符串),可以用来判断几个自定义组件实例是不是在同一个页面内 2.7.1
animate String selector, Array keyframes, Number duration, Function callback 执行关键帧动画,详见动画 2.9.0
clearAnimation String selector, Object options, Function callback 清除关键帧动画,详见动画 2.9.0

代码示例:

在开发者工具中预览效果

Component({

  behaviors: [],

  // 属性定义(详情参见下文)
  properties: {
    myProperty: { // 属性名
      type: String,
      value: ''
    },
    myProperty2: String // 简化的定义方式
  },

  data: {}, // 私有数据,可用于模板渲染

  lifetimes: {
    // 生命周期函数,可以为函数,或一个在methods段中定义的方法名
    attached: function () { },
    moved: function () { },
    detached: function () { },
  },

  // 生命周期函数,可以为函数,或一个在methods段中定义的方法名
  attached: function () { }, // 此处attached的声明会被lifetimes字段中的声明覆盖
  ready: function() { },

  pageLifetimes: {
    // 组件所在页面的生命周期函数
    show: function () { },
    hide: function () { },
    resize: function () { },
  },

  methods: {
    onMyButtonTap: function(){
      this.setData({
        // 更新属性和数据的方法与更新页面数据的方法类似
      })
    },
    // 内部方法建议以下划线开头
    _myPrivateMethod: function(){
      // 这里将 data.A[0].B 设为 'myPrivateData'
      this.setData({
        'A[0].B': 'myPrivateData'
      })
    },
    _propertyChange: function(newVal, oldVal) {

    }
  }

})

注意:在 properties 定义段中,属性名采用驼峰写法(propertyName);在 wxml 中,指定属性值时则对应使用连字符写法(component-tag-name property-name="attr value"),应用于数据绑定时采用驼峰写法(attr="")。

properties 定义

定义段类型是否必填描述最低版本
type   属性的类型  
optionalTypes Array 属性的类型(可以指定多个) 2.6.5
value   属性的初始值  
observer Function 属性值变化时的回调函数  

属性值的改变情况可以使用 observer 来监听。目前,在新版本基础库中不推荐使用这个字段,而是使用 Component 构造器的 observers 字段代替,它更加强大且性能更好。

代码示例:

Component({
  properties: {
    min: {
      type: Number,
      value: 0
    },
    min: {
      type: Number,
      value: 0,
      observer: function(newVal, oldVal) {
        // 属性值变化时执行
      }
    },
    lastLeaf: {
      // 这个属性可以是 Number 、 String 、 Boolean 三种类型中的一种
      type: Number,
      optionalTypes: [String, Object],
      value: 0
    }
  }
})

属性的类型可以为 String Number Boolean Object Array 其一,也可以为 null 表示不限制类型。

多数情况下,属性最好指定一个确切的类型。这样,在 WXML 中以字面量指定属性值时,值可以获得一个确切的类型,如:

<custom-comp min="1" max="5" />

此时,由于自定义组件的对应属性被规定为 Number 类型, min 和 max 会被赋值为 1 和 5 ,而非 "1" 和 "5" ,即:

this.data.min === 1 // true
this.data.max === 5 // true

提示:

  • 使用 this.data 可以获取内部数据和属性值;但直接修改它不会将变更应用到界面上,应使用 setData 修改。
  • 生命周期函数无法在组件方法中通过 this 访问到。
  • 属性名应避免以 data 开头,即不要命名成 dataXyz 这样的形式,因为在 WXML 中, data-xyz="" 会被作为节点 dataset 来处理,而不是组件属性。
  • 在一个组件的定义和使用时,组件的属性名和 data 字段相互间都不能冲突(尽管它们位于不同的定义段中)。
  • 从基础库 2.0.9 开始,对象类型的属性和 data 字段中可以包含函数类型的子字段,即可以通过对象类型的属性字段来传递函数。低于这一版本的基础库不支持这一特性。
  • bug : 位于 slot 中的自定义组件没有触发 pageLifetimes 中声明的页面生命周期,此问题在 2.5.2 中修复。
  • bug : 对于 type 为 Object 或 Array 的属性,如果通过该组件自身的 this.setData 来改变属性值的一个子字段,则依旧会触发属性 observer ,且 observer 接收到的 newVal 是变化的那个子字段的值, oldVal 为空, changedPath 包含子字段的字段名相关信息;目前推荐使用 observers 定义段代替。

Behavior(Object object)

注册一个 behavior,接受一个 Object 类型的参数。

参数

Object object

定义段类型是否必填描述最低版本
properties Object Map 同组件的属性  
data Object 同组件的数据  
methods Object 同自定义组件的方法  
behaviors String Array 引入其它的 behavior  
created Function 生命周期函数  
attached Function 生命周期函数  
ready Function 生命周期函数  
moved Function 生命周期函数  
detached Function 生命周期函数  

代码示例:

// my-behavior.js
module.exports = Behavior({
  behaviors: [],
  properties: {
    myBehaviorProperty: {
      type: String
    }
  },
  data: {
    myBehaviorData: {}
  },
  attached: function(){},
  methods: {
    myBehaviorMethod: function(){}
  }
})

微信小程序 模块化

any require(string path)

引入模块。返回模块通过 module.exports 或 exports 暴露的接口。

参数

名称类型说明
path string 需要引入模块文件相对于当前文件的相对路径,或npm模块名,或npm模块路径。不支持绝对路径

示例代码

// common.js
function sayHello(name) {
  console.log(`Hello ${name} !`)
}
function sayGoodbye(name) {
  console.log(`Goodbye ${name} !`)
}

module.exports.sayHello = sayHello
exports.sayGoodbye = sayGoodbye
var common = require('common.js')
Page({
  helloMINA: function() {
    common.sayHello('MINA')
  },
  goodbyeMINA: function() {
    common.sayGoodbye('MINA')
  }
})

Object module

当前模块对象

属性

属性类型说明
exports Object 模块向外暴露的对象,使用require引用该模块时可以获取

示例代码

// common.js
function sayHello(name) {
  console.log(`Hello ${name} !`)
}
function sayGoodbye(name) {
  console.log(`Goodbye ${name} !`)
}

module.exports.sayHello = sayHello
exports.sayGoodbye = sayGoodbye

Object exports

module.exports 的引用

示例代码

// common.js
function sayHello(name) {
  console.log(`Hello ${name} !`)
}
function sayGoodbye(name) {
  console.log(`Goodbye ${name} !`)
}

module.exports.sayHello = sayHello
exports.sayGoodbye = sayGoodbye

微信小程序 基础功能

Object wx

小程序 API 全局对象,用于承载小程序能力相关 API。

Object wx.env

小程序环境变量对象

String wx.env.USER_DATA_PATH

文件系统中的用户目录路径


console

向调试面板中打印日志。console 是一个全局对象,可以直接访问。在微信客户端中,向 vConsole 中输出日志。

方法:

console.debug()

向调试面板中打印 debug 日志

参数

 

any ...args
 

日志内容,可以有任意多个。

 

console.error()

向调试面板中打印 error 日志

参数

 

any ...args

日志内容,可以有任意多个。

 

console.group(string label)

在调试面板中创建一个新的分组。随后输出的内容都会被添加一个缩进,表示该内容属于当前分组。调用 console.groupEnd之后分组结束。

参数

string label

分组标记,可选。

注意

仅在工具中有效,在 vConsole 中为空函数实现。

 

console.groupEnd()

结束由 console.group 创建的分组

注意

仅在工具中有效,在 vConsole 中为空函数实现。

 

console.info()

向调试面板中打印 info 日志

参数

any ...args

日志内容,可以有任意多个。

 

console.log()

向调试面板中打印 log 日志

参数

any ...args

日志内容,可以有任意多个

 

console.warn()

向调试面板中打印 warn 日志

参数

any ...args

日志内容,可以有任意多个。


number setTimeout(function callback, number delay, any rest)

设定一个定时器。在定时到期以后执行注册的回调函数

参数

function callback

回调函数

number delay

延迟的时间,函数的调用会在该延迟之后发生,单位 ms。

any rest

param1, param2, ..., paramN 等附加参数,它们会作为参数传递给回调函数。

返回值

number

定时器的编号。这个值可以传递给 clearTimeout 来取消该定时。

 

clearTimeout(number timeoutID)

取消由 setTimeout 设置的定时器。

参数

number timeoutID

要取消的定时器的 ID

 

number setInterval(function callback, number delay, any rest)

设定一个定时器。按照指定的周期(以毫秒计)来执行注册的回调函数

参数

function callback

回调函数

number delay

执行回调函数之间的时间间隔,单位 ms。

any rest

param1, param2, ..., paramN 等附加参数,它们会作为参数传递给回调函数。

返回值

number

定时器的编号。这个值可以传递给 clearInterval 来取消该定时。

 

clearInterval(number intervalID)

取消由 setInterval 设置的定时器。

参数

number intervalID

要取消的定时器的 ID

微信小程序 注册程序 App()函数

App()


App()函数用来注册一个小程序。接受一个object参数,其指定小程序的生命周期函数等。

object参数说明:

 

属性类型描述触发时机
onLaunch Function 生命周期函数--监听小程序初始化 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
onShow Function 生命周期函数--监听小程序显示 当小程序启动,或从后台进入前台显示,会触发 onShow
onHide Function 生命周期函数--监听小程序隐藏 当小程序从前台进入后台,会触发 onHide
onError Function 错误监听函数 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息
onPageNotFound Function 页面不存在监听函数 当小程序出现要打开的页面不存在的情况,会带上页面信息回调该函数,详见下文
其他 Any   开发者可以添加任意的函数或数据到 Object 参数中,用 this 可以访问

前台、后台定义:当用户点击左上角关闭,或者按了设备 Home 键离开微信,小程序并没有直接销毁,而是进入了后台;当再次进入微信或再次打开小程序,又会从后台进入前台。需要注意的是:只有当小程序进入后台一定时间,或者系统资源占用过高,才会被真正的销毁。

关闭小程序(基础库版本1.1.0开始支持):当用户从扫一扫、转发等入口(场景值为1007, 1008, 1011, 1025)进入小程序,且没有置顶小程序的情况下退出,小程序会被销毁。小程序运行机制在基础库版本 1.4.0 有所改变:上一条关闭逻辑在新版本已不适用, 详情

示例代码:

App({
  onLaunch: function(options) { 
    // Do something initial when launch.
  },
  onShow: function(options) {
      // Do something when show.
  },
  onHide: function() {
      // Do something when hide.
  },
  onError: function(msg) {
    console.log(msg)
  },
  globalData: 'I am global data'
})

onLaunch, onShow 参数

字段类型说明
path String 打开小程序的路径
query Object 打开小程序的query
scene Number 打开小程序的场景值
shareTicket String shareTicket,详见 获取更多转发信息
referrerInfo Object 当场景为由另一个小程序打开时,返回此字段
referrerInfo.appId String 来源小程序的 appId
referrerInfo.extraData Object 来源小程序传过来的数据

场景值 详见

以下场景支持返回 referrerInfo.appId:

场景值场景appId 信息含义
1020 公众号 profile 页相关小程序列表 返回来源公众号 appId
1035 公众号自定义菜单 返回来源公众号 appId
1036 App 分享消息卡片 返回来源应用 appId
1037 小程序打开小程序 返回来源小程序 appId
1038 从另一个小程序返回 返回来源小程序 appId
1043 公众号模板消息 返回来源公众号 appId

onPageNotFound

基础库 1.9.90 开始支持,低版本需做兼容处理

当要打开的页面并不存在时,会回调这个监听器,并带上以下信息:

字段类型说明
path String 不存在页面的路径
query Object 打开不存在页面的 query
isEntryPage Boolean 是否本次启动的首个页面(例如从分享等入口进来,首个页面是开发者配置的分享页面)

开发者可以在 onPageNotFound 回调中进行重定向处理,但必须在回调中同步处理,异步处理(例如 setTimeout 异步执行)无效。

示例代码:

App({
  onPageNotFound(res) {
    wx.redirectTo({
      url: 'pages/...'
    })
  }
})

注意:

  1. 微信开发者工具暂不支持 onPageNotFound 调试,请使用真机调试
  2. 如果开发者没有添加 onPageNotFound 监听,当跳转页面不存在时,将推入微信客户端原生的页面不存在提示页面
  3. 如果 onPageNotFound 回调中又重定向到另一个不存在的页面,将推入微信客户端原生的页面不存在提示页面,并且不在回调 onPageNotFound

getApp()


我们提供了全局的getApp()函数,可以获取到小程序实例。

// other.js
var appInstance = getApp()
console.log(appInstance.globalData) // I am global data

注意:

App()必须在app.js中注册,且不能注册多个。

不要在定义于App()内的函数中调用getApp(),使用this就可以拿到app实例。

不要在onLaunch的时候调用getCurrentPage(),此时page还没有生成。

通过getApp()获取实例之后,不要私自调用生命周期函数。

微信小程序 场景值

场景值列表

关于场景值的详细说明和获取方式请参考 指南-场景值

场景值ID说明图例
1000 其他 /
1001 发现栏小程序主入口,「最近使用」列表(基础库2.2.4版本起包含「我的小程序」列表) /
1005 微信首页顶部搜索框的搜索结果页 查看
1006 发现栏小程序主入口搜索框的搜索结果页 查看
1007 单人聊天会话中的小程序消息卡片 查看
1008 群聊会话中的小程序消息卡片 查看
1010 收藏夹 查看
1011 扫描二维码 查看
1012 长按图片识别二维码 查看
1013 扫描手机相册中选取的二维码 查看
1014 小程序模板消息 查看
1017 前往小程序体验版的入口页 查看
1019 微信钱包(微信客户端7.0.0版本改为支付入口) 查看

微信小程序 注册页面 Page()函数

Page


Page() 函数用来注册一个页面。接受一个 object 参数,其指定页面的初始数据、生命周期函数、事件处理函数等。

object 参数说明:

属性类型描述
data Object 页面的初始数据
onLoad Function 生命周期函数--监听页面加载
onReady Function 生命周期函数--监听页面初次渲染完成
onShow Function 生命周期函数--监听页面显示
onHide Function 生命周期函数--监听页面隐藏
onUnload Function 生命周期函数--监听页面卸载
onPullDownRefresh Function 页面相关事件处理函数--监听用户下拉动作
onReachBottom Function 页面上拉触底事件的处理函数
onShareAppMessage Function 用户点击右上角转发
onPageScroll Function 页面滚动触发事件的处理函数
其他 Any 开发者可以添加任意的函数或数据到 object 参数中,在页面的函数中用 this 可以访问

示例代码:

//index.js
Page({
  data: {
    text: "This is page data."
  },
  onLoad: function(options) {
    // Do some initialize when page load.
  },
  onReady: function() {
    // Do something when page ready.
  },
  onShow: function() {
    // Do something when page show.
  },
  onHide: function() {
    // Do something when page hide.
  },
  onUnload: function() {
    // Do something when page close.
  },
  onPullDownRefresh: function() {
    // Do something when pull down.
  },
  onReachBottom: function() {
    // Do something when page reach bottom.
  },
  onShareAppMessage: function () {
   // return custom share data when user share.
  },
  onPageScroll: function() {
    // Do something when page scroll
  },
  // Event handler.
  viewTap: function() {
    this.setData({
      text: 'Set some data for updating view.'
    })
  },
  customData: {
    hi: 'MINA'
  }
})

初始化数据


初始化数据将作为页面的第一次渲染。data 将会以 JSON 的形式由逻辑层传至渲染层,所以其数据必须是可以转成 JSON 的格式:字符串,数字,布尔值,对象,数组。

渲染层可以通过 WXML 对数据进行绑定。

示例代码:

 

<view>{{text}}</view>
<view>{{array[0].msg}}</view>
Page({
  data: {
    text: 'init data',
    array: [{msg: '1'}, {msg: '2'}]
  }
})

 

生命周期函数


  • onLoad: 页面加载

    • 一个页面只会调用一次,可以在 onLoad 中获取打开当前页面所调用的 query 参数。
  • onShow: 页面显示

    • 每次打开页面都会调用一次。
  • onReady: 页面初次渲染完成

    • 一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。
    • 对界面的设置如wx.setNavigationBarTitle请在onReady之后设置。详见生命周期
  • onHide: 页面隐藏

    • navigateTo或底部tab切换时调用。
  • onUnload: 页面卸载

    • redirectTonavigateBack的时候调用。

生命周期的调用以及页面的路由方式详见

onLoad参数

类型说明
Object 其他页面打开当前页面所调用的 query 参数

页面相关事件处理函数


  • onPullDownRefresh: 下拉刷新

    • 监听用户下拉刷新事件。
    • 需要在configwindow选项中开启enablePullDownRefresh
    • 当处理完数据刷新后,wx.stopPullDownRefresh可以停止当前页面的下拉刷新。
  • onReachBottom: 上拉触底

    • 监听用户下拉触底事件。
  • onPageScroll: 页面滚动

    • 监听用户滑动页面事件。
    • 参数为 Object,包含以下字段:
字段类型说明
scrollTop Number 页面在垂直方向已滚动的距离(单位px)
  • onShareAppMessage: 用户转发
    • 只有定义了此事件处理函数,右上角菜单才会显示“转发”按钮
    • 用户点击转发按钮的时候会调用
    • 此事件需要 return 一个 Object,用于自定义转发内容

自定义转发字段

字段说明默认值
title 转发标题 当前小程序名称
path 转发路径 当前页面 path ,必须是以 / 开头的完整路径

示例代码

Page({
  onShareAppMessage: function () {
    return {
      title: '自定义转发标题',
      path: '/page/user?id=123'
    }
  }
})

 

事件处理函数


除了初始化数据和生命周期函数,Page 中还可以定义一些特殊的函数:事件处理函数。在渲染层可以在组件中加入事件绑定,当达到触发事件时,就会执行 Page 中定义的事件处理函数。

示例代码:

<view bindtap="viewTap"> click me </view>
Page({
  viewTap: function() {
    console.log('view tap')
  }
})

Page.prototype.route


route 字段可以获取到当前页面的路径。

Page.prototype.setData()


setData 函数用于将数据从逻辑层发送到视图层,同时改变对应的 this.data 的值。

setData() 参数格式


接受一个对象,以 key,value 的形式表示将 this.data 中的 key 对应的值改变成 value。

其中 key 可以非常灵活,以数据路径的形式给出,如 array[2].messagea.b.c.d,并且不需要在 this.data 中预先定义。

注意:

  1. 直接修改 this.data 而不调用 this.setData 是无法改变页面的状态的,还会造成数据不一致
  2. 单次设置的数据不能超过1024kB,请尽量避免一次设置过多的数据

示例代码:

<!--index.wxml-->
<view>{{text}}</view>
<button bindtap="changeText"> Change normal data </button>
<view>{{num}}</view>
<button bindtap="changeNum"> Change normal num </button>
<view>{{array[0].text}}</view>
<button bindtap="changeItemInArray"> Change Array data </button>
<view>{{object.text}}</view>
<button bindtap="changeItemInObject"> Change Object data </button>
<view>{{newField.text}}</view>
<button bindtap="addNewField"> Add new data </button>
//index.js
Page({
  data: {
    text: 'init data',
    num: 0,
    array: [{text: 'init data'}],
    object: {
      text: 'init data'
    }
  },
  changeText: function() {
    // this.data.text = 'changed data'  // bad, it can not work
    this.setData({
      text: 'changed data'
    })
  },
  changeNum: function() {
    this.data.num = 1
    this.setData({
      num: this.data.num
    })
  },
  changeItemInArray: function() {
    // you can use this way to modify a danamic data path
    this.setData({
      'array[0].text':'changed data'
    })
  },
  changeItemInObject: function(){
    this.setData({
      'object.text': 'changed data'
    });
  },
  addNewField: function() {
    this.setData({
      'newField.text': 'new data'
    })
  }
})

以下内容你不需要立马完全弄明白,不过以后它会有帮助。

生命周期


下图说明了 Page 实例的生命周期。

1488607970192659

 

微信小程序 页面路由

 

页面路由

在小程序中所有页面的路由全部由框架进行管理。

页面栈

框架以栈的形式维护了当前的所有页面。当发生路由切换的时候,页面栈的表现如下:

路由方式页面栈表现
初始化 新页面入栈
打开新页面 新页面入栈
页面重定向 当前页面出栈,新页面入栈
页面返回 页面不断出栈,直到目标返回页,新页面入栈
Tab 切换 页面全部出栈,只留下新的 Tab 页面
重加载 页面全部出栈,只留下新的页面

getCurrentPages()

getCurrentPages()函数用于获取当前页面栈的实例,以数组形式按栈的顺序给出,第一个元素为首页,最后一个元素为当前页面。

Tip:不要尝试修改页面栈,会导致路由以及页面状态错误。

路由方式

对于路由的触发方式以及页面生命周期函数如下:

路由方式触发时机路由前页面路由后页面
初始化 小程序打开的第一个页面   onLoad, onSHow
打开新页面 调用 API wx.navigateTo 或使用组件 <navigator open-type="navigateTo"/> onHide onLoad, onShow
页面重定向 调用 API wx.redirectTo 或使用组件 <navigator open-type="redirectTo"/> onUnload onLoad, onShow
页面返回 调用 API wx.navigateBack 或使用组件<navigator open-type="navigateBack">或用户按左上角返回按钮 onUnload onShow
Tab 切换 调用 API wx.switchTab 或使用组件 <navigator open-type="switchTab"/> 或用户切换 Tab   各种情况请参考下表
重启动 调用 API wx.reLaunch 或使用组件 <navigator open-type="reLaunch"/> onUnload onLoad, onShow

Tab 切换对应的生命周期(以 A、B 页面为 Tabbar 页面,C 是从 A 页面打开的页面,D 页面是从 C 页面打开的页面为例):

当前页面路由后页面触发的生命周期(按顺序)
A A Nothing happend
A B A.onHide(), B.onLoad(), B.onShow()
A B(再次打开) A.onHide(), B.onShow()
C A C.onUnload(), A.onShow()
C B C.onUnload(), B.onLoad(), B.onShow()
D B D.onUnload(), C.onUnload(), B.onLoad(), B.onShow()
D(从转发进入) A D.onUnload(), A.onLoad(), A.onShow()
D(从转发进入) B D.onUnload(), B.onLoad(), B.onShow()

Tips:

  • navigateTo,redirectTo只能打开非 tabBar 页面。
  • switchTab 只能打开 tabBar 页面。
  • reLaunch 可以打开任意页面。
  • 页面底部的 tabBar 由页面决定,即只要是定义为 tabBar 的页面,底部都有 tabBar。
  • 调用页面路由带的参数可以在目标页面的onLoad中获取。

微信小程序 模块化

文件作用域

在JavaScript文件中声明的变量和函数只在该文件中有效;不同的文件中可以声明相同名字的变量和函数,不会互相影响。

通过全局函数getApp()可以获取全局的应用实例,如果需要全局的数据可以在App()中设置,如:

// app.js
App({
  globalData: 1
})
// a.js
// The localValue can only be used in file a.js.
var localValue = 'a'
// Get the app instance.
var app = getApp()
// Get the global data and change it.
app.globalData++
// b.js
// You can redefine localValue in file b.js, without interference with the localValue in a.js.
var localValue = 'b'
// If a.js it run before b.js, now the globalData shoule be 2.
console.log(getApp().globalData)

模块化

我们可以将一些公共的代码抽离成为一个单独的js文件,作为一个模块。模块只有通过module.exports或者 exports才能对外暴露接口。

需要注意的是:

  • exportsmodule.exports的一个引用,因此在模块里边随意更改exports的指向会造成未知的错误。所以我们更推荐开发者采用module.exports来暴露模块接口,除非你已经清晰知道这两者的关系。
  • 小程序目前不支持直接引入node_modules,开发者需要使用到node_modules时候建议拷贝出相关的代码到小程序的目录中。

 

// common.js
function sayHello(name) {
  console.log('Hello ${name} !')
}
function sayGoodbye(name) {
  console.log('Goodbye ${name} !')
}

module.exports.sayHello = sayHello
exports.sayGoodbye = sayGoodbye

​在需要使用这些模块的文件中,使用require(path)将公共代码引入。

var common = require('common.js')
Page({
  helloMINA: function() {
    common.sayHello('MINA')
  }
  goodbyeMINA: function() {
    common.sayGoodbye('MINA')
  }
})

Tips

1. tip:require暂时不支持绝对路径

小程序 API

2018-12-07 16:06 更新

小程序API

小程序开发框架MINA提供丰富的微信原生API,可以方便的调起微信提供的能力,如获取用户信息本地存储支付功能等。

详细介绍请参考微信小程序API文档

微信小程序 WXML

数据绑定

WXML中的动态数据均来自对应Page的data。

简单绑定

数据绑定使用"Mustache"语法(双大括号)将变量包起来,可以作用于:

内容

<view> {{ message }} </view>
Page({
  data: {
    message: 'Hello MINA!'
  }
})

组件属性(需要在双引号之内)

<view id="item-{{id}}"> </view>
Page({
  data: {
    id: 0
  }
})

控制属性(需要在双引号之内)

<view wx:if="{{condition}}"> </view>
Page({
  data: {
    condition: true
  }
})

关键字(需要在双引号之内)

true:boolean 类型的 true,代表真值。

false: boolean 类型的 false,代表假值。

<checkbox checked="{{false}}"> </checkbox>

特别注意:不要直接写 checked="false",其计算结果是一个字符串,转成 boolean 类型后代表真值。

运算

可以在{{}}内进行简单的运算,支持的有如下几种方式:

三元运算

<view hidden="{{flag ? true : false}}"> Hidden </view>

算数运算

<view> {{a + b}} + {{c}} + d </view>
Page({
  data: {
    a: 1,
    b: 2,
    c: 3
  }
})

view中的内容为3 + 3 + d

逻辑判断

<view wx:if="{{length > 5}}"> </view>

字符串运算

<view>{{"hello" + name}}</view>
Page({
  data:{
    name:"MINA"
  }
})

数据路径运算

<view>{{object.key}} {{array[0]}}</view>
Page({
  data: {
    object: {
      key: 'Hello '
    },
    array: ['MINA']
  }
})

组合

也可以在Mustache内直接进行组合,构成新的对象或者数组。

数组

<view wx:for-items="{{[zero, 1, 2, 3, 4]}}"> {{item}} </view>
Page({
  data: {
    zero: 0
  }
})

最终组合成数组[0, 1, 2, 3, 4]。

对象

<template is="objectCombine" data="{{for: a, bar: b}}"></template>
Page({
  data: {
    a: 1,
    b: 2
  }
})

最终组合成的对象是{for: 1, bar: 2}

也可以用扩展运算符...来将一个对象展开

<template is="objectCombine" data="{{...obj1, ...obj2, e: 5}}"></template>
Page({
  data: {
    obj1: {
      a: 1,
      b: 2
    },
    obj2: {
      c: 3,
      d: 4
    }
  }
})

最终组合成的对象是{a: 1, b: 2, c: 3, d: 4, e: 5}

如果对象的key和value相同,也可以间接地表达。

<template is="objectCombine" data="{{foo, bar}}"></template>
Page({
  data: {
    foo: 'my-foo',
    bar: 'my-bar'
  }
})

最终组合成的对象是{foo: 'my-foo', bar:'my-bar'}

注意:上述方式可以随意组合,但是如有存在变量名相同的情况,后边的会覆盖前面,如:

<template is="objectCombine" data="{{...obj1, ...obj2, a, c: 6}}"></template>
Page({
  data: {
    obj1: {
      a: 1,
      b: 2
    },
    obj2: {
      b: 3,
      c: 4
    },
    a: 5
  }
})

 

最终组合成的对象是 {a: 5, b: 3, c: 6}

注意: 花括号和引号之间如果有空格,将最终被解析成为字符串

<view wx:for="{{[1,2,3]}} ">
  {{item}}
</view>

等同于

<view wx:for="{{[1,2,3] + ' '}}">
  {{item}}
</view>

微信小程序 列表渲染 wx:for

wx:for


在组件上使用 wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。

默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item

<view wx:for="{{array}}">
  {{index}}: {{item.message}}
</view>
Page({
  data: {
    array: [{
      message: 'foo',
    }, {
      message: 'bar'
    }]
  }
})

使用 wx:for-item 可以指定数组当前元素的变量名,

使用 wx:for-index 可以指定数组当前下标的变量名:

<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
  {{idx}}: {{itemName.message}}
</view>

如下,是一个轮播的图片列表循环,使用了wx:for方法:

20200629113357203

20200629113319412

 这个注意了。wx:key还是要加上的,不然一直报这个提示错误

20200629145733130

 

 

wx:for 也可以嵌套,下边是一个九九乘法表

<view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="i">
  <view wx:for="{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx:for-item="j">
    <view wx:if="{{i <= j}}">
      {{i}} * {{j}} = {{i * j}}
    </view>
  </view>
</view>

block wx:for


类似 block wx:if,也可以将 wx:for 用在<block/>标签上,以渲染一个包含多节点的结构块。例如:

<block wx:for="{{[1, 2, 3]}}">
  <view> {{index}}: </view>
  <view> {{item}} </view>
</block>

wx:key


如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如 <input/> 中的输入内容,<switch/> 的选中状态),需要使用 wx:key 来指定列表中项目的唯一的标识符。

wx:key 的值以两种形式提供

  1. 字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。
  2. 保留关键字 *this 代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字,如:

当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。

如不提供 wx:key,会报一个 warning, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。

示例代码:

<switch wx:for="{{objectArray}}" wx:key="unique" style="display: block;"> {{item.id}} </switch>
<button bindtap="switch"> Switch </button>
<button bindtap="addToFront"> Add to the front </button>

<switch wx:for="{{numberArray}}" wx:key="*this" style="display: block;"> {{item}} </switch>
<button bindtap="addNumberToFront"> Add to the front </button>
Page({
  data: {
    objectArray: [
      {id: 5, unique: 'unique_5'},
      {id: 4, unique: 'unique_4'},
      {id: 3, unique: 'unique_3'},
      {id: 2, unique: 'unique_2'},
      {id: 1, unique: 'unique_1'},
      {id: 0, unique: 'unique_0'},
    ],
    numberArray: [1, 2, 3, 4]
  },
  switch: function(e) {
    const length = this.data.objectArray.length
    for (let i = 0; i < length; ++i) {
      const x = Math.floor(Math.random() * length)
      const y = Math.floor(Math.random() * length)
      const temp = this.data.objectArray[x]
      this.data.objectArray[x] = this.data.objectArray[y]
      this.data.objectArray[y] = temp
    }
    this.setData({
      objectArray: this.data.objectArray
    })
  },
  addToFront: function(e) {
    const length = this.data.objectArray.length
    this.data.objectArray = [{id: length, unique: 'unique_' + length}].concat(this.data.objectArray)
    this.setData({
      objectArray: this.data.objectArray
    })
  },
  addNumberToFront: function(e){
    this.data.numberArray = [ this.data.numberArray.length + 1 ].concat(this.data.numberArray)
    this.setData({
      numberArray: this.data.numberArray
    })
  }
})

注意:

当 wx:for 的值为字符串时,会将字符串解析成字符串数组

<view wx:for="array">
  {{item}}
</view>

等同于

<view wx:for="{{['a','r','r','a','y']}}">
  {{item}}
</view>

注意: 花括号和引号之间如果有空格,将最终被解析成为字符串

<view wx:for="{{[1,2,3]}} ">
  {{item}}
</view>

等同于

<view wx:for="{{[1,2,3] + ' '}}" >
  {{item}}
</view>

wx:if

在框架中,我们用wx:if="{{condition}}"来判断是否需要渲染该代码块:

<view wx:if="{{condition}}"> True </view>

也可以用wx:elifwx:else来添加一个else块:

<view wx:if="{{length > 5}}"> 1 </view>
<view wx:elif="{{length > 2}}"> 2 </view>
<view wx:else> 3 </view>

block wx:if

因为wx:if是一个控制属性,需要将它添加到一个标签上。但是如果我们想一次性判断多个组件标签,我们可以使用一个<block/>标签将多个组件包装起来,并在上边使用wx:if控制属性。

<block wx:if="{{true}}">
  <view> view1 </view>
  <view> view2 </view>
</block>

注意:<block/>并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。

实例:

wxml:使用view

<!--index.wxml-->
<button bindtap="EventHandle">按钮</button>
<!-- wx:if -->
<view wx:if="{{boolean==true}}">
    <view class="bg_black"></view>
</view>
 <view wx:elif="{{boolean==false}}">
    <view class="bg_red"></view>
</view>

wxss:

/**index.wxss**/
.bg_black {
  height: 200rpx;
  background: lightskyblue;
}

.bg_red {
  height: 200rpx;
  background: lightpink;
}

js:

// index.js
 
Page({
  data: {
    boolean:false
  },
 
  EventHandle: function(){
    var bol = this.data.boolean;

    this.setData({
      boolean: !bol
     })
  } 
})
wx:ifvshidden

因为wx:if之中的模板也可能包含数据绑定,所以当wx:if的条件值切换时,框架有一个局部渲染的过程,因为它会确保条件块在切换时销毁或重新渲染。

同时wx:if也是惰性的,如果在初始渲染条件为false,框架什么也不做,在条件第一次变成真的时候才开始局部渲染。

相比之下,hidden就简单的多,组件始终会被渲染,只是简单的控制显示与隐藏。

一般来说,wx:if有更高的切换消耗而hidden有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用hidden更好,如果在运行时条件不大可能改变则wx:if较好。

微信小程序 模板(template)

模板


WXML提供模板(template),可以在模板中定义代码片段,然后在不同的地方调用。

定义模板


使用name属性,作为模板的名字。然后在<template/>内定义代码片段,如:

<!--
  index: int
  msg: string
  time: string
-->
<template name="msgItem">
  <view>
    <text> {{index}}: {{msg}} </text>
    <text> Time: {{time}} </text>
  </view>
</template>

使用模板


使用is属性,声明需要的使用的模板,然后将模板所需要的data传入,如:

<template is="msgItem" data="{{...item}}"/>
Page({
  data: {
    item: {
      index: 0,
      msg: 'this is a template',
      time: '2016-09-15'
    }
  }
})

is属性可以使用Mustache语法,来动态决定具体需要渲染哪个模板:

<template name="odd">
  <view> odd </view>
</template>
<template name="even">
  <view> even </view>
</template>

<block wx:for="{{[1, 2, 3, 4, 5]}}">
    <template is="{{item % 2 == 0 ? 'even' : 'odd'}}"/>
</block>

模板的作用域

模板拥有自己的作用域,只能使用data传入的数据。

微信小程序 事件

什么是事件


  • 事件是视图层到逻辑层的通讯方式。
  • 事件可以将用户的行为反馈到逻辑层进行处理。
  • 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。
  • 事件对象可以携带额外信息,如id, dataset, touches。

事件的使用方式


  • 在组件中绑定一个事件处理函数。

bindtap,当用户点击该组件的时候会在该页面对应的Page中找到相应的事件处理函数。

<view id="tapTest" data-hi="WeChat" bindtap="tapName"> Click me! </view>
  • 在相应的Page定义中写上相应的事件处理函数,参数是event。
Page({
  tapName: function(event) {
    console.log(event)
  }
})
  • 可以看到log出来的信息大致如下
    {
    "type": "tap",
    "timeStamp":895,
    "target": {
      "id": "tapTest",
      "dataset": {
       "hi": "WeChat"
      }
    },
    "currentTarget": {
      "id": "tapTest",
      "dataset": {
        "hi": "WeChat"
      }
    },
    "detail": {
      "x":53,
      "y":14
    },
    "touches": [{
      "identifier":0,
      "pageX":53,
      "pageY":14,
      "clientX":53,
      "clientY":14,
    }],
    "changedTouches": [{
      "identifier":0,
      "pageX":53,
      "pageY":14,
      "clientX":53,
      "clientY":14,
    }],
    }

事件详解

事件分类

事件分为冒泡事件和非冒泡事件

  1. 冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。
  2. 非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。

WXML的冒泡事件列表:

类型触发条件
touchstart 手指触摸动作开始
touchmove 手指触摸后移动
touchcancel 手指触摸动作被打断,如来电提醒,弹窗
touchend 手指触摸动作结束
tap 手指触摸后马上离开
longtap 手指触摸后,超过350ms再离开

注:除上表之外的其他组件自定义事件都是非冒泡事件,如<form/>submit事件,<input/>input事件,<scroll-view/>scroll事件,(详见各个组件)

事件绑定


事件绑定的写法同组件的属性,以key、value的形式。

  • key以bindcatch开头,然后跟上事件的类型,如bindtapcatchtouchstart
  • value是一个字符串,需要在对应的Page中定义同名的函数。不然当触发事件的时候会报错。

bind事件绑定不会阻止冒泡事件向上冒泡,catch事件绑定可以阻止冒泡事件向上冒泡。

如在下边这个例子中,点击inner view会先后触发handleTap3handleTap2(因为tap事件会冒泡到middle view,而middle view阻止了tap事件冒泡,不再向父节点传递),点击middle view会触发handleTap2,点击outter view会触发handleTap1

<view id="outter" bindtap="handleTap1">
  outer view
  <view id="middle" catchtap="handleTap2">
    middle view
    <view id="inner" bindtap="handleTap3">
      inner view
    </view>
  </view>
</view>

事件对象


如无特殊说明,当组件触发事件时,逻辑层绑定该事件的处理函数会收到一个事件对象。

BaseEvent基础事件对象属性列表:

属性类型说明
type String 事件类型
timeStamp Integer 事件生成时的时间戳
target Object 触发事件的组件的一些属性值集合
currentTarget Object 当前组件的一些属性值集合

CustomEvent 自定义事件对象属性列表(继承 BaseEvent):

属性类型说明
detail Object 额外的信息

TouchEvent 触摸事件对象属性列表(继承 BaseEvent):

属性类型说明
touches Array 触摸事件,当前停留在屏幕中的触摸点信息的数组
changedTouches Array 触摸事件,当前变化的触摸点信息的数组

特殊事件:<canvas/>中的触摸事件不可冒泡,所以没有 currentTarget。

type

通用事件类型

timeStamp

该页面打开到触发事件所经过的毫秒数。

target

触发事件的源组件。

属性类型说明
id String 事件源组件的id
tagName String 当前组件的类型
dataset Object 事件源组件上由data-开头的自定义属性组成的集合

currentTarget

事件绑定的当前组件。

属性类型说明
id String 当前组件的id
tagName String 当前组件的类型
dataset Object 当前组件上由data-开头的自定义属性组成的集合

说明: target 和 currentTarget 可以参考上例中,点击 inner view 时,handleTap3 收到的事件对象 target 和 currentTarget 都是 inner,而 handleTap2 收到的事件对象 target 就是 inner,currentTarget 就是 middle。

 

dataset

在组件中可以定义数据,这些数据将会通过事件传递给 SERVICE。书写方式:以data-开头,多个单词由连字符-链接,不能有大写(大写会自动转成小写)如data-element-type,最终在 event.target.dataset 中会将连字符转成驼峰elementType

示例:

<view data-alpha-beta="1" data-alphaBeta="2" bindtap="bindViewTap"> DataSet Test </view>
Page({
  bindViewTap:function(event){
    event.target.dataset.alphaBeta === 1 // - 会转为驼峰写法
    event.target.dataset.alphabeta === 2 // 大写会转为小写
  }
})

touches

touches 是一个数组,每个元素为一个 Touch 对象(canvas 触摸事件中携带的 touches 是 CanvasTouch 数组)。 表示当前停留在屏幕上的触摸点。

Touch 对象

属性类型说明
identifier Number 触摸点的标识符
pageX, pageY Number 距离文档左上角的距离,文档的左上角为原点 ,横向为X轴,纵向为Y轴
clientX, clientY Number 距离页面可显示区域(屏幕除去导航条)左上角距离,横向为X轴,纵向为Y轴

CanvasTouch 对象

属性类型说明特殊说明
identifier Number 触摸点的标识符  
x, y Number 距离 Canvas 左上角的距离,Canvas 的左上角为原点 ,横向为X轴,纵向为Y轴  

changedTouches

changedTouches 数据格式同 touches。表示有变化的触摸点,如从无变有(touchstart),位置变化(touchmove),从有变无(touchend、touchcancel)。

detail

自定义事件所携带的数据,如表单组件的提交事件会携带用户的输入,媒体的错误事件会携带错误信息,详见组件定义中各个事件的定义。

点击事件的detail 带有的 x, y 同 pageX, pageY 代表距离文档左上角的距离。

微信小程序 WXML提供了import和include引用方式

引用

WXML提供两种文件引用方式importinclude

import

import可以在该文件中使用目标文件定义的template,如:

在item.wxml中定义了一个叫itemtemplate

<!-- item.wxml -->
<template name="item">
  <text>{{text}}</text>
</template>

在index.wxml中引用了item.wxml,就可以使用item模板:

<import src="item.wxml"/>
<template is="item" data="{{text: 'forbar'}}"/>

import的作用域


import有作用域的概念,即只会import目标文件中定义的template,而不会import目标文件import的template。

如:C import B,B import A,在C中可以使用B定义的template,在B中可以使用A定义的template,但是C不能使用A定义的template

<!-- A.wxml -->
<template name="A">
  <text> A template </text>
</template>
<!-- B.wxml -->
<import src="a.wxml"/>
<template name="B">
  <text> B template </text>
</template>
<!-- C.wxml -->
<import src="b.wxml"/>
<template is="A"/>  <!-- Error! Can not use tempalte when not import A. -->
<template is="B"/>

include

include可以将目标文件除了<template/>的整个代码引入,相当于是拷贝到include位置,如:

<!-- index.wxml -->
<include src="header.wxml"/>
<view> body </view>
<include src="footer.wxml"/>
<!-- header.wxml -->
<view> header </view>
<!-- footer.wxml -->
<view> footer </view>

微信小程序 WXS模块

 

WXS 模块

WXS 代码可以编写在 wxml 文件中的<wxs> 标签内,或以 .wxs 为后缀名的文件内。

模块

每一个 .wxs 文件和 <wxs> 标签都是一个单独的模块。

每个模块都有自己独立的作用域。即在一个模块里面定义的变量与函数,默认为私有的,对其他模块不可见。

一个模块要想对外暴露其内部的私有变量与函数,只能通过 module.exports 实现。

.wxs 文件

在微信开发者工具里面,右键可以直接创建 .wxs 文件,在其中直接编写 WXS 脚本。

示例代码:

// /pages/comm.wxs

var foo = "'hello world' from comm.wxs"; var bar = function(d) { return d; } module.exports = { foo: foo, bar: bar };

上述例子在 /pages/comm.wxs 的文件里面编写了 WXS 代码。该 .wxs 文件可以被其他的 .wxs 文件 或 WXML 中的 <wxs> 标签引用。

module 对象

每个 wxs 模块均有一个内置的 module 对象。

属性

  • exports: 通过该属性,可以对外共享本模块的私有变量与函数。

示例代码:

// /pages/tools.wxs

var foo = "'hello world' from tools.wxs"; var bar = function (d) { return d; } module.exports = { FOO: foo, bar: bar, }; module.exports.msg = "some msg";

{{tools.msg}}

{{tools.bar(tools.FOO)}}

页面输出:

some msg
'hello world' from tools.wxs

require 函数

在.wxs模块中引用其他 wxs 文件模块,可以使用 require 函数。

引用的时候,要注意如下几点:

  • 只能引用 .wxs 文件模块,且必须使用相对路径。
  • wxs 模块均为单例,wxs 模块在第一次被引用时,会自动初始化为单例对象。多个页面,多个地方,多次引用,使用的都是同一个 wxs 模块对象。
  • 如果一个 wxs 模块在定义之后,一直没有被引用,则该模块不会被解析与运行。

示例代码:

// /pages/tools.wxs

var foo = "'hello world' from tools.wxs"; var bar = function (d) { return d; } module.exports = { FOO: foo, bar: bar, }; module.exports.msg = "some msg";

// /pages/logic.wxs

var tools = require("./tools.wxs");

console.log(tools.FOO); console.log(tools.bar("logic.wxs")); console.log(tools.msg);


控制台输出:

'hello world' from tools.wxs
logic.wxs
some msg

标签

属性名类型默认值说明
module String   当前<wxs>标签的模块名。必填字段。
src String   引用 .wxs 文件的相对路径。仅当本标签为单闭合标签标签的内容为空时有效。

module 属性

module 属性是当前<wxs>标签的模块名。在单个 wxml 文件内,建议其值唯一。有重复模块名则按照先后顺序覆盖(后者覆盖前者)。不同文件之间的 wxs 模块名不会相互覆盖。

module 属性值的命名必须符合下面两个规则:

  • 首字符必须是:字母(a-zA-Z),下划线(_
  • 剩余字符可以是:字母(a-zA-Z),下划线(_), 数字(0-9)

示例代码:

<!--wxml--> 

<wxs module="foo">

var some_msg = "hello world"; module.exports = { msg : some_msg, }

</wxs>

<view> {{foo.msg}} </view>

页面输出:

hello world

上面例子声明了一个名字为 foo 的模块,将 some_msg 变量暴露出来,供当前页面使用。

src 属性

src 属性可以用来引用其他的 wxs 文件模块。

引用的时候,要注意如下几点:

  • 只能引用 .wxs 文件模块,且必须使用相对路径。
  • wxs 模块均为单例,wxs 模块在第一次被引用时,会自动初始化为单例对象。多个页面,多个地方,多次引用,使用的都是同一个 wxs 模块对象。
  • 如果一个 wxs 模块在定义之后,一直没有被引用,则该模块不会被解析与运行。

示例代码:

// /pages/index/index.js

Page({ data: { msg: "'hello world' from js", } })

<!-- 也可以直接使用单标签闭合的写法

-->

{{some_comms.bar(some_comms.foo)}}

{{some_comms.bar(msg)}}

页面输出:

'hello world' from comm.wxs
'hello wrold' from js

上述例子在文件 /page/index/index.wxml 中通过 标签引用了 /page/comm.wxs 模块。

注意

  • <wxs>模块只能在定义模块的 WXML 文件中被访问到。使用<include> 或<import> 时, <wxs>模块不会被引入到对应的 WXML 文件中。
  • 标签中,只能使用定义该 的 WXML 文件中定义的 模块。

微信小程序 变量

概念

  • WXS 中的变量均为值的引用。
  • 没有声明的变量直接赋值使用,会被定义为全局变量。
  • 如果只声明变量而不赋值,则默认值为 undefined。
  • var表现与javascript一致,会有变量提升。
var foo = 1;
var bar = "hello world";
var i; // i === undefined

上面代码,分别声明了 foo、 bar、 i 三个变量。然后,foo 赋值为数值 1 ,bar 赋值为字符串 "hello wolrd"。

变量名

变量命名必须符合下面两个规则:

  • 首字符必须是:字母(a-zA-Z),下划线(_)
  • 剩余字符可以是:字母(a-zA-Z),下划线(_), 数字(0-9)

保留标识符

以下标识符不能作为变量名:

delete 
void 
typeof

null 
undefined 
NaN 
Infinity 
var

if 
else 

true 
false

require

this 
function 
arguments
return

for
while
do
break
continue
switch
case
default

微信小程序 语句

if 语句

在 WXS 中,可以使用以下格式的 if 语句 :

  • if (expression) statement : 当 expression 为 truthy 时,执行 statement。
  • if (expression) statement1 else statement2 : 当 expression 为 truthy 时,执行 statement1。 否则,执行 statement2
  • if ... else if ... else statementN 通过该句型,可以在 statement1 ~ statementN 之间选其中一个执行。

示例语法:

// if ...

if (表达式) 语句;

if (表达式) 
  语句;

if (表达式) {
  代码块;
}


// if ... else 

if (表达式) 语句;
else 语句;

if (表达式) 
  语句;
else 
  语句;

if (表达式) {
  代码块;
} else {
  代码块;
}

// if ... else if ... else ...

if (表达式) {
  代码块;
} else if (表达式) {
  代码块;
} else if (表达式) {
  代码块;
} else {
  代码块;
}

switch 语句

示例语法:

switch (表达式) {
  case 变量:
    语句;
  case 数字:
    语句;
    break;
  case 字符串:
    语句;
  default:
    语句;
}
  • default 分支可以省略不写。
  • case 关键词后面只能使用:变量,数字,字符串。

示例代码:

var exp = 10;

switch ( exp ) {
case "10":
  console.log("string 10");
  break;
case 10:
  console.log("number 10");
  break;
case exp:
  console.log("var exp");
  break;
default:
  console.log("default");
}

输出:

number 10

for 语句

示例语法:

for (语句; 语句; 语句)
  语句;

for (语句; 语句; 语句) {
  代码块;
}
  • 支持使用 break,continue 关键词。

示例代码:

for (var i = 0; i < 3; ++i) {
  console.log(i);
  if( i >= 1) break;
}

输出:

0
1

while 语句

示例语法:

while (表达式)
  语句;

while (表达式){
  代码块;
}

do {
  代码块;
} while (表达式)
  • 当表达式为 true 时,循环执行语句或代码块。
  • 支持使用 break,continue 关键词。

微信小程序 数据类型

数据类型

WXS 语言目前共有以下几种数据类型:

  • number : 数值
  • string :字符串
  • boolean:布尔值
  • object:对象
  • function:函数
  • array : 数组
  • date:日期
  • regexp:正则

微信小程序 基础类库

console

console.log 方法用于在 console 窗口输出信息。它可以接受多个参数,将它们的结果连接起来输出。

Math

JSON

方法

  • stringify(object): 将 object 对象转换为 JSON 字符串,并返回该字符串。
  • parse(string): 将 JSON 字符串转化成对象,并返回该对象。

Number

属性

  • MAX_VALUE
  • MIN_VALUE
  • NEGATIVE_INFINITY
  • POSITIVE_INFINITY
以上属性的具体使用请参考 ES5 标准。

Date

属性

  • parse
  • UTC
  • now
以上属性的具体使用请参考 ES5 标准。

Global

属性

  • NaN
  • Infinity
  • undefined
以上属性的具体使用请参考 ES5 标准。

方法

  • parseInt
  • parseFloat
  • isNaN
  • isFinite
  • decodeURI
  • decodeURIComponent
  • encodeURI
  • encodeURIComponent

微信小程序 WXSS

WXSS

WXSS(WeiXin Style Sheets)是一套样式语言,用于描述WXML的组件样式。

WXSS用来决定WXML的组件应该怎么显示。

为了适应广大的前端开发者,我们的WXSS具有CSS大部分特性。同时为了更适合开发微信小程序,我们对CSS进行了扩充以及修改。

与css相比我们扩展的特性有:

尺寸单位

  • rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在iPhone6上,屏幕宽度为375px,共有750个物理像素,则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

建议:开发微信小程序时设计师可以用iPhone6作为视觉稿的标准。

注意: 在较小的屏幕上不可避免的会有一些毛刺,请在开发时尽量避免这种情况。

样式导入

使用@import语句可以导入外联样式表,@import跟需要导入的外联样式表的相对路径,用;表示语句结束。

示例代码:

/** common.wxss **/
.small-p{
  padding:5px;
}
/** app.wxss **/
@import "common.wxss";
.middle-p {
  padding:15px;
}

内联样式

框架组件上支持使用style、class属性来控制组件的样式。

  • style:静态的样式统一写到class中。style接收动态的样式,在运行时会进行解析,请尽量避免将静态的样式写进style中,以免影响渲染速度。
<view style="color:{{color}};" />
  • class:用于指定样式规则,其属性值是样式规则中类选择器名(样式类名)的集合,样式类名不需要带上.,样式类名之间用空格分隔。
<view class="normal_view" />

选择器

目前支持的选择器有:

选择器样例样例描述
.class .intro 选择所有拥有class="intro"的组件
#id #firstname 选择拥有id="firstname"的组件
element view 选择所有view组件
element, element view checkbox 选择所有文档的view组件和所有的checkbox组件
::after view::after 在view组件后边插入内容
::before view::before 在view组件前边插入内容

全局样式与局部样式

定义在app.wxss中的样式为全局样式,作用于每一个页面。在page的wxss文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖app.wxss中相同的选择器。

简易双向绑定

2020-08-14 16:18 更新
基础库 2.9.3 开始支持,低版本需做兼容处理

双向绑定语法

在 WXML 中,普通的属性的绑定是单向的。例如:

<input value="{{value}}" />

如果使用 ​this.setData({ value: 'leaf' })​ 来更新 ​value​ ,​this.data.value​ 和输入框的中显示的值都会被更新为 leaf ;但如果用户修改了输入框里的值,却不会同时改变 ​this.data.value​ 。

如果需要在用户输入的同时改变 ​this.data.value​ ,需要借助简易双向绑定机制。此时,可以在对应项目之前加入 ​model​: 前缀:

<input model:value="{{value}}" />

这样,如果输入框的值被改变了, ​this.data.value​ 也会同时改变。同时, WXML 中所有绑定了 ​value​ 的位置也会被一同更新, 数据监听器 也会被正常触发。

用于双向绑定的表达式有如下限制:

    1. 只能是一个单一字段的绑定,如
<input model:value="值为 {{value}}" />
<input model:value="{{ a + b }}" />

都是非法的;

  1. 目前,尚不能 data 路径,如

    <input model:value="{{ a.b }}" />
    

    这样的表达式目前暂不支持。

在自定义组件中传递双向绑定

双向绑定同样可以使用在自定义组件上。如下的自定义组件:

// custom-component.js
Component({
  properties: {
    myValue: String
  }
})
<!-- custom-component.wxml -->
<input model:value="{{myValue}}" />

这个自定义组件将自身的 ​myValue​ 属性双向绑定到了组件内输入框的 ​value​ 属性上。这样,如果页面这样使用这个组件:

<custom-component model:my-value="{{pageValue}}" />

当输入框的值变更时,自定义组件的 ​myValue​ 属性会同时变更,这样,页面的 ​this.data.pageValue​ 也会同时变更,页面 WXML 中所有绑定了 ​pageValue​ 的位置也会被一同更新。

在自定义组件中触发双向绑定更新

自定义组件还可以自己触发双向绑定更新,做法就是:使用 setData 设置自身的属性。例如:

// custom-component.js
Component({
  properties: {
    myValue: String
  },
  methods: {
    update: function() {
      // 更新 myValue
      this.setData({
        myValue: 'leaf'
      })
    }
  }
})

如果页面这样使用这个组件:

<custom-component model:my-value="{{pageValue}}" />

当组件使用 ​setData​ 更新 ​myValue​ 时,页面的 ​this.data.pageValue​ 也会同时变更,页面 WXML 中所有绑定了 ​pageValue​ 的位置也会被一同更新。

微信小程序 性能Trace工具

2018-07-20 11:48 更新

微信 Andoid 6.5.10 开始,我们提供了 Trace 导出工具,开发者可以在开发者工具 Trace Panel 中使用该功能。

使用方法

  1. PC 上需要先安装adb工具,可以参考一些主流教程进行安装,Mac 上可使用 brew 直接安装。
  2. 确定adb工具已成功安装后,在开发者工具上打开 Trace Panel,将 Android 手机通过 USB 连接上 PC,点击「Choose Devices」,此时手机上可能弹出连接授权框,请点击「允许」。
  3. 选择设备后,在手机上打开你需要调试的开发版小程序,通过右上角菜单,打开性能监控面板,重启小程序;
  4. 重启后,在小程序上进行操作,完成操作后,通过右上角菜单,导出 Trace 数据;
  5. 此时开发者工具 Trace Panel 上会自动拉取 Trace 文件,选择你要分析的 Trace 文件即可;

可以通过adb devices命令确定设备是否已和 PC 建立起连接

image

性能面板

从微信 6.5.8 开始,我们提供了性能面板让开发者了解小程序的性能。开发者可以在开发版小程序下打开性能面板,打开方法:进入开发版小程序,进入右上角更多按钮,点击「显示性能窗口」。

image

性能面板指标说明

指标说明
CPU 小程序进程的 CPU 占用率,仅 Android 下提供
内存 小程序进程的内存占用(Total Pss),仅 Android 下提供
启动耗时 小程序启动总耗时
下载耗时 小程序包下载耗时,首次打开或资源包需更新时会进行下载
页面切换耗时 小程序页面切换的耗时
帧率/FPS  
首次渲染耗时 页面次首次渲染的耗时
再次渲染耗时 页面再次渲染的耗时(通常由开发者的 setData 操作触发)
数据缓存 小程序通过 Storage 接口储存的缓存大小

兼容

2020-08-31 17:56 更新

小程序的功能不断的增加,但是旧版本的微信客户端并不支持新功能,所以在使用这些新能力的时候需要做兼容。

文档会在组件,API等页面描述中带上各个功能所支持的版本号。

可以通过wx.getSystemInfo或者wx.getSystemInfoSync获取到小程序的基础库版本号。

也可以通过wx.canIUse 详情 来判断是否可以在该基础库版本下直接使用对应的API或者组件

兼容方式 - 接口

对于新增的 API,可以用以下代码来判断是否支持用户的手机。

if (wx.openBluetoothAdapter) {
  wx.openBluetoothAdapter()
} else {
  // 如果希望用户在最新版本的客户端上体验您的小程序,可以这样子提示
  wx.showModal({
    title: '提示',
    content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。'
  })
}

兼容方式 - 参数

对于 API 的参数或者返回值有新增的参数,可以判断用以下代码判断。

wx.showModal({
  success: function(res) {
    if (wx.canIUse('showModal.cancel')) {
      console.log(res.cancel)
    }
  }
})

兼容方式 - 组件

对于组件,新增的属性在旧版本上不会被处理,不过也不会报错。如果特殊场景需要对旧版本做一些降级处理,可以这样子做。

Page({
  data: {
    canIUse: wx.canIUse('button.open-type.contact')
  }
})
<button wx:if="{{canIUse}}" open-type="contact"> 客服消息 </button>
<contact-button wx:else></contact-button>

 

 

posted @ 2022-03-27 21:36  hanease  阅读(219)  评论(0编辑  收藏  举报