uni-app中的页面,默认保存在工程根目录下的pages目录下。
每次新建页面,均需在pages.json中配置pages列表;
未在pages.json -> pages 中注册的页面,uni-app会在编译阶段进行忽略。pages.json的完整配置参考:页面配置。
通过HBuilderX开发 uni-app 项目时,在 uni-app 项目上右键“新建页面”,HBuilderX会自动在pages.json中完成页面注册,开发更方便。
同时,HBuilderX 还内置了常用的页面模板(如图文列表、商品列表等),选择这些模板,可以大幅提升你的开发效率。
新建页面时,可以选择vue或nvue,还可以选择是否创建同名目录。创建目录的意义在于,如果你的页面较复杂,需要拆分多个附属的js、css、组件等文件,则使用目录归纳比较合适。如果只有一个页面文件,大可不必多放一层目录。
删除页面时,需做两件工作:
pages.json是工程的页面管理配置文件,包括:页面路由注册、页面参数配置(原生标题栏、下拉刷新…)、首页tabbar等众多功能。
其篇幅较长,另见 pages.json
pages.json -> pages 配置项中的第一个页面,作为当前工程的首页(启动页)。
{
"pages": [
{
"path": "pages/index/index", //名字叫不叫index无所谓,位置在第一个,就是首页
"style": {
"navigationBarTitleText": "首页" //页面标题
}
},
{
"path": "pages/my",
"style": {
"navigationBarTitleText": "我的"
}
},
]
}
uni-app 页面基于 vue 规范。一个页面内,有3个根节点标签 、
<template>
<view class="content">
<button @click="buttonClick">{{title}}</button>
</view>
</template>
<script>
export default {
data() {
return {
title: "Hello world", // 定义绑定在页面上的data数据
}
},
onLoad() {
// 页面启动的生命周期,这里编写页面加载时的逻辑
},
methods: {
buttonClick: function () {
console.log("按钮被点了")
},
}
}
</script>
<style>
.content {
width: 750rpx;
background-color: white;
}
</style>
vue的template中写的全都是vue组件,每个组件支持属性、事件、vue指令,还可以绑定vue的data数据。
在vue的选项式(option)规范中,script下包含export default {}。(除了选项式,还有组合式)
页面级的代码大多写在export default {}中。写在里面的代码,会随着页面关闭而关闭。
export default 外的代码
先来介绍写在export default {}外面的代码,一般有几种情况:
<script>
const TAB_OFFSET = 1; // 外层静态变量不会跟随页面关闭而回收
import charts from 'charts.ts'; // 导入外部js/ts模块
import swiperPage from 'swiper-page.vue'; //导入非easycom的组件
type GroupType = {
id : number,
title : string
} // 在ts中,为下面data数据的 groupList 定义类型
export default {
components: {
swiperPage
}, // 注册非easycom组件
data() {
return {
groupList: [
{ id: 1, title: "第一组" },
{ id: 2, title: "第二组" },
] as GroupType[], // 为数据groupList定义ts类型
}
},
onLoad() {},
methods: {}
}
</script>
开发者应谨慎编写export default {}外面的代码,这里的代码有2个注意事项:
export default 里的代码
export default {} 里的内容,是页面的主要逻辑代码。包括几部分:
整体效果就是,刚开始按钮文字是"点我",点一下后按钮文字变成了"被点了"
uni-app 页面除支持 Vue 组件生命周期外还支持下方页面生命周期函数.
接下来我们介绍onLoad、onReady、onShow的先后关系,页面加载的详细流程。
了解了页面加载时序原理,我们就知道如何避免页面加载常见的问题:
优化白屏的方法:
卡住动画不启动的原因:
不建议使用
onPageScroll : function(e) { //nvue暂不支持滚动监听,可用bindingx代替
console.log("滚动距离为:" + e.scrollTop);
},
当用户进行以下操作时,会触发该函数:
注意事项:
页面中的遮罩处于显示状态时,点击返回不希望直接关闭页面,而是隐藏掉遮罩。遮罩隐藏后,继续点击返回再执行默认的逻辑。
自定义遮罩 通常自定义的遮罩/弹出层,都会做成组件,这样方便复用。新建 uni-app 项目->components->mask.vue 文件,代码如下:
<template>
<view>
<view class="cpt-mask">
</view>
</view>
</template>
<script>
export default {}
</script>
<style>
.cpt-mask {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #000000;
opacity: 0.5;
z-index: 99;
}
</style>
引用遮罩组件 在页面中引入 mask 自定义组件后,通过一个状态值来控制其隐藏/显示。
<mask v-if="showMask"></mask>
这里用 v-if,不要用 v-show,自定义组件存在一些问题待优化。
在 onBackPress 中,判定当前遮罩是否处于显示状态。如果显示,则关闭遮罩并返回 true。
onBackPress() {
if (this.showMask) {
console.log('onBackPress close mask');
this.showMask = false;
return true;
} else {
uni.showModal({
title: '提示',
content: '自定义是否退出uni-app?',
success: function(res) {
if (res.confirm) {
// 退出当前应用,改方法只在App中生效
plus.runtime.quit();
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
return true;
}
},
onTabItemTap : function(e) {
console.log(e);
// e的返回格式为json对象: {"index":0,"text":"首页","pagePath":"pages/index/index"}
},
{
"fontSrc": "/static/yticon.ttf",
"text": "",
"fontSize": "26",
"color": "#303133",
"float": "left",
"background": "rgba(0,0,0,0)",
"onclick": "function() { [native code] }",
"__cb__": {
"id": "plus71692953577889",
"htmlId": "__uniapp__service"
},
"index": 0
}
getApp() 函数用于获取当前应用实例VUE,一般用于获取globalData。也可通过应用实例调用 App.vue methods 中定义的方法。
getCurrentPages() 函数用于获取当前页面栈的实例,以数组形式按栈的顺序给出,数组中的元素为页面实例,第一个元素为首页,最后一个元素为当前页面。
getCurrentPages()仅用于展示页面栈的情况,请勿修改页面栈,以免造成页面状态错误。页面关闭时,对应页面实例会在页面栈中删除。
var pages = getCurrentPages();
var page = pages[pages.length - 1];
uni.$emit('update',{msg:'页面更新'})
监听全局的自定义事件。事件可以由 uni.$emit 触发,回调函数会接收所有传入事件触发函数的额外参数。
uni.$on('update',function(data){
console.log('监听到事件来自 update ,携带参数 msg 为:' + data.msg);
})
监听全局的自定义事件。事件可以由 uni.$emit 触发,但是只触发一次,在第一次触发之后移除监听器。
uni.$once('update',function(data){
console.log('监听到事件来自 update ,携带参数 msg 为:' + data.msg);
})
移除全局自定义事件监听器。
$emit、$on、$off
常用于跨页面、跨组件通讯,这里为了方便演示放在同一个页面
uni.$emit()和uni.$on()
进行页面间通讯:监听事件
// 我的页面
onLoad(){
// 监听事件
uni.$on('login',(usnerinfo)=>{
this.usnerinfo = usnerinfo;
})
},
onUnload() {
// 移除监听事件
uni.$off('login');
},
因为事件监听是全局的,所以使用 uni.$on
,需要使用 uni.$off
移除全局的事件监听,避免重复监听。
触发事件
// 登陆页面
uni.$emit('login', {
avatarUrl: 'https://img-cdn-qiniu.dcloud.net.cn/uploads/nav_menu/10.jpg',
token: 'user123456',
userName: 'unier',
login: true
});
使用 uni.$emit
触发事件后,对应的 uni.$on
就会监听到事件触发,在回调中去执行相关的逻辑。
uni-app 有两种页面路由跳转方式:使用navigator组件跳转、调用API跳转。