页面事件
页面怎么打开、关掉见 页面生命周期。本章是页面已经显示之后:滚动、轻触、滑动,以及点按钮去执行脚本。下拉刷新见 下拉刷新。
点按已经拆开,不要用一个事件包打天下:
| 手势 | 页面空白 | 组件上(按钮、卡片等) |
|---|---|---|
| 轻触一次 | Page.onTap | JSON 写 onTap |
| 连续轻触两次 | Page.onDoubleTap | onDoubleTap |
| 按住不放 | Page.onLongPress | onLongPress |
| 快滑 | onSwipeUp / Down / Left / Right,或统一 onSwipe | — |
组件上写了对应 JSON,空白处的页面事件不会再收到(点到按钮就只走按钮)。
Page({}) 里未声明的不会调用。onScroll 较频繁,只打到控制台。同时写了轻触和双击时,系统要等一小会儿才能区分,轻触会略慢。
Page({
onTap() {},
onDoubleTap() {},
onLongPress() {},
onSwipeUp() {},
onSwipe(e) {}
});{
"title": {
"text": "页面事件",
"fontSize": 18,
"color": "#FFFFFF",
"background": "#006A65"
},
"style": {
"background": "#F5F5F5",
"padding": 12
},
"body": [
{
"type": "notice",
"text": "点空白走页面 onTap / onDoubleTap / onLongPress。点按钮走组件自己的事件,不会混到页面空白上。"
},
{
"type": "text",
"text": "调用记录",
"style": {
"fontWeight": "bold"
}
},
{
"type": "list",
"bind": "logs",
"item": {
"type": "notice",
"text": "{{item.text}}"
}
},
{
"type": "row",
"style": {
"gap": 8
},
"children": [
{
"type": "button",
"text": "轻触",
"onTap": "onBtnTap"
},
{
"type": "button",
"text": "双击",
"onDoubleTap": "onBtnDoubleTap"
},
{
"type": "button",
"text": "长按",
"onLongPress": "onBtnLongPress"
}
]
},
{
"type": "notice",
"text": "下滑到底会 onReachBottom,再滑回顶部会 onReachTop。onScroll 只打到控制台。"
},
{
"type": "space",
"height": 120
},
{
"type": "text",
"text": "占位,方便滚动"
},
{
"type": "space",
"height": 120
},
{
"type": "text",
"text": "继续向下"
},
{
"type": "space",
"height": 160
}
]
}事件
| 时机 | 方法 |
|---|---|
| 页面滚动 | onScroll(e),e.scrollY / e.deltaY |
| 整页滚到底 | onReachBottom(e) |
| 整页滚到顶 | onReachTop(e) |
| 整页下拉刷新 | onPullDownRefresh(),见 下拉刷新 |
| 点空白 | onTap |
| 双击空白 | onDoubleTap |
| 长按空白 | onLongPress |
| 滑动 | onSwipeUp / onSwipeDown / onSwipeLeft / onSwipeRight / onSwipe |
组件上也可以写这些事件:按钮、卡片写 onTap,list / grid 可写 onScroll / onReachBottom / onReachTop,表单写 onChange,见 组件。
读写自定义组件用 this.selectComponent(id),组件通知父级用 this.triggerEvent,见 父页交互。
页面方法
Page({}) 上除了 setData / appendData,还可以直接调用下面这些。跳转、提示、打开链接与 JSON action 同名,见 页面跳转。
| 方法 | 作用 |
|---|---|
this.navigate(page|{ page, params }) | 打开另一页 |
this.redirect(page|{ page, params }) | 关掉当前二级页再打开 |
this.switchTab(page|{ page }) | 切底栏。已打开过的 Tab 保留数据和滚动,只再走 onShow |
this.back() | 关闭当前二级页 |
this.toast(text|{ text, duration }) | 短提示 |
this.openUrl(url) | 系统浏览器打开 |
this.setTitle(text|{ text, color, background }) | 改当前页标题栏 |
this.scrollTo(y|{ y, animated, top }) | 滚页面,y 与 onScroll.scrollY 一样是 px |
this.showPopup(id|showIf) / this.hidePopup(...) | 按弹层 id 或 showIf 显示隐藏 |
this.showLoading(text?) / this.hideLoading() | 盖一层加载,不必在 JSON 里放 loading 节点 |
this.stopPullDownRefresh() | 结束下拉刷新转圈,见 下拉刷新 |
this.setTabBar(items|{ items, ... }) | 创建底栏。无参数则恢复入口 bottomMenus |
this.setTabBarItem({ page, ... }) | 改某一项的角标、隐藏、文字、图标 |
this.setTabBarStyle({ ... }) | 改整栏文字色、图标色、背景、隐藏 |
字符串参数会同时当作 page / text / url / id。自定义组件里调用这些方法,走的是所在页面。
this.setTitle('已改标题');
this.setTitle({ text: '已改标题', color: '#FFFFFF', background: '#006A65' });
this.scrollTo(400);
this.scrollTo({ y: 0, animated: false });
this.scrollTo({ top: true });
this.showPopup('sheet');
this.hidePopup('open');
this.showLoading('加载中');
this.hideLoading();
this.stopPullDownRefresh();showPopup 会去页面 popups(以及 body 里的 type: popup)里找 id 或 showIf,再把对应字段写成 true。找不到就把参数当成数据路径。也可以继续 this.setData({ open: true })。
加载圈画在当前页最上层,和页面 JSON 里的 loading 组件不是同一个。列表触底转圈仍用 setData + showIf,见下面示例。
{
"title": {
"text": "页面方法",
"fontSize": 18,
"color": "#FFFFFF",
"background": "#006A65"
},
"style": {
"background": "#F5F5F5",
"padding": 12
},
"body": [
{
"type": "notice",
"text": "点按钮走 this.toast / setTitle / showPopup / showLoading / scrollTo。"
},
{
"type": "row",
"style": {
"gap": 8
},
"children": [
{
"type": "button",
"text": "提示",
"onTap": "sayHi"
},
{
"type": "button",
"text": "改标题",
"onTap": "retitle"
}
]
},
{
"type": "row",
"style": {
"gap": 8
},
"children": [
{
"type": "button",
"text": "弹层",
"onTap": "openSheet"
},
{
"type": "button",
"text": "加载",
"onTap": "busy"
}
]
},
{
"type": "row",
"style": {
"gap": 8
},
"children": [
{
"type": "button",
"text": "滚下去",
"onTap": "down"
},
{
"type": "button",
"text": "回顶部",
"onTap": "up"
}
]
},
{
"type": "space",
"height": 140
},
{
"type": "text",
"text": "占位,方便滚动"
},
{
"type": "space",
"height": 140
},
{
"type": "text",
"text": "继续向下"
},
{
"type": "space",
"height": 160
}
],
"popups": [
{
"id": "sheet",
"title": "弹层",
"showIf": "open",
"body": [
{
"type": "notice",
"text": "点关闭或遮罩即可。"
},
{
"type": "button",
"text": "关闭",
"onTap": "closeSheet"
}
]
}
]
}底部菜单
底栏的样子和入口写法见 底部菜单。二级页用 this.setTabBar({ items }) 创建一栏,this.setTabBar() 恢复默认。用 page(文件夹或 id)或 index(从 0 起)定位某一项。
setTabBar
| 参数 | 说明 |
|---|---|
| items | 菜单数组,字段与入口 bottomMenus 相同。不传则恢复默认 |
| 其余 | 与 setTabBarStyle 相同,创建时一并生效 |
this.setTabBar({
items: [
{ title: '首页', icon: 'img/home.svg', page: 'pages/home' },
{ title: '组件', icon: 'img/apps.svg', page: 'pages/components', badge: 3 }
]
});
this.setTabBar();setTabBarItem
| 参数 | 说明 |
|---|---|
| page / index | 改哪一项。page 可写 pages/stats 或 stats |
| badge | 角标数字或短文案。0、'' 表示去掉 |
| hidden | true 隐藏这一项,false 再显示 |
| title | 改文字 |
| icon / selectedIcon | 改图标路径 |
this.setTabBarItem({ page: 'msg', badge: 9 });
this.setTabBarItem({ page: 'msg', title: '私信' });
this.setTabBarItem({ page: 'msg', hidden: true });
this.setTabBarStyle({ color: '#C2410C', selectedColor: '#EA580C' });
this.setTabBarStyle({ iconColor: '#C2410C', selectedIconColor: '#EA580C' });
this.setTabBarStyle({ background: '#1A1A1A', borderColor: '#333333' });setTabBarStyle
| 参数 | 说明 |
|---|---|
| color | 未选中项的文字颜色。未单独写图标色时,图标也用这个 |
| selectedColor | 选中项的文字颜色。未单独写图标色时,图标也用这个 |
| iconColor | 未选中项的图标颜色。不写则跟 color |
| selectedIconColor | 选中项的图标颜色。不写则跟 selectedColor |
| background | 底栏背景 |
| borderColor | 顶部分割线 |
| fontSize | 文字大小(sp) |
| hidden | true 隐藏整栏 |
this.setTabBarStyle({
background: '#1A1A1A',
borderColor: '#333333'
});
this.setTabBarStyle({ hidden: true });列表触底时不要默认转圈。在 onReachBottom 里打开 loading,模拟或请求结束后再关掉:
onReachBottom() {
if (this.data.loading || this.data.noMore) {
return;
}
this.setData({ loading: true });
System.sleep(2000);
this.setData({ loading: false, noMore: true, footer: '—— 我是有底线的 ——' });
}执行脚本
轻触、长按等事件在 Page 方法里执行自动化脚本,不要写在 JSON 的 action 里。路径相对项目根目录。
{ "type": "button", "text": "运行示例", "onTap": "onRunSample" }Page({
onRunSample() {
Engines.executeScript('tasks/sample.js');
},
onRun(e) {
Engines.executeScript(e.item.jsFile);
}
});Engines.executeScript 见 Engines。任务脚本里也可以再 require 公共代码,见 require。
