SuperAPI AI Directory

kuikly-reactive-observer

Frontend & websites

View repository

Updated 10-15 15:18

About this skill

Kuikly Reactive Update and Directive System

Core Mechanism

attr {} When reactive fields are read within a closure, the framework automatically collects dependencies; when the field value changes, the bound UI properties are automatically updated.Only the data needs to be updated, and the UI responds automatically.

Note:observable internally uses == to compare the old and new values,and does not trigger an update when they are equal。


Reactive Field Declaration

In Pager(which implements the PagerScope interface) or any PagerScope subclass, use:

// 推荐:PagerScope 扩展函数
import com.tencent.kuikly.core.reactive.handler.observable
import com.tencent.kuikly.core.reactive.handler.observableList
import com.tencent.kuikly.core.reactive.handler.observableSet

var counter by observable(0) // single value var list by observableList() // reactive list, used with vfor var tags by observableSet() // reactive set


### 绑定到 UI

```kotlin
var title by observable("Hello")

Text {
    attr {
        text(ctx.title) // 直接引用响应式字段,自动绑定
    }
}
// 更新 ctx.title = "World" 后,Text 自动刷新

Directive System

Loop Directives: vfor / vforIndex

var list by observableList<String>()

// vfor:遍历 observableList,增删时自动增量更新
List {
    attr { flex(1f) }
    vfor({ ctx.list }) { item ->
        Text { attr { text(item) } }
    }
}

// vforIndex:额外提供 index 和 count
vforIndex({ ctx.list }) { item, index, count ->
    View {
        attr { backgroundColor(if (index % 2 == 0) Color.GRAY else Color.TRANSPARENT) }
        Text { attr { text("$index: $item") } }
    }
}

A closure must be passed { ctx.list }, not a value passed directly ctx.list。

Loop Directive: vforLazy (very large lists)

Only used in ListView (excluding PageList, WaterfallList), dynamically adding and removing virtual nodes outside the visible range:

List {
    attr { flex(1f) }
    vforLazy({ ctx.list }, maxLoadItem = 50) { item, index, count ->
        Text { attr { text(item) } }
    }
}
Parameter Type Default Value Description
itemList () -> ObservableList<T> — Data source closure
maxLoadItem Int 30 Maximum number of virtual nodes in memory; recommended to be 2~3 times the number visible on one screen
itemCreator (T, Int, Int) -> Unit — Build closure

Conditional Directives: vif / velseif / velse

var state by observable(0)

View {
    vif({ ctx.state == 1 }) {
        Text { attr { text("状态1") } }
    }
    velseif({ ctx.state == 2 }) {
        View { attr { size(100f, 100f); backgroundColor(Color.GREEN) } }
    }
    velse {
        Text { attr { text("其他状态") } }
    }
}

velseif / velse must immediately follow vif or velseif, and no other components can be inserted in between.

Binding Directive: vbind

Similar to a when statement; when the bound value changes,remove all child components and rebuild:

var state by observable(0)

View {
    vbind({ ctx.state }) {
        when (ctx.state) {
            1 -> Text { attr { text("状态1") } }
            2 -> View { attr { size(100f, 100f); backgroundColor(Color.GREEN) } }
        }
    }
}

vbind When the bound value is null , the creator closure is not executed.


Efficient List Updates: diffUpdate

// 基本用法(基于 Myers diff 算法,只增删变化的 Item)
list.diffUpdate(newData)

// 自定义比较(通过 id 判断是否同一元素)
userList.diffUpdate(newUsers) { old, new -> old.id == new.id }
Method Behavior Performance
clear() + addAll() Destroy all Items → rebuild Poor
diffUpdate(newList) Only add and remove changed Items Excellent

Common Errors and Constraint Rules

See the following reference files for details:

  • Common Errors:COMMON_MISTAKES.md — 8 typical errors such as broken reactive dependencies, modifying an object's internal properties not triggering updates, vfor passing a value instead of a closure, ViewBuilder not being invoked, etc.
  • Directive Constraint Rules:DIRECTIVE_RULES.md — the vfor closure must generate exactly one root node, the root node cannot be a directive node, vforLazy is limited to ListView, velseif/velse must immediately follow vif, the index/count update rules of vforIndex, etc.