自定义组件处于非激活状态时,状态变量将不响应更新,即@Watch不会调用,状态变量关联的节点不会刷新。通过freezeWhenInactive属性来决定是否使用冻结功能,不传参数时默认不使用。支持的场景有:页面路由,TabContent,LazyforEach,Navigation。
说明:
从API version 11开始,支持自定义组件冻结功能。
当前支持的场景
页面路由
-
当页面A调用router.pushUrl接口跳转到页面B时,页面A为隐藏不可见状态,此时如果更新页面A中的状态变量,不会触发页面A刷新。
-
当应用退到后台运行时无法被冻结。
页面A:
import router from '@ohos.router';
@Entry
@Component({
freezeWhenInactive: true })
struct FirstTest {
@StorageLink('PropA') @Watch("first") storageLink: number = 47;
first() {
console.info("first page " + `${
this.storageLink}`)
}
build() {
Column() {
Text(`From fist Page ${
this.storageLink}`).fontSize(50)
Button('first page storageLink + 1').fontSize(30)
.onClick(() => {
this.storageLink += 1
})
Button('go to next page').fontSize(30)
.onClick(() => {
router.pushUrl({
url: 'pages/second' })
})
}
}
}
页面B:
import router from '@ohos.router';
@Entry
@Component({
freezeWhenInactive: true })
struct SecondTest {
@StorageLink('PropA') @Watch("second") storageLink2: number = 1;
second() {
console.info("second page: " + `${
this.storageLink2}`)
}
build() {
Column() {
Text(`second Page ${
this.storageLink2}`).fontSize(50)
Button('Change Divider.strokeWidth')
.onClick(() => {
router.back()
})
Button('second page storageLink2 + 2').fontSize(30)
.onClick(() => {
this.storageLink2 += 2
})
}
}
}
在上面的示例中:
1.点击页面A中的Button “first page storLink + 1”,storLink状态变量改变,@Watch中注册的方法first会被调用。
2.通过router.pushUrl({url: ‘pages/second’}),跳转到页面B,页面A隐藏,状态由active变为inactive。
3.点击页面B中的Button “this.storLink2 += 2”,只回调页面B@Watch中注册的方法second,因为页面A的状态变量此时已被冻结。
4.点击“back”,页面B被销毁,页面A的状态由inactive变为active,重新刷新在inactive时被冻结的状态变量,页面A@Watch中注册的方法first被再次调用。
TabContent
-
对Tabs中当前不可见的TabContent进行冻结,不会触发组件的更新。
-
需要注意的是:在首次渲染的时候,Tab只会创建当前正在显示的TabContent,当切换全部的TabContent后,TabContent才会被全部创建。
@Entry
@Component
struct TabContentTest {
@State @Watch("onMessageUpdated") message: number = 0;
onMessageUpdated() {
console.info(`TabContent message callback func ${
this.message}`)
}
build() {
Row() {
Column() {
Button('change message').onClick(() => {
this.message++
})
Tabs() {
TabContent() {
FreezeChild({
message: this.message })
}.tabBar('one')
TabContent() {
FreezeChild({
message: this.message })
}.tabBar('two')
}
}
.width('100%')
}
.height('100%')
}
}
@Component({
freezeWhenInactive: true })
struct FreezeChild {
@Link @Watch("onMessageUpdated") message: number
private index: number = 0
onMessageUpdated() {
console.info(`FreezeChild message callback func ${