属性

普通属性

margin

调整组件外边距,可以用于几乎所有组件(例外见下表),格式与 css 中的类似,除了顺序(这里是左上右下,从左边开始,顺时针方向):

  • margin="4" 指定所有边使用相同的外边距;

  • margin="10 8" 指定左右、上下的外边距,左右外边距一样,上下外边距一样;

  • margin="10 8 5" 指定左、上下、右方向的外边距,上下外边距一样;

  • margin="10 8 5 8" 分别指定左、上、右、下方向的外边距;

  • margin="10 - 5" 指定左、上下、右方向的外边距,上下外边距保留默认值;

    除了下面的组件之外,其它组件有默认的外边距,如果您在修改 margin 的时候,某一个方向想保留默认的外边距,使用 - 代替数字即可。

    组件说明
    Row默认无外边距,可以手动设置。
    Column默认无外边距,可以手动设置。
    For无外边距,无法设置,可以为其子组件添加外边距,或作为其它组件的子组件使用。

flex

调整同级组件尺寸占比。

比如下面的例子,在一行中,第一个 Text 组件将占用 1/(1+2) = 1/3 宽度比例,第二个则是 2/3。

<Row>
    <Text flex="1">33.33%</Text>
    <Text flex="2">66.67%</Text>
</Row>

name

相当于 HTML 表单的 name 属性,用来提交数据的时候作为标识的。可选。部分组件有此属性(具体见每个组件文档)

只能使用字母和数字命名以及[]后缀(表示数组)。模板会收集 name 属性不为空的组件的数据,然后以 JSON 的格式传给接口。每个 name 对应一个 JSON 字段,因此同一个模板里面 name 应该保持唯一性,避免在 JSON 里面字段被覆盖;

  • 数据只有一层,不要使用 .
    目前不支持返回多层结构的 JSON 数据;请不要在 name 中使用 . 号,. 号目前作为保留字符。
  • 仅支持一维数组
    当您需要将同一类数据放在一个数组里面的时候,只需要将 name 属性声明为一样的并且后面带上 []
    不过只支持一维数组,所以类似 list[0][] 的 name 会被当成名字叫 list[0] 的一维数组。
  • 使用规范保守的命名
    使用规范保守的命名,如果以后对高级数据结构进行支持的时候,对于不规范的命名可能会带来不必要的麻烦。
  • 关于提交的键值数据类型,请参考具体组件的文档中“属性表格”-“属性名称”-“name"括号部分。

特殊属性

特殊属性通常由动作事件触发,带有特殊处理事务。

特殊属性命名方式类似:aaa:bbb,中间带有英文半角冒号,前半部分名称(前缀)相同的属性,意味着每个组件中最多只有一个生效。 比如在组件中使用了多个前缀名称相同的属性 c:ac:bc:c,那么最终只有(最后声明的)一个生效,其余忽略。

v:show/v:hide

动态显示/隐藏组件,可以用于任何组件。
是否支持变量替换:不支持。
触发条件:无。

<Text v:show="key">Hello</Text>
<Text v:hide="key">Hello</Text>

配合数据使用,用来展示/隐藏组件。

  • 注意这里的 key 为变量名,不能使用 {{key}}
  • v:show 当条件为真,则显示组件,否则隐藏;
  • v:hide 当条件为真,则隐藏组件,否则显示;

条件判断规则:

  • 如果是布尔值,则直接判断;
  • 如果是字符串,空字符串为 false,否则为 true
  • 如果是数字,0 为 false,否则为 true
  • 其它情况,根据变量(key)是否存在判断,不存在为 false,否则为 true
    {
        "true_1": true,
        "false_1": false,

        "true_2": -1,
        "false_2": 0,

        "true_3": "0",
        "false_3": ""
    }
<Text v:show="true_1">v:show="true"</Text>
<Text v:hide="false_1">v:hide="false"</Text>
<Text v:show="true_2">v:show=-1</Text>
<Text v:hide="false_2">v:hide=0</Text>
<Text v:show="true_3">v:show="0"</Text>
<Text v:hide="false_3">v:hide=""</Text>
<Text v:hide="keyNotExist">v:hide=</Text>
查看渲染结果

link:open/link:opena

打开链接。

是否支持变量替换:支持。
触发条件:点击。

<Text link:open="https://example.com/a/b/c">打开地址</Text>
<Text link:opena="https://example.com/user/auth">关联帐号</Text>
  • link:open 点击打开指定的地址,需要填写完整的 URL;
  • link:opena 最后多了一个 a,通过此属性打开的页面,可以在页面中获取到 requestToken,从而得到用户的 openID;

当使用 link:opena 的时候,请务必确认链接地址是您信任的地址。


api:get/api:post

向 API 接口发起请求,以获取/提交数据。
是否支持变量替换:支持。
触发条件:点击。

  • 带有 api:get 属性的组件,当组件被点击的时候,客户端将会向指定的地址发起一次 HTTP GET 请求,其中地址是 服务地址+api:get 属性的值连接起来的字符串。
  • 带有 api:post 属性的组件,当组件被点击的时候,客户端会收集对应的模板中的组件的数据,以 JSON 格式 POST 到指定的地址,其中地址是 服务地址+api:post 属性的值连接起来的字符串。

需要模板指定服务地址才能使用,这里不允许填写完整的 URL 地址。参考与客户端对接

提交的 JSON 数据的内容取决于模板中的 name 属性,请具体参考各个组件文档。

<Input name="name"></Input>
<Button api:get="/get/data">获取数据</Button>
<Button api:post="/post/data">提交表单</Button>

message:create/message:delete/message:replace

新建/删除/替换消息。
是否支持变量替换:支持。
触发条件:点击。

下面是此三种属性的所有用法

<Button message:create="@">使用本消息模板新建消息</Button>
<Button message:create="templateID,version">指定消息模板新建消息</Button>

<Button message:delete="@">删除本消息</Button>
<Button message:delete="messageID,localMessageID">删除指定消息</Button>
<Button message:delete="messageID">删除指定消息</Button>
<Button message:delete="0,localMessageID">删除指定消息</Button>

<Button message:replace="templateID,version">替换消息</Button>

dialog:page/dialog:return

打开新页面和关闭页面(返回上一页)。
是否支持变量替换:支持。
触发条件:点击。

当从消息或者一个页面中打开一个新的页面时,data 字段会进行深度拷贝传递到新页面,可以直接使用且互不影响。 此默认行为是单向的,即只有 dialog:page 有此行为,dialog:return 是不支持的,但是你可以通过 data(…) 返回额外的变量。

通过 form()data() 参数来传递变化的数据:

# dialog:page 格式
<Button dialog:page="templateID,templateVersion;">查看文章</Button>
<Button dialog:page="templateID,templateVersion; form(name1, name2, name4=name3)">查看文章</Button>
<Button dialog:page="templateID,templateVersion; data(var1, var2.var21, varRename=var3)">查看文章</Button>
<Button dialog:page="templateID,templateVersion; form(name1, name2, name4=name3); data(var1, var2.var21, varRename=var3)">查看文章</Button>


# dialog:return 格式
<Button dialog:return="">返回(不带任何数据返回)</Button>
<Button dialog:return="form(name1, name2, name4=name3)">确认(附带表单数据返回)</Button>
<Button dialog:return="data(var1, var2.var21, varRename=var3)">确认(附带变量数据返回)</Button>
<Button dialog:return="form(name1, name2, name4=name3); data(var1, var2.var21, varRename=var3)">确认(两者都有)</Button>
  • templateID,templateVersion
    模板ID和模板版本号。dialog:page 必填,dialog:return 没有此参数。

  • form(name1, name2, name4=name3) (可选)
    表示将当前模板中的表单数据(name 分别为 name1、name2、name3,且 name3 会被重命名为 name4)传递给新页面(或返回给上一页)。

    • * 号支持:表示收集当前表单所有值作为参数;
    • 嵌套:不支持,因为表单键名本身没有嵌套的说法,等于普通的名称一样处理;
  • data(var1, var2.var21, varRename=var3) (可选)
    将当前变量 var1、varRename=var3(手动重命名为 varRename)、var2.var21(自动重命名为 var21,等同于 var21=var2.var21)一起传递到新页面(或返回给上一页)。
    模板中有时候会有一些临时变量,比如在 For 组件遍历的时候,也是可以使用的。

    • * 号支持:不支持,因为本来 data 值是全部从上个页面传递过来的;
    • 嵌套变量:支持,data(aa, bb.cc, dd=bb.cc) 等同于 data(aa, cc=bb.cc, dd=bb.cc);
    • 暂不支持数组的形式;

    比如,现在我们有一个文章列表,用户在消息中点了某个文章标题,打开新页面,开始查看此篇文章的内容,数据如下:

    {
        "articleList": [
            {"id": 1, "title": "xxx xxx"},
            {"id": 2, "title": "xx xxxx xxx"},
            ...
        ]
    }
    
    # 模板:文章列表页
    <For list="articleList" item="article">
        <Text dialog:page="xxxxxx,1">{{article.title}}</Text>
    </For>
    

    这个时候需要知道用户点了哪个标题,然后把对应的 ID 传过去:

    <For list="articleList" item="article">
        <Text dialog:page="xxxxxx,1; data(article.id, articleTitle=article.title)">{{article.title}}</Text>
    </For>
    

    新页面中得到的 data

    {
        "articleList": [                        <- 原有的数据默认传递过来
            {"id": 1, "title": "title 1"},
            {"id": 2, "title": "title 2"},
            ...
        ],
        "id": 2,                   <- 新增的字段
        "articleTitle": "title 2"  <- 新增的字段
    }
    
    #  接着定义新的模板:文章内容页,用户标题后进入此页面,阅读文章内容
    <AutoLoad>/article/{{id}}</AutoLoad>
    <Dialog title="{{articleTitle}}"><Dialog>
    <HTMLReader>{{content}}</HTMLReader>
    

    当页面打开的时候,会首先加载该模板,然后开始替换变量

    # 首次打开页面之后,变量替换之后的模板内容
    <AutoLoad>/article/2</AutoLoad>
    <Dialog title="title 2"><Dialog>
    <HTMLReader></HTMLReader>
    

    接着 AutoLoad 组件从指定的接口获取数据,预期此接口会返回数据格式如下:

    {
        "updatePart": {
            "ops": [
                {
                    "$set": {
                        "article": {
                            "articleTitle": "title 2 from server",
                            "content": "...",
                            ...
                        }
                    }
                }
            ]
        }
    }
    

    客户端根据 updatePart 的结果对当前已有的数据进行操作,结果如下:

    {
        "articleList": [
            {"id": 1, "title": "xxx xxx"},
            {"id": 2, "title": "xx xxxx xxx"},
            ...
        ],
        "id": 2,
        "rename": 2,
        "article": {                                 <- updatePart 新增的字段
            "articleTitle": "title 2 from server",
            "content": "...",
            ...
        }
    }
    

    取回数据后,模板开始第二次替换变量渲染(AutoLoad 因为只会在模板加载后首次生效,之后便不再生效),将页面标题设置为的新的标题,将 content 替换为文章内容。

    <!-- 不再生效的 <AutoLoad>/article/2</AutoLoad> -->
    <Dialog title="title 2 from server"><Dialog>
    <HTMLReader>...</HTMLReader>