小程序的事件处理
<swiper bindchange="当轮播图切换页面时触发该事件"></swiper>
<scroll-view bindscrolltoupper="滚到顶触发"
bindscrolltolower="滚到底触发"></scroll-view>
<input bindinput="" />
<image bindtap=""></image>
<picker bindchange=""></picker>
.................
很多事件类型匹配相应的组件。
小程序的事件类型主要分为2类:
- 冒泡事件 组件触发该事件后,该事件将会向父节点传递。
- 非冒泡事件 组件触发该事件后,该事件不会向父节点传递。
WXML的冒泡事件列表:
类型 | 触发条件 |
---|---|
touchstart | 手指触摸动作开始 |
touchmove | 手指触摸后移动 |
touchcancel | 手指触摸动作被打断,如来电提醒,弹窗 |
touchend | 手指触摸动作结束 |
tap | 手指触摸后马上离开 |
longpress | 手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发 |
注:除上表之外的其他组件自定义事件如无特殊声明都是非冒泡事件,如 form 的submit事件,input 的input事件,scroll-view 的scroll事件,(详见各个组件)
案例:pages/event/event
为组件绑定事件的方式
<view bindtap="tapview"></view>
<view bind:tap="tapview"></view>
<view catchtap="tapview"></view>
使用bind事件类名
方式或catch事件类名
方式都可以为组件绑定事件,不一样的是catch
方式将会自动阻止事件冒泡。
bind:事件类名
也可以为组件绑定事件,所不同的是,bind可以为所有组件绑定事件,而bind:
方式不能用于部分原生组件。
原生组件:
原生组件指的是由android、ios操作系统直接控制的组件,而不是小程序自定义设计的组件。原生组件与操作系统底层直接打交道,不会被小程序过多干预。
比如:video组件、camera组件、input组件等。
小程序中事件触发后的传参方案
<image bindtap="tapImage"></image>
点击图片,触发tap
事件,执行tapImage
方法。
注意:绑定tap
事件时,事件处理函数名:tapImage
严禁出现小括号。 这样就会出现一个问题,小程序触发tap事件后,如何给tapImage
方法传递自定义参数?
需求:
<view>
臭豆腐 2 5.0 <button bindtap="del" data-i="0">删除</button>
</view>
<view>
螺蛳粉 2 5.0 <button bindtap="del" data-i="1">删除</button>
</view>
<view>
臭鳜鱼 2 5.0 <button bindtap="del" data-i="2" data-a=''>删除</button>
</view>
del(event){
let i = event.target.dataset.i
console.log(i) // 获取点击的按钮上绑定的data-i属性值
}
对于非冒泡事件,一般都是小程序官方自定义事件,这种事件触发后所涉及到的参数一般都被组件封装到了detail属性中,所以直接使用 event.detail
就可以访问到:
<input bindinput="handleInput" />
<switch bindchange="handleChange"></switch>
<scroll-view bindscroll="handleScroll"></scroll-view>
<swiper bindchange="changeSwiper"></swiper>
handleInput(event){
event.detail.value
}
handleChange(event){
event.detail.value
}
handleScroll(event){
event.detail
}
changeSwiper(event){
event.detail
}
案例:吃饭睡觉打豆豆。
小程序常用API
小程序界面交互类API
小程序路由跳转类API
(编程式跳转)
- wx.switchTab 跳转到tabbar页面,这样将会销毁所有非
tabbar
页面。 - wx.reLaunch 重新启动小程序,打开某一个页面。
- wx.redirectTo 销毁当前页,跳转到目标非
tabbar
页面。 - wx.navigateTo 保留跳转,保留当前页,跳转到非
tabbar
页面。 - [wx.navigateBack](https://developers.weixin.qq.com/miniprogram/dev/api/route/ wx.navigateBack.html) 销毁当前页从而回到上一页、上n页。
小程序两个页面跳转过程中的参数传递方案
小程序页面设计中,从页面A跳转到页面B的过程中将涉及到相关的参数传递。参数传递场景有两类:
-
正向传参
A页面跳转到B页面,顺便带点参数给B页面,在B页面接收。
A页面中传参:
wx.navigateTo({ url:'/pages/b/b?name=张三&pwd=1234&age=15' })
B页面中接收:
//在B页面的js文件中: Page({ onLoad(option){ // 小程序传递的option对象封装了上一个页面传过来的参数 option.name option.pwd option.age } })
-
反向传参
A页面跳转到B页面,在B页面中操作时,将一些数据回传给A。
A页面在跳转的过程中,通过events声明一个函数,接收B回传的数据:
wx.navigateTo({ url: 'b', events: { acceptData: (data)=>{ // 当B回传数据后,执行该方法,data就是回传回来的数据 } } })
B页面中,找准合适的时机,当需要会出参数给A页面时,需要如下代码:
let ec = this.getOpenerEventChannel() // 事件通道,用于与A通信 ec.emit('acceptData', '参数信息') // 通过A页面,执行acceptData,传参
实现选择城市业务。
小程序的生命周期
搞清楚每一个组件生命周期的过程。
搞清楚每一个生命周期钩子方法执行的时机。
搞清楚每一个生命周期钩子方法执行的先后顺序与执行次数。
未来使用时,找准生命周期方法,在合适的位置写代码就行了。
小程序页面的生命周期
定义了小程序中一个普通页面,从生到死所经过的生命周期钩子方法。
/** 生命周期函数--监听页面加载 执行一次 */
onLoad(options) {
},
/** 生命周期函数--监听页面初次渲染完成 执行一次 */
onReady() {
},
/** 生命周期函数--监听页面显示 执行多次 */
onShow() {
},
/** 生命周期函数--监听页面隐藏 执行多次 */
onHide() {
},
/** 生命周期函数--监听页面卸载 执行一次 */
onUnload() {
},
小程序应用的生命周期
整个微信小程序,从应用启动到应用关停也会涉及到应用全局的生命周期,其中有关的生命周期钩子方法在app.js
中进行声明:
// app.js
// 当前文件将会在小程序初次启动时加载,仅加载一次
// 在该js文件中可以定义应用全局的生命周期
App({
/** 生命周期回调—监听小程序初始化
小程序初始化完成时触发,全局只触发一次。 */
onLaunch(){
console.log('App onLaunch...')
},
/** 生命周期回调—监听小程序显示
小程序启动,或从后台进入前台显示时 */
onShow(){
let t = new Date().getTime()
console.log('App onShow...'+t)
let delta = t - this.globalData.time
if(this.globalData.time!=0 && delta > 5000) {
console.log('您已经离开了5秒钟,请重新登录...')
}
},
/** 生命周期回调—监听小程序隐藏
* 小程序从前台进入后台时 */
onHide(){
let t = new Date().getTime()
console.log('App onHide...' + t)
// 将隐藏app时的时间戳存入globalData.time
this.globalData.time = t
},
/** 在App.js中声明globalData用于存储全局共享的数据 */
globalData : {
time : 0,
cityname: '北京',
username: '张三',
}
})
app.js
中推荐声明一个globalData
属性用于存储全局共享数据,由于小程序全局app.js仅加载一次,所以App
对象也属于全局单例。所有页面都可以通过一些API
拿到App对象从而共享globalData
中的数据。例如:
// app.js
App({
globalData: {
name: 'zhangsan',
......
}
})
在页面中如果希望访问该globalData
数据,如下:
//a.js
Page({
onLoad(){
// getApp()方法将会返回全局唯一的App对象
let name = getApp().globalData.name
}
})
基于生命周期与App.globalData
实现反向传参
- 从A页面跳转到B页面。
- 在B页面中,将数据存入
App.globalData
,返回A页面。 - 在A页面中,重写
onShow
方法,从App.globalData
中获取存储的数据从而完成反向传参。
小程序中的网络通信
测试连接: https://api.tedu.cn/index.php?cid=1
修改DNS
为:114.114.114.114
- 电脑右下角,右键网络,打开网络设置。
- 更改适配器选项。
- 右键当前正在使用的网络:选择属性。
- 双击列表中:Internet 协议版本4.
- 修改
DNS
服务器地址:114.114.114.114
。 - 确定。
小程序中的网络通信相关API
wx.request({
url: '请求地址',
method: '请求方式 GET|POST等',
header: {}, // 设置请求消息头
data: {}, // 传递请求参数
success: (res)=>{....},
fail: (err)=>{....},
complete: (res)=>{....}
})
案例:发请求,访问接口。pages/req/req
。
https://api.tedu.cn 不在以下 request 合法域名列表中,请参考文档:https://developers.weixin.qq.com/miniprogram/dev/framework/ability/network.html
小程序开发者工具只允许向合法的域名发送https
请求。合法的域名需要在小程序后台管理网站 — 开发 — 开发管理 — 开发设置 — 服务器域名的位置 来进行域名配置。
https://wx.mp.qq.com
扫码登录即可。
当合法域名配置完毕后,打开开发工具,点击右上角:详情、项目配置,刷新合法域名列表即可看到配置的域名信息。(如果依然不在合法域名列表中,重启开发工具即可)
在小程序/小游戏中使用网络相关的 API
时,需要注意下列问题,请开发者提前了解。
1. 服务器域名配置
每个微信小程序需要事先设置通讯域名,小程序只可以跟指定的域名进行网络通信。包括普通 HTTPS 请求(wx.request)、上传文件(wx.uploadFile)、下载文件(wx.downloadFile) 和 WebSocket 通信(wx.connectSocket)。
2. 配置流程
服务器域名请在 「小程序后台 - 开发 - 开发设置 - 服务器域名」 中进行配置,配置时需要注意:
- 域名只支持
https
(wx.request、wx.uploadFile、wx.downloadFile) 和wss
(wx.connectSocket) 协议; - 域名不能使用 IP 地址(小程序的局域网 IP 除外)或 localhost;
- 可以配置端口,如 https://myserver.com:8080,但是配置后只能向 https://myserver.com:8080 发起请求。如果向 https://myserver.com、https://myserver.com:9091 等 URL 请求则会失败。
- 如果不配置端口。如 https://myserver.com,那么请求的 URL 中也不能包含端口,甚至是默认的 443 端口也不可以。如果向 https://myserver.com:443 请求则会失败。
- 域名必须经过
ICP
备案; - 出于安全考虑,api.weixin.qq.com 不能被配置为服务器域名,相关 API 也不能在小程序内调用。 开发者应将 AppSecret 保存到后台服务器中,通过服务器使用
getAccessToken
接口获取access_token
,并调用相关 API; - 不支持配置父域名,使用子域名。