模板语法

Lessjs 组件库是基于 Web Components 技术开发。在页面开发中,有些数据是需要通过接口请求异步得到的。当页面加载时,数据还未请求回来,这时内容并不能立即渲染到页面上。因此,我们可以使用 <template> 元素来编写不在页面呈现中显示的标记模板。当数据请求回来后,组件会立即渲染它的模板。

可以通过以下两种方式指定模板:

可以通过模板ID来指定页面中的任何模板。模板内必须只有一个根元素

<spz-render layout="container" template="render-template"></spz-render>
<template id="render-template">
  <div>
    Render Outer Template
  </div>
</template>

将模板嵌套在组件元素内部,成为组件元素的子元素。

<spz-render layout="container">
  <template>
    <div>
      Render Inner Template
    </div>
  </template>
</spz-render>

在模板内部,可以使用 data 来获取组件注入的数据。当使用 data 内的第一层级属性时,可以省略 data 字段。

语法规范:

  • ||&& 和三元操作符(?:)前后不支持空格,例如:${data.name||data.handle}
  • 不支持 =====!=!== 操作符
  • 不能写任何类型的注释

最基本的数据获取形式是文本插值,它使用的是占位符(一种由美元符号和大括号分隔的嵌入式表达式:${})来取出数据。它在模板字符串用法一致。直接在元素中使用时,不需要反引号来包裹。以下例子展示了从模板中获取的文本数据:

<template>
  <div>
    <span>${data.name}</span>
    <!-- 等价于(仅展示,模版内不支持写注释) -->
    <span>${name}</span>
  </div>
</template>

原始 HTML

在非模版内使用占位符会将数据解释为纯文本,而不是获取的数据。

${data.name}
<div>${data.name}</div>

当模板内的数据不可以直接使用,需要通过函数来处理后使用时,可以在 ${} 中支持写IIFE(立即运行函数)来处理和呈现数据。我们不推荐在模版内函数做任何DOM操作,而仅仅是作为数据处理的作用。如果我们想要操作DOM元素,建议使用 spz-script 元素来实现。

<template>
  <div>
    <h3>${title}</h3>

    ${function() {
      const variants = (data.variants || []).map((variant) => {
        // ...
      });

      return `
        <div>
          <div spz-for="variant in variants">
            <!-- ... -->
          </div>
        </div>
      `;
    }()}
  </div>
</template>

支持在占位符中写三元表达式。

<spz-render layout="container">
  <template>
    <div>
      ${name ? name : 'not exist name'}
    </div>
</template>
</spz-render>

模版支持 spz-forspz-ifspz-else 三个命令。

spz-for

  • 基于原始数据多次渲染元素。期望的绑定值类型:Array | Object | Iterable
  • 指令值必须使用特殊语法 alias in expressionalias of expression 为正在迭代的元素提供一个别名:
<script id="render-json" type="application/json">
  [1, 2, 3, 4, 5]
</script>

<spz-render layout="container" src="script:render-json">
  <template>
    <ul>
      <li spz-for="value in data">${value}</li>
    </ul>
  </template>
</spz-render>

或者,你也可以为索引指定别名 (如果用在对象,则是键值):

<script id="render-index-json" type="application/json">
  [1, 2, 3, 4, 5]
</script>

<spz-render layout="container" src="script:render-index-json">
  <template>
    <ul>
      <li spz-for="(value, index) in data">${index} - ${value}</li>
    </ul>
  </template>
</spz-render>

spz-for 的默认方式是尝试就地更新元素而不移动它们。要强制其重新排序元素,你需要用特殊 attribute key 来提供一个排序提示:

<script id="render-key-json" type="application/json">
  [1, 2, 3, 4, 5]
</script>

<spz-render layout="container" src="script:render-key-json">
  <template>
    <ul>
      <li spz-for="(value, index) of data" key="value">${index} - ${value}</li>
    </ul>
  </template>
</spz-render>

注意: 在 spz-for 内,keyspz-if 属性不需要通过 ${} 占位符来取值,需要直接省略占位符,组件内部会给该命令内的这两个属性加上占位符。

spz-ifspz-else

这两个命令可以配对使用或者单独使用 spz-if 来做判断逻辑。

<script id="render-if-json" type="application/json">
  {
    "name": "lessjs"
  }
</script>

<spz-render layout="container" src="script:render-if-json">
  <template>
    <div>
      <div spz-if="${name === 'lessjs'}">Lessjs</div>
      <div spz-else>Not lessjs</div>

      <div>${name === 'lessjs' ? 'Lessjs' : 'Not Lessjs'}</div>
    </div>
</template>
</spz-render>

支持从接口中获取数据的组件都支持写法。特殊的例如 spz-countdown 元素,它不会从接口中获取数据,但是它会将倒计时间的数据传递给模板内,用户可以自定义自己想要的呈现样式。

本页目录