所有元素都具有属性。内置元素带有常见属性,例如 color 或尺寸属性。
赋值绑定
你可以为它们赋值或整个 表达式:
export component Example inherits Window { // Simple expression: ends with a semi colon
width: 42px; // or a code block (no semicolon needed)
height: { 42px }}Slint 中的属性既可以使用简单的 表达式 进行赋值(以分号 ; 结尾), 也可以使用 代码块(用 { ... } 括起来),代码块不需要分号。 对于简单值,这两种形式可以互换使用,但当你需要多条语句时,代码块非常有用。
例如,下面这两种绑定是等价的:
background: touch-area.is-pressed ? red : blue;
background: { if (touch-area.is-pressed) { return red; } else { return blue; }}两种形式都是响应式的,Slint 会自动跟踪表达式或代码块中使用的依赖。
属性的默认值就是其类型的默认值。 例如 boolean 类型的属性默认为 false,int 类型的属性默认为 0,依此类推。
声明属性
除了已有属性之外,你还可以通过指定类型、名称以及可选的默认值来 定义额外的属性:
export component Example { // declare a property of type int with the name `my-property`
property<int> my-property;
// declare a property with a default value
property<int> my-second-property: 42;}可以使用一个限定符来标注额外属性,限定符规定了 该属性的读写方式:
private(默认):该属性只能在组件内部访问。in:该属性是一个输入。组件的使用者可以设置和修改它, 例如通过绑定或在回调中赋值。 组件可以提供一个默认绑定,但不能通过赋值覆盖它。out:一个输出属性,只能由组件设置。对于组件 的使用者来说,它是只读的。in-out:该属性可被任何人读取和修改。
export component Button { // This is meant to be set by the user of the component.
in property <string> text; // This property is meant to be read by the user of the component.
out property <bool> pressed; // This property is meant to both be changed by the user and the component itself.
in-out property <bool> checked;
// This property is internal to this component.
private property <bool> has-mouse;}组件顶层声明的所有非 private 的属性,在将组件用作元素时都可以从外部访问, 也可以通过语言绑定从业务逻辑中访问。
变更回调
在 Slint 中,可以定义一个在属性值发生变化时被调用的回调。
import { LineEdit } from "std-widgets.slint";export component Example inherits Window { VerticalLayout { LineEdit { // This callback is invoked when the `text` property of the LineEdit changes
changed text => { t.text = self.text; } } t := Text {} }}请注意,这些回调不会立即被调用。 它们会被排入队列,在事件循环的后续迭代中 被调用。只有当属性的值确实发生变化时,回调才会被调用。 如果一个属性的值在同一事件循环周期内多次变化,那么该回调只会被调用一次。 此外,如果一个属性的值发生变化,然后在回调执行之前又恢复到原始状态,那么该回调将不会被调用。
警告: 在 change 事件期间以可能导致同一属性受到影响的方式修改属性是未定义行为。
export component Example { in-out property <int> foo; property <int> bar: foo + 1; // This setup creates a potential loop between `foo` and `bar`, and the outcome is undefined.
changed bar => { foo += 1; }}上面这个例子表示一个无限循环。Slint 会在几次迭代之后打破该循环。 因此,如果存在一系列 changed 回调,其中一个回调触发了另一个 change 回调, 那么这个序列可能会被打断,后续的回调将不会被调用。
因此,务必避免过度使用 changed 回调。
警告: 仅当无法通过绑定实现时才使用 changed 回调。
例如,避免这样做:
changed bar => { foo = bar + 1; }而应选择:
foo: bar + 1;声明式绑定会自动管理依赖关系。 使用 changed 回调会强制立即对绑定进行求值,而绑定通常是按需延迟求值的。 这种做法也会破坏绑定的纯度,从而增加通过图形化编辑器进行编辑的难度。 累积过多的 changed 事件可能引发各种问题和 bug,尤其是在涉及循环的场景中——一个 change 回调修改某个属性时,可能会触发对同一属性的进一步修改。