Skip to main content

Expressions

开发者可以在 Storyboard 编排中使用 JavaScript 表达式。

brick: my-brick
properties:
groups: <% _.groupBy(DATA.list, 'category') %>

Storyboard 中的表达式用 <% %> 嵌入,可以在诸如构件属性、事件等大部分场景中使用。

properties:
# ✅
good: "<% `Question: ${QUERY.q}` %>"

# 🚫 Not work: has extra prefix string
bad1: "Question: <% QUERY.q %>"

# 🚫 Not work: has extra suffix string
bad2: "<% QUERY.q %>&extra=1"

# 🚫 Not work: missing spaces
bad3: "<%QUERY.path%>"

表达式中可以使用大部分 JavaScript 表达式语法和 API,以及 Brick Next 内置对象。

内置 API

表达式中支持的内置对象主要如下:

对象类型说明
_objectLodash 函数库,例如 _.groupBy(list, 'category')。注意:剔除了注明会修改原始数据的、以及 Function 一节的 API。
momentfunctionMoment 函数库,例如 moment().format(...)。注意:剔除了注明会修改原始数据的 API。
ANCHORstringURL hash 参数去掉前缀 #
APPobject微应用信息(对应 storyboard 的 app 字段),例如 <% APP.homepage %>
BASE_URLstring页面的根目录,可能为 """/next",例如 `${BASE_URL}/hello-world`
CTXobjectContext 对象。
DATA-Context/State resolve 进行 transform 时的原始数据,或 UseBrick 对应的原始数据。
EVENTobject事件对象,仅适用于事件配置中。
FLAGSobject特性开关信息的键值对,键名为开关名,值为是否启用的布尔值。
FNobject调用指定函数,例如 FN.sayHello()
HASHstringURL hash 参数,带前缀 #(如有)。
I18N_TEXTfunction使用 I18N_TEXT(...) 根据当前语言设置转换带有国际化设置的字典为对应文本内容。
I18Nfunction使用 I18N(...) 显示应用预设的国际化内容。
IMGobject使用 IMG.get(...) 获取图像资源的 URL。
INDEXnumber控制节点 :forEach 内的子节点使用 INDEX 来访问对应的子项的索引(从 0 开始计数)。
INSTALLED_APPSobject使用 INSTALLED_APPS.has("your-app") 来判断指定微应用是否已安装。也可以使用 INSTALLED_APPS.has("your-app", ">=1.2.3") 来判断指定微应用已安装并且版本满足指定规则(目前仅支持 >= > = < <=
ITEM-控制节点 :forEach 内的子节点使用 ITEM 来访问对应的子项数据。
LOCAL_STORAGEobjectlocalStorage 存储的信息,支持 getItem 方法获取 localStorage 项,例如 LOCAL_STORAGE.getItem("your-key")。需要写入或移除数据,请使用内建处理器:localStorage.*
MEDIAobject媒体查询全局对象
MISCobject系统 Misc 设置。
PARAMSURLSearchParamsURLSearchParams 原始对象。
PATH_NAMEstringURL 路径名,例如当 URL 为 http://www.uwintech.cn/next/path/name?a=a 时,<% PATH_NAME %> 将转换为 /path/name
PATHstringURL path 参数。例如对于路径为 /object/:objectId 的路由,构件可以使用 <% PATH.objectId %> 引用当前 URL 对应的参数。
PERMISSIONSobject使用 PERMISSIONS.check("your:action-x") 检查当前登录用户是否拥有指定权限。可以传递多个 actions,当用户拥有所有指定权限时返回 true,否则返回 false
PIPESobject管道字典。例如可以使用 PIPES.yaml(whatever) 来引用 yaml 管道函数。
PROCESSORSobject自定义加工函数
QUERY_ARRAYobjectURL query 参数,在解析某项参数值时将返回数组。例如当 URL 为 ?a=1&a=2 时,QUERY_ARRAY.a 可以得到 ["1", "2"]
QUERYobjectURL query 参数,例如当 URL 为 ?a=1&b=2 时,QUERY.a 可以得到 "1"
SAFE_TAG_URLfunction类似于 TAG_URL 但会执行严格编码(会转换 /%2F)。
SESSION_STORAGEobjectsessionStorage 存储的信息,支持 getItem 方法获取 sessionStorage 项,例如 SESSION_STORAGE.getItem("your-key")。需要写入或移除数据,请使用内建处理器:sessionStorage.*
SIZEnumber控制节点 :forEach 内的子节点使用 SIZE 来访问数据源的数量。
STATEobject模板状态数据
SYSobject系统信息,例如当前登录用户名: SYS.username, 当前登录用户实例 ID: SYS.userInstanceId
TAG_URLfunction使用 JavaScript 的 Tagged Template 来实现对 URL 参数的自动编码(会忽略 / 的编码)。例如 TAG_URL`${APP.homepage}?q=${q}` 可以得到 /hello?q=a%26b (假设 APP.homepage/helloqa&b)。
THEMEobject通过 THEME.getTheme() 获得当前主题(通常为 "light""dark-v2"

递归标记

由于表达式(包括占位符和 Transform)计算得到的数据通常包含来自用户输入的数据,因此为了避免意外解析(例如某数据需要保存原始内容的表达式字符串),表达式得到的数据的内部的其它表达式在消费时不会执行解析。同时也为了避免类比于 XSS 的攻击,例如攻击者将某用户输入数据设置为包含恶意表达式的内容。

通过添加递归标记 ~ 例如 <%~ DATA %>,可以允许该表达式得到的数据的内部的其它表达式(包括占位符和 Transform)在消费时继续执行解析。请谨慎使用该标记。

附录

由于在设计上它仅用于数据加工和逻辑处理,因此我们剔除了修改数据、访问 DOM 等相关的语法和 API。

支持的 JavaScript 语法清单:

  • ✅ ArrayExpression: [1, 2, 3]
  • ✅ ObjectExpression: { a: 1 }
  • ✅ ArrowFunctionExpression: () => 1
  • ✅ UnaryExpression <Partial>
    • - + ! typeof void
  • ✅ BinaryExpression <Partial>
    • == != === !==
    • < <= > >=
    • + - * / % **
    • |> (pipeline operators! minimal version)
  • ✅ LogicalExpression: || && ?? (nullish coalescing 💅)
  • ✅ MemberExpression: a.b
  • ✅ OptionalMemberExpression: a?.b (optional chaining 💅)
  • ✅ ConditionalExpression: a ? 1 : 2
  • ✅ CallExpression: a(1)
  • ✅ SequenceExpression: a, b
  • ✅ TemplateLiteral: `/your/${path}`
    • ✅ Tagged template: TAG_URL`${APP.homepage}/list?q=${q}`
  • ✅ SpreadElement: [1, ...a] { a, ...rest }
  • ✅ ObjectPattern: ({ a, b }) => null
  • ✅ ArrayPattern: ([ a, b ]) => null
  • ✅ RestElement: (...args) => null
  • ✅ AssignmentPattern: (a = 1) => null
  • ✅ NewExpression <Partial>
    • new Array(...)
    • new Date(...)
    • new Map(...)
    • new Set(...)
    • new WeakMap(...)
    • new WeakSet(...)
    • new URLSearchParams(...)

不支持的 JavaScript 语法清单:

  • 🚫 Statement: if (a) {}
  • 🚫 Declaration: var a
  • 🚫 FunctionExpression: function a() {}
  • 🚫 UpdateExpression: ++i
  • 🚫 AssignmentExpression: a = 1
  • 🚫 Class: class A {}
  • UnaryExpression <Partial>
    • 🚫 ~ delete
  • BinaryExpression <Partial>
    • 🚫 << >> >>>
    • 🚫 | ^ & in instanceof
  • 🚫 Raw string in tagged template

浏览器原生 API 支持清单:

  • Object <Partial>
    • entries() fromEntries() keys() values()
    • 🚫 Other Methods assign(), etc.
  • ✅ Array
  • ✅ Boolean
  • ✅ Date
  • ✅ Infinity
  • ✅ JSON
  • ✅ Math
  • ✅ NaN
  • ✅ Number
  • ✅ String
  • ✅ atob
  • ✅ btoa
  • ✅ decodeURI
  • ✅ decodeURIComponent
  • ✅ encodeURI
  • ✅ encodeURIComponent
  • ✅ isFinite
  • ✅ isNaN
  • ✅ parseFloat
  • ✅ parseInt
  • location (readonly) <Partial>
    • ✅ href
    • ✅ origin
    • ✅ host
    • ✅ hostname