用于定义页面数据和实现生命周期接口。
支持ES6语法。
可以通过import引入功能模块,在代码中调用模块方法请参见API文档说明。
import fetch from "@system.fetch"
也可以一次引入所有的模块,例如:
import system from "@system"
在代码中使用system.network来调用接口方法。
JS代码引用推荐使用import来导入,例如:
import utils from '../Common/utils.js'
请认真理解protected/public/private/data属性的区别。public/data属性定义的数据在启动可以被外部的同名参数覆盖,所以请勿使用其定义用于敏感或安全的变量,如定义的变量和web组件的trustedUrl属性进行绑定。
| 属性 | 类型 | 描述 |
|---|---|---|
| data deprecated | object/function | 页面的数据模型,能够转换为JSON对象;属性名不能以$或_开头,不要使用for, if, show, tid等保留字。如果是函数,返回结果必须是对象,在页面初始时会执行函数获取结果作为data的值。遗留使用,建议直接通过public替代,data与private,protected和public不能重合使用。 |
| private | object | 页面的数据模型,private段下的变量仅允许当前页面内代码更改其值。 |
| protected | object | 页面的数据模型,protected段下的变量也可以在当前应用的页面间跳转时通过参数传递更改其值。 |
| public | object | 页面的数据模型,public段下的变量还可以允许外部通过url的参数传递更改其值,即与原data属性行为一致。 |
| props | array | 用于定义组件的公开属性列表(外部可见),可以通过<tag xxxx='value'>方式传递给到组件内部;属性名必须全部小写,不能以$或_开头,不要使用for, if, show, tid等保留字。目前公开属性的数据类型不支持function。 |
| computed(1050+) | object | 计算属性,属性名不能以$或_开头, 不要使用 for, if, show, tid 等保留字。 |
| 属性 | 类型 | 描述 |
|---|---|---|
| data | object/function | 页面的数据模型,能够转换为JSON对象;属性名不能以$或_开头,不能使用for, if, show, tid等保留字。如果是函数,返回结果必须是对象,在页面初始化时会执行函数获取结果作为data的值。 |
| props | array/object | 用于定义组件的公开属性列表(外部可见),可以通过<tag xxxx='value'>方式传递到组件内部;属性名必须全部小写,不能以$或_开头,不能使用for, if, show, tid等保留字。目前公开属性的数据类型不支持function。 |
| computed(1050+) | object | 计算属性,属性名不能以$或_开头, 不要使用 for, if, show, tid 等保留字。 |
| externalClasses(1100+) | array | 外部样式属性,定义外部传入的样式名(父组件可覆盖子组件样式)。 |
示例如下:
props: {
// 检测类型
a: Number,
// 检测类型+其他验证
b: {
type: Number, // 类型检查
default: 0, // 默认值
required: true, // 必填项检查
validator: function (value) { validator函数检查
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
} 示例如下:
export default {
data: {
firstName: 'Quick',
lastName: 'App'
},
computed: {
fullName: {
get () {
return `${this.firstName} ${this.lastName}`
},
set (value) {
const names = value.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
},
onReady () {
console.log(this.fullName) // Quick App
this.fullName = 'John Doe'
console.log(this.firstName) // John
console.log(this.lastName) // Doe
}
} 您可以通过 externalClasses 将外部样式传递给自定义组件。
如果传入的样式名称在自定义组件中已有定义,则优先级:外部样式 > 自定义组件中定义的样式;如果在一个节点上同时应用通用样式和外部样式,则优先级:外部样式>通用样式。
示例如下:
//parent.ux
<import name="child" src="./child.ux"></import>
<template>
<div class="demo-page">
<div class ="item">
<child color-child="color-parent"></child>
</div>
<div class ="item">
<input class="btn" type="button" value="nextTickShow" onclick="nextTickShow"/>
</div>
</div>
</template>
<script>
import router from '@system.router';
module.exports = {
data: {
},
onInit() {
},
nextTickShow: function() {router.push({
uri: 'Hello/NextTick',
})}
}
</script>
<style>
.demo-page {
align-items: center;
flex-direction: column;
height: 100%;
}
.item{
margin-top: 50px;
margin-right: 20px;
margin-left: 20px;
margin-bottom: 200px;
}
.color-parent {
color: green;
}
.btn{
background-color: #ff5e00;
color: #e9da05;
}
</style> //child.ux
<template>
<div class="container">
<text class="color-child">The color of the node is determined by the parent component</text>
</div>
</template>
<script>
export default {
externalClasses: ['color-child'],
data() {
return {}
},
onInit() {
}
}
</script>
<style>
.container {
height: 100%;
border-width: 1px;
margin: 20px;
padding: 10px;
flex-direction: column;
justify-content: center;
align-items: center;
}
.color-child {
color: red;
}
</style> | 属性 | 类型 | 描述 |
|---|---|---|
| $app | object | 应用对象。 |
| $page | object | 页面对象。 |
| $valid | boolean | 页面对象是否有效。 |
| $visible | boolean | 页面是否处于用户可见状态。 |
| $attrs(1090+) | object | 用于高优先级组件传值。 |
| $listeners(1090+) | object | 用于不同级别组件间发送所有事件监听。 |
$attrs:
示例代码如下:
//parent.ux
<template>
<div class="item-content">
<child attr1="attr1"></child>
</div>
</template> //child.ux
<template>
<div>
<grandson $attrs></grandson>
<input type="button" value="child" id="child-click" onclick="click" />
</div>
</template>
<script>
export default {
click() {
this.childAttr1 = this.$attrs.attr1
},
}
</script> //grandson.ux
<template>
<div class="box">
<text class="title">Attr1:{{grandChildAttr1}}</text>
<input type="button" value="grand-child" id="grand-child-click" onclick="click" />
</div>
</template>
<script>
export default {
click() {
this.grandChildAttr1 = this.$attrs.attr1
},
}
</script> $listeners:
示例代码如下:
// parent.ux
<template>
<div class="demo-page">
<child onevent1="handleEvent1"></child>
</div>
</template>
<script>
export default {
handleEvent1(evt) {
// do something!
}
}
</script> // child.ux <grandson $listeners></grandson>
// grandson.ux
<input type="button" value="grandson-event1" onclick="emitEvent1"/>
<script>
export default {
emitEvent1() {
this.$emit('event1', {childName: 'grandson'})
}
}
</script> :
可通过$app访问。
| 属性 | 类型 | 描述 |
|---|---|---|
| $def | object | 使用this.$app.$def获取在app.ux中暴露的对象。 |
| $data | object | 使用this.$app.$data获取在manifest.json的config.data中声明的全局数据。 |
可通过$page访问。
| 属性 | 类型 | 描述 |
|---|---|---|
| action | string | 获取打开当前页面的action。仅在当前页面是通过filter匹配的方式打开时有效,否则为undefined。参见“manifest文件”。 |
| uri | string | 获取打开当前页面的uri。仅在当前页面是通过filter匹配的方式打开时有效,否则为undefined。参见“manifest文件”。 |
| 属性 | 类型 | 参数 | 描述 |
|---|---|---|---|
| $set | function | key: String value: Any | 添加数据属性,必须在onInit函数中使用,否则<template>中数据绑定无法生效。 用法: this.$set('key',value) this.$vm('id').$set('key',value) |
| $delete | function | key: String | 删除数据属性,如果在onInit函数中使用,会导致<template>中相应的数据绑定无法生效。 用法: this.$delete('key') this.$vm('id').$delete('key') |
| 属性 | 类型 | 参数 | 描述 |
|---|---|---|---|
| $element | function | id: String 组件id | 获取指定id的组件dom对象,如果没有指定id,则返回根组件dom对象。 用法: <template><div id='xxx'></div></template>
|
| $root | function | 无 | 获取顶层ViewModel。 |
| $parent | function | 无 | 获取父亲ViewModel。 |
| $child | function | id:String 组件id | 获取指定id的自定义组件的ViewModel。 用法:this.$child('xxx') 获取id为xxx的组件ViewModel |
| $rootElement deprecated | function | 无 | 获取根组件dom对象。 用法:this.$rootElement(),获取根组件实例对象,等同于this.$element() |
| $vm deprecated | function | id: String 组件id | 获取指定id的自定义组件的ViewModel。 用法:this.$vm('xxx') ,获取id为xxx的div组件ViewModel。 |
| $forceUpdate | function | 无 | 强制页面刷新。 |
| getApp | function | 无 | 全局方法,方便获取app的信息,功能和$app对象相同。例如:getApp().$data.appName; |
| $nextTick(1100+) | function | function: 回调函数 | 在下次DOM升级循环结束之后执行延迟回调。 在修改数据之后立即使用这个方法,可以获取升级后的DOM。 |
$nextTick示例代码:
<template>
<div class="container">
<div>
<text class="title" id="title">{{ msg }}</text>
</div>
<div>
<input class="btn" type="button" value="nextTick" onclick="showInput" />
</div>
</div>
</template>
<script>
export default {
private: {
msg: "One",
next: null,
isShow: false
},
showInput() {
this.msg = "two";
this.$nextTick(() => {
this.msg = "Three";
});
this.msg = "four";
},
}
</script> | 属性 | 类型 | 参数 | 描述 |
|---|---|---|---|
| $on | function |
| 添加事件处理句柄。 用法:this.$on('xxxx', this.fn) ,fn是在<script>中定义的函数。 |
| $off | function |
| 删除事件处理句柄。 用法:this.$off('xxxx', this.fn) ,this.$off('xxx') 删除指定事件的所有处理句柄。 |
| $dispatch | function | type: String 事件名 | 向上层组件发送事件通知。 用法:this.$dispatch('xxx'),正常情况下,会一直向上传递事件(冒泡),如果要停止冒泡,在事件句柄函数中调用evt.stop()即可。 |
| $broadcast | function | type: String 事件名 | 向子组件发送事件通知。 用法:this.$broadcast('xxx'),正常情况下,会一直向下传递事件,如果要停止传递,在事件句柄函数中调用evt.stop()即可。 |
| $emit | function |
| 触发事件,对应的句柄函数被调用。 用法:this.$emit('xxx') ,this.$emit('xxx', {a:1}),传递的事件参数可在事件回调函数中,通过evt.detail来访问,例如evt.detail.a。 |
| $emitElement | function |
| 触发组件事件, 对应的句柄函数被调用。 用法:this.$emitElement('xxx', null, 'id'), this.$emitElement('xxx', {a:1}),传递的事件参数可在事件回调函数中,通过evt.detail来访问,例如evt.detail.a。 |
| $watch | function |
| 动态添加属性/事件绑定,属性必须在data中定义,handler函数必须在<script>定义;当属性值发生变化时事件才被触发。 用法:this.$watch('a','handler') |
可通过$page访问。
| 属性 | 类型 | 参数 | 描述 |
|---|---|---|---|
| setTitleBar | function |
| 设置当前页面的标题栏。 用法:this.$page.setTitleBar({text:'Hello', textColor:'#FF0000', backgroundColor:'#FFFFFF',backgroundOpacity :0.5,menu: false})。 |
| name(1030+) | string | - | 获取manifest中当前页面的名称。 用法:this.$page.name |
| component(1030+) | string | - | 获取manifest中当前页面的组件名称。 用法:this.$page.component |
| path(1030+) | string | - | 获取manifest中当前页面的Path。 用法:this.$page.path |
| finish | function | - | 退出当前页面,结束页面生命周期,页面的onDestroy会被调用。 |
| orientation(1040+) | string | - | 获取manifest中当前页面的屏幕方向。 用法:this.$page.orientation
|
| statusBarHeight(1050+) | string | - | 获取statusBar 的高度。 用法:this.$page.statusBarHeight |
| windowHeight(1050+) | string | - | 获取当前页面的窗口高度。 用法:this.$page. windowHeight |
| windowWidth(1050+) | string | - | 获取当前页面的窗口宽度。 用法:this.$page.windowWidth |
| setStatusBar(1050+) | function |
| 设置当前页面的状态栏。 用法:this.$page.setStatusBar({immersive:true,textStyle:'dark', backgroundColor:'#FFFFFF', backgroundOpacity:0.5,visible:false}); |
| exitFullscreen(1050+) | function | - | 页面退出全屏模式。 用法:this.$page.exitFullscreen(); 说明: 此方法必须是全屏下的video组件和stack组件调用才能生效。 |
| query(1060+) | object | - | 获取打开页面后router中携带的参数,是uri和params中参数的合集。 用法:this.$page.query |
| scrollBy(1070+) | function |
| 在窗口中按指定的偏移量滚动页面。 用法:this.$page.scrollBy({top:500, behavior:"smooth"}); 说明: 此方法必须在页面已经显示的情况下使用才有效果,即在onShow及以后阶段使用才有效果。 |
| scrollTo(1070+) | function |
| 滚动到页面中的某个指定坐标。 用法:this.$page.scrollTo({top:0, behavior:"smooth"}); |
| setSecure(1073+) | function | secure:Boolean 是否设置防截屏 | 是否设置防截屏。 用法:this.$page.setSecure(true/false); |
| setNavigationBar(1079+) | function | visible:Boolean 导航栏是否可见 | 设置当前页面的导航栏。 用法:this.$page.setNavigationBar({visible:false}); 注意: 当setNavigationBar的visible为false时,无论设置setStatusBar的visible为true或者false,系统状态栏都会被隐藏。 |
| function |
| 设置当前页面的MenubarData。 用法:this.$page.setMenubarData({shareTitle:'分享标题', shareDescription:'分享描述', shareIcon:'https://appimg.dbankcdn.com/application/icon144/b53a74c7982a47ea8c1c3f7408640989.png', shareCurrentPage:true, shareUrl:'https://developer.huawei.com', shareParams:"{\"key\":\"1\",\"id\":0}", usePageParams:true}); | |
| setMeta(1090+) | function |
| 是否允许以普通网页形式被爬虫程序发现并爬取。 用法:this.$page.setMeta({ pic:"the online address of the cover-image", description:"Hello" }); |
| enableAlertBeforeUnload(1107+) | function | message:String 询问对话框内容。 | 调用后,当用户尝试从当前页面返回上一页时,会弹出一个对话框。 用法:this.$page.enableAlertBeforeUnload({message:"Hello" }); |
| disableAlertBeforeUnload(1107+) | function | - | 取消enableAlertBeforeUnload的设置。 用法:this.$page.disableAlertBeforeUnload(); |
| 属性 | 类型 | 参数 | 返回值 | 描述 | 触发时机 |
|---|---|---|---|---|---|
| onInit | function | 无 | 无 | 监听页面初始化 | 当页面完成初始化时调用,只触发一次。 |
| onReady | function | 无 | 无 | 监听页面创建完成 | 当页面完成创建可以显示时触发,只触发一次。 |
| onShow | function | 无 | 无 | 监听页面显示 | 当进入页面时触发。 说明: 当页面根节点为自定义组件时,不会触发。建议使用div作为根节点。 |
| onHide | function | 无 | 无 | 监听页面隐藏 | 当页面跳转离开时触发。 |
| onDestroy | function | 无 | 无 | 监听页面退出 | 当页面跳转离开(不进入导航栈)时触发。 |
| onBackPress | function | 无 | Boolean | 监听返回按钮动作 | 当用户点击返回按钮时触发。
|
| onMenuPress | function | 无 | 无 | 监听菜单按钮动作 | 当用户点击ActionBar右边菜单按钮时触发。 从1070版本开始,该配置无效。 |
| onMenuButtonPress(1040+,TV特有,非厂商联盟标准) | function | 无 | Boolean | 监听菜单按钮动作 | 用户点击遥控器的菜单按键会触发。
|
| onRefresh(1050+) | function | Object | 无 | 监听页面重新打开 |
该回调中参数为重新打开该页面时携带的参数。 详细请参见“页面启动模式”。 |
| function | Object,参数为type | 无 | 监听应用配置发生变化 | 当应用配置发生变化时触发,如
| |
| onReachTop (1080+) | function | 无 | 无 | 监听页面是否触顶 | 页面滚动位置从不触顶到触顶时触发。 |
| onPageScroll (1080+) | function | 无 | function | 监听页面滚动 | 页面发生滚动时触发。 |
| onReachBottom (1080+) | function | 无 | 无 | 监听页面是否触底 | 页面滚动位置从不触底到触底时触发。 |
type表示应用配置发生变化的原因类型,目前支持的参数值如下:
| 参数值 | 描述 |
|---|---|
| locale | 应用配置因为语言、国家或地区配置变化而发生改变。 |
| themeMode(1083+) | 应用配置因为系统主题模式变化而发生改变。 |
| orientation(1083+) | 在manifest的orientation设置为auto,并且系统自动旋转开关打开时,切换横竖屏模式会触发。 说明: 当横竖屏方向切换时,可以通过调用应用配置的configuration.setScreenOrientation获取屏幕当前的横竖屏状态。 |
| foldScreenMode(1083+) | 屏幕的物理大小改变(如折叠屏折叠/展开)时触发。 |
页面生命周期接口的调用顺序:
| 属性 | 类型 | 参数 | 返回值 | 描述 | 触发时机 |
|---|---|---|---|---|---|
| onCreate | function | 无 | 无 | 监听应用创建。 | 当应用创建时调用。 |
| onRequest(1070+) | function | 无 | 无 | 监听应用拉起,minPlatformVersion 配置为1065及以上才会触发。 | 当应用新启动时调用。 |
| onShow(1070+) | function | 无 | 无 | 监听应用展示,minPlatformVersion配置为1065及以上才会触发。 | 当应用返回手机前台时调用。 |
| onHide(1070+) | function | 无 | 无 | 监听应用隐藏,minPlatformVersion配置为1065及以上才会触发。 | 当应用退到手机后台时调用。 |
| onError(1030+) | function | Object,该对象包括两个属性:message和stack,分别表示错误消息的说明和错误消息的栈调用信息。 | 无 | 监听应用错误信息。 | 当应用出现错误时调用。 |
| onPageNotFound(1060+) | function | 无 | Object,该对象包含一个属性:uri,表示跳转错误页面的原始链接。 | 在跳转到错误页面的时候回调此生命周期。 | 当引擎导航到错误页面的时候触发。 |
| onDestroy | function | 无 | 无 | 监听应用销毁。 | 当应用销毁时触发。 |
| onScreenChange(1079+) | function | 无 | String | 监听屏幕状态。
| 当屏幕状态变化时调用。 |
实现页面间的消息通信。
使用方法:创建消息通道对象
const channel = new BroadcastChannel('channel1') | 属性 | 类型 | 参数 | 描述 |
|---|---|---|---|
| onmessage | function | Event 消息对象 | 订阅消息 channel.onmhttpsessage = function (event) {
console.log(event.data)
} 通过event.data 获取消息内容 |
| postMessage | function | Object 消息内容 | 发布消息 channel.postMessage("hello world") |
| close | function | 无 | 关闭消息通道 channel.close() |
调用示例代码如下:
页面messageChannel创建了消息通道,并接收消息。跳转到页面detail,在页面detail通过消息通道发送消息。页面messageChannel收到消息后通过toast展示出来。
页面messageChannel.ux文件:
<template>
<div>
<div>
<text>{{componentName}}</text>
</div>
<div>
<input type="button" onclick="creatChannel" value="创建消息通道"/>
<input type="button" onclick="routeChannel" value="跳转到detail页面发送消息"/>
<input type="button" onclick="cancelChannel" value="关闭消息通道"/>
</div>
</div>
</template>
<style>
@import '../Common/css/common.css';
.item-container {
margin-bottom: 50px;
margin-right: 60px;
margin-left: 60px;
flex-direction: column;
}
</style>
<script>
import prompt from '@system.prompt'
import router from "@system.router"
var channel;
export default {
data: {
componentName: 'messageChannel',
},
onInit: function () {
this.$page.setTitleBar({text: 'messageChannel'})
},
creatChannel: function () {
channel = new BroadcastChannel('channel1');
channel.onmessage = function (event) {
console.log(event.data)
prompt.showToast({message: '接受消息:' + event.data});
};
},
routeChannel: function () {
router.push({
uri: '/Detail'
});
},
cancelChannel: function () {
channel.close();
}
}
</script> 页面detail.ux文件:
<template>
<div>
<div>
<text>{{componentName}}</text>
</div>
<div>
<input type="button" onclick="postChannel" value="发送消息"/>
</div>
</div>
</template>
<style>
@import '../../Common/css/common.css';
.item-container {
margin-bottom: 50px;
margin-right: 60px;
margin-left: 60px;
flex-direction: column;
}
</style>
<script>
export default {
data: {
componentName: 'detail',
},
onInit: function () {
this.$page.setTitleBar({text: 'detail'})
},
postChannel: function () {
var channel = new BroadcastChannel('channel1');
channel.postMessage("hello world");
}
}
</script>
消息通道建立后注册了回调:channel.onmessage = function (event) { ..... }; 必须调用相同对象的channel.close()方法才能给将消息通道关闭掉。