跳到主要内容

表达式

表达式是微搭应用中的核心概念之一,广泛使用在各类出参、入参、属性绑定等场景。微搭应用中使用的表达式为 JavaScript 表达式,合法的 JavaScript 表达式即为合法的微搭表达式。需要注意的是微信小程序对 JavaScript 的限制在微搭中依然存在,所以如果希望能顺利支持小程序,则在代码编写时需要尽量避免使用 evalnew Function 这些代码。

应用中的表达式

微搭应用中所有支持绑定表达式的地方都会有 fx 标记或 {{ }} 站位符,常见的表达式使用场景有:

  • 属性绑定,最常见的是组件属性(props)绑定
  • 事件(包括事件流)中的动作入参绑定
  • 微搭数据表、APIs query 中的入参绑定
  • 在 MySQL query 的表达式占位符 {{ }} 中使用表达式

具体产品化使用可参考:https://cloud.tencent.com/document/product/1301/86577

微搭 API

微搭中内置了丰富的客户端 API 供表达式或其他自定义代码使用。微搭中内置 API 都在 $w 命名空间下,除了命名空间外一些作用域也是通过 $w 来引用。

绑定表达式时需要遵循以下几点规则:

  1. 使用同步表达式而不是异步
  2. 使用无副作用表达式
  3. 使用表达式而不是语句

在绑定表达式之外,生命周期、页面 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

原始 echat 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'
}
]
}