表达式
表达式是微搭应用中的核心概念之一,广泛使用在各类出参、入参、属性绑定等场景。微搭应用中使用的表达式为 JavaScript 表达式,合法的 JavaScript 表达式即为合法的微搭表达式。需要注意的是微信小程序对 JavaScript 的限制在微搭中依然存在,所以如果希望能顺利支持小程序,则在代码编写时需要尽量避免使用 eval
、new Function
这些代码。
应用中的表达式
微搭应用中所有支持绑定表达式的地方都会有 fx
标记或 {{ }}
占位符,常见的表达式使用场景有:
- 属性绑定,最常见的是组件属性(props)绑定
- 事件(包括事件流)中的动作入参绑定
- 微搭数据表、APIs query 中的入参绑定
- 在 MySQL query 的表达式占位符
{{ }}
中使用表达式
具体产品化使用可参考:https://cloud.tencent.com/document/product/1301/86577
微搭 API
微搭中内置了丰富的客户端 API 供表达式或其他自定义代码使用。微搭中内置 API 都在 $w
命名空间下,除了命名空间外一些作用域也是通过 $w
来引用。
绑定表达式时需要遵循以下几点规则:
在绑定表达式之外,生命周期、页面 handler、全局 common 中的代码都是 JavaScript 模块,可以编写更为复杂的代码逻辑而不受表达式规则的约束。
同步表达式
在没有特别声明的情况下使用表达式的场景都要求是同步表达式,即立即返回结果的表达式。一些需要等待返回 Promise 的异步表达式,在绑定时可能不会正常运行。
比如微搭提供了两个 API 来获取用户信息 $w.auth.currentUser
和 $w.auth.getUserInfo()
, 如果想在文本组件中展示用户昵称:
- 文本内容属性可以直接绑定同步表达式
$w.auth.currentUser.nickName
✅ - 但不能绑定异步表达式
$w.auth.getUserInfo().then(user => user.nickName)
❌
类似的异步 API 在微搭中还有 $w.cloud.callDataSource
, $w.cloud.callWorkflow
, $w.cloud.getTempFileURL
, 如果希望绑定这些异步内容,当前需要通过变量作为同步表达式来中转。
无副作用表达式
每一个合法的表达式都能计算成某个值,但从概念上讲,有两种类型的表达式:有副作用的(比如赋值)和单纯计算求值的。
尽管微搭没有硬性限制必须绑定副作用或者无副作用的表达式,但建议总是使用无副作用的表达式,因为在表达式绑定组件属性这些常见场景中时,表达式的执行时机复杂相对难以预测,不合时宜的调用这些有副作用的表达式或者 API 会产生难以预料的异常行为。
微搭中的部分具有副作用的 API 有:
- 更新变量:
$w.app.setState
,$w.page.setState
- 数据源或者流程调用:
$w.cloud.callDataSource
,$w.cloud.callWorkflow
- 触发 query 或 eventflow:
$w.query1.trigger
,$w.eventflow1.trigger
- 大部分的组件方法:
$w.input1.setValue
,$w.listView1.refresh
等
表达式和语句
表达式是一组代码的集合,它返回一个值。
JavaScript 应用程序是由许多语法正确的语句组成的。单个语句可以跨多行。如果每个语句用分号隔开,那么多个语句可以在一行中出现。
新手容易犯的一个错误是把普通的 JavaScript 语句当做表达式,从而导致一些异常情况,下面列举了一些常见的把语句当做表达式的例子:
例一,构造一个数组
// Bad ×
// 多行语句不是表达式,没有返回值
let list = [];
$w.query1.data.records.forEach((item) => {
list.push(item);
});
map
或者 reduce
做数组运算// Good √
$w.query1.data.records.map((item) => {
return item;
});
例二,构造一个通用图表 (echart) 的 option
// Bad ×
// echat 的 option 赋值语句
// 赋值是个表达式,但有副总用,并且分号结束表明这是个语句
option = {
xAxis: {
type: "category",
data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
},
yAxis: {
type: "value",
},
series: [
{
data: [150, 230, 224, 218, 135, 147, 260],
type: "line",
},
],
};
// Good √
{
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
data: [150, 230, 224, 218, 135, 147, 260],
type: 'line'
}
]
}