跳到正文

表达式与数据绑定 ​

机器翻译

本页由英文原文机器翻译而来,尚未经过母语审校,欢迎在 GitHub 上提出修改。内容如有出入,以英文原文为准。

花括号之间的任何内容都是表达式:{total * 2}。Quantum 用作用域中的变量对它求值, 并把结果放在原处。

本页的每个示例都按所示运行——tests/docs 执行每个代码块,并与它下面的 Output 比较。

一个值,或者带值的文本 ​

当一个属性恰好是一个表达式时,你得到的是带类型的值。周围还有其他内容时,你得到的是文本:

xml
<q:component name="Order" xmlns:q="https://quantum.lang/ns">
  <q:set name="price" value="9.5" type="number" />
  <q:set name="qty" value="3" type="number" />
  <q:return value="{price * qty}" />
</q:component>

Output: 28.5

xml
<q:component name="Summary" xmlns:q="https://quantum.lang/ns">
  <q:set name="price" value="9.5" type="number" />
  <q:set name="qty" value="3" type="number" />
  <q:return value="{qty} items, total {price * qty}" />
</q:component>

Output: "3 items, total 28.5"

运算符 ​

类别运算符
算术+ - * / //(整除) % **
比较== != < <= > >= in not in
逻辑and or not——或 && || !
选择value if condition else other

以文本形式到达的值——表单字段、查询参数、LLM 给出的工具参数——看起来像数字时会被当作数字, 所以 + 是相加:

xml
<q:component name="Sum" xmlns:q="https://quantum.lang/ns">
  <q:set name="a" value="17" />
  <q:set name="b" value="25" />
  <q:return value="{a + b}" />
</q:component>

Output: 42

xml
<q:component name="Age" xmlns:q="https://quantum.lang/ns">
  <q:set name="age" value="20" type="number" />
  <q:set name="invited" value="false" type="boolean" />
  <q:return value="{'enters' if age >= 18 && !invited else 'waits'}" />
</q:component>

Output: "enters"

in 的比较方式与 == 相同,所以以文本形式到达的值仍然能在列表中找到它对应的数字:

xml
<q:component name="Member" xmlns:q="https://quantum.lang/ns">
  <q:set name="chosen" value="5" />
  <q:set name="allowed" value="[1, 5, 10]" type="array" />
  <q:return value="{chosen in allowed}" />
</q:component>

Output: true

读取列表和记录 ​

xml
<q:component name="Reading" xmlns:q="https://quantum.lang/ns">
  <q:set name="user" type="object" value='{"name": "Ana", "tags": ["admin", "dev"]}' />
  <q:return value="{user.name} has {user.tags.length} tags, first {user.tags[0]}, last {user.tags[-1]}" />
</q:component>

Output: "Ana has 2 tags, first admin, last dev"

true、false 和 null 是字面量。在双引号属性中,字符串使用单引号:{status == 'active'}。

函数 ​

函数示例结果
upper(s)、lower(s)、trim(s)upper('ana')ANA
replace(s, old, new)replace('a-b', '-', '+')a+b
split(s, sep=',')split('a,b')['a', 'b']
contains(s, part)contains('quantum', 'ant')true
len(x)、first(x)、last(x)len(items)项的数量
get(x, key, default=null)——可选的键或索引get(prefs, 'theme', 'light')这个值,缺失时为 default
join(list, sep=', ')、sort(list)join(sort(tags), ' / ')文本
round(n, digits=0)——.5 向远离零的方向取整round(2.5)3
ceil(n)、floor(n)、abs、min、maxceil(7 / 3)3
int(x)、float(x)、str(x)int('42')42
now()now()当前日期和时间
dateAdd(unit, n, start=now)dateAdd('d', 7)一周之后
dateDiff(unit, start, end)dateDiff('h', a, b)整小时数
dateFormat(date, pattern)dateFormat(now(), '%d/%m/%Y')10/09/2026
hashPassword(s)、verifyPassword(s, hash)见身份认证
random()、random(a, b)random(1, 6)0 到 1 之间的数;a 到 b 之间的整数
chance(p)、pick(list)pick(tips)以概率 p 为真;一个元素

日期函数的单位:s、n(分钟)、h、d、w。在组件中声明的 q:function 也以同样的方式调用:{twice(price)}。

函数按名字调用,从不作为方法调用:写 split(title, ' '),而不是 title.split(' '); 写 ceil(n),而不是 Math.ceil(n)。出于 JavaScript 习惯写错时,错误会指出应该用的函数。 .length 可以用于文本和列表。

xml
<q:component name="Functions" xmlns:q="https://quantum.lang/ns">
  <q:function name="twice">
    <q:param name="x" type="number" />
    <q:return value="{x * 2}" />
  </q:function>
  <q:set name="tags" value='["dev", "admin"]' type="array" />
  <q:return value="{upper(join(sort(tags), ' / '))} {twice(21)}" />
</q:component>

Output: "ADMIN / DEV 42"

带作用域的变量 ​

session.、application.、request.、form.、query. 和 cookie. 从各自的作用域读取。 页面常常在值存在之前就渲染——比如登录之前——所以读取一个没有设置的值会得到空文本:

xml
<q:component name="Hello" xmlns:q="https://quantum.lang/ns">
  <q:return value="[{session.name}]" />
</q:component>

Output: "[]"

对没有设置的值做算术是一个错误,而不是空结果。计数器请用 operation="increment",它从零开始:

xml
<q:component name="Visits" xmlns:q="https://quantum.lang/ns">
  <q:set name="session.visits" operation="increment" />
  <q:return value="{session.visits}" />
</q:component>

Output: 1

当表达式失败时 ​

在 q: 属性中,无法求值的表达式会以指明它的错误让组件停止——不会悄悄地替换成别的东西:

xml
<q:component name="Broken" xmlns:q="https://quantum.lang/ns">
  <q:set name="total" value="3" type="number" />
  <q:return value="{totl + 1}" />
</q:component>

Error: {totl + 1} could not be evaluated: variable 'totl' is not defined, did you mean 'total'?

求值失败({10 / zero})以及对没有设置的作用域值做算术,也是如此。

有两个地方是有意更宽容的:

  • 条件检查的是存在性。 不存在的名字、键或属性会让 condition 为假,所以 <q:if condition="flash"> 在还没有提示消息时也能工作。其他任何问题——语法错误、 不存在的函数——仍然是错误。
  • HTML 内容保留原文。 页面内容中无法解析的表达式会按原样渲染,并记录一次日志。 页面内容中也会有代码示例和零散的花括号,它们不能让页面崩溃。
xml
<q:component name="Presence" xmlns:q="https://quantum.lang/ns">
  <q:if condition="flash">
    <q:return value="there is one" />
  </q:if>
  <q:return value="there is none" />
</q:component>

Output: "there is none"

不是表达式的花括号 ​

JSON 对象和正则表达式的量词会保持原样:

xml
<q:component name="Literals" xmlns:q="https://quantum.lang/ns">
  <q:set name="pattern" value="[0-9]{10,11}" />
  <q:set name="rows" value='[{"a": 1}, {"b": 2}]' type="array" />
  <q:return value="{pattern} {len(rows)}" />
</q:component>

Output: "[0-9]{10,11} 2"

参考 ​

本页的规则是 SPEC.md 中的 EXPR-1 到 EXPR-5。

MIT 许可证 · 使用 VitePress 构建