4、小程序开发语言入门(TTML):模板语法与数据绑定

好,咱们进入正题。TTML 是抖音小程序的标记语言,说白了就是用来写页面结构的。你把它想象成 HTML 的亲戚就行,但规矩更严,能力也更强。

我个人习惯把 TTML 看作「带电池的 HTML」。为什么这么说?因为它内置了数据绑定、条件判断、循环渲染这些能力。你不需要额外引入 Vue 或 React,开箱即用。

4.1 数据绑定:{{}} 双花括号

这是最基础、也最常用的语法。在 TTML 里,你想把 JS 里的数据展示到页面上,就用 {{ }} 包起来。

<!-- 页面显示:你好,抖音小程序 -->
<view>你好,{{ name }}</view>

对应的 JS 文件里,你需要在 data 中定义这个变量:

Page({
  data: {
    name: '抖音小程序'
  }
})

我在项目中遇到过一个问题:新手容易把 {{ }} 用在标签属性里,比如 <view id="{{ itemId }}">,这是完全 OK 的。但注意,不能用在 tt:if 这类指令的值外面,比如 tt:if="{{ show }}" 是对的,但 tt:if="show" 就不行。

小技巧: 数据绑定支持表达式。比如 {{ count + 1 }}{{ '前缀' + text }}{{ flag ? '是' : '否' }}。但不能写复杂的语句,比如 iffor 循环。

4.2 条件渲染:tt:if 家族

条件渲染就是「根据条件决定显示哪块内容」。TTML 提供了三个指令:tt:iftt:eliftt:else

<view tt:if="{{ score >= 90 }}">优秀</view>
<view tt:elif="{{ score >= 60 }}">及格</view>
<view tt:else>不及格</view>

嗯,这里要注意:tt:elif 必须紧跟在 tt:if 后面,中间不能有其他元素。否则条件判断会断裂。

我曾经踩过一个坑:用 hidden 属性代替 tt:if 来控制显示隐藏。两者有什么区别?tt:if 是「真·销毁重建」,条件为 false 时 DOM 节点直接不存在;而 hidden 只是用 display: none 隐藏。如果你的组件初始化很重(比如有复杂计算),用 tt:if 反而更省性能。反之,频繁切换的场景用 hidden 更好。

注意: 不要同时使用 tt:ifhidden 控制同一个元素,逻辑会打架。选一个就行。

4.3 列表渲染:tt:for

循环渲染是写列表页的必备技能。语法很简单:

<view tt:for="{{ items }}" tt:key="id">
  {{ index }} - {{ item.name }}
</view>

这里有几个关键点:

  • tt:for 绑定一个数组
  • 默认的循环变量是 item,索引是 index
  • 你可以用 tt:for-item="myItem"tt:for-index="myIndex" 重命名
  • 必须提供 tt:key,用来提升渲染性能

你想想看,如果不写 tt:key,小程序会怎么处理?它会用索引作为 key。一旦列表顺序变了(比如你删除了第一项),整个列表都会重新渲染。加了 key 之后,框架能精准定位哪些元素需要更新。

我个人习惯用数据的唯一 ID 作为 key,比如 tt:key="id"。如果数据没有 ID,也可以用 tt:key="*this",意思是把整个 item 当作 key——但前提是 item 是基本类型(字符串、数字),不能是对象。

避坑指南: 我曾经在循环里嵌套循环,结果忘了给内层循环重命名 item,导致内外层变量冲突。记住:嵌套循环时一定要用 tt:for-item 指定不同的变量名。

4.4 模板与引用:复用代码

写页面时,经常会有重复的 UI 片段。比如商品卡片、用户头像、列表项。TTML 提供了 <template> 来定义可复用的模板。

先定义模板:

<template name="productCard">
  <view class="card">
    <image src="{{ img }}"></image>
    <text>{{ title }} - ¥{{ price }}</text>
  </view>
</template>

然后在需要的地方引用:

<template is="productCard" data="{{ ...item }}" />

这里 data 属性用来传递数据。我用 ...item 展开对象,这样模板里就能直接使用 imgtitleprice 这些字段。

模板可以放在当前页面文件里,也可以抽成单独的 .ttml 文件,用 <import> 引入。不过我个人建议:如果模板只在当前页面用,直接写在文件底部;如果多个页面共用,就抽成独立文件。

进阶用法: 模板支持嵌套。你可以在一个模板里引用另一个模板。但注意不要形成循环引用,小程序会报错。

4.5 实战经验总结

说了这么多,我总结几条实战中容易忽略的点:

知识点 常见错误 正确做法
数据绑定 在属性值里写 id="itemId" id="{{ itemId }}"
条件渲染 多个条件用 tt:if 堆叠 tt:if / tt:elif / tt:else 链式判断
列表渲染 忘记写 tt:key 始终提供唯一 key
模板引用 模板和数据作用域混淆 data 显式传递

最后说一句:TTML 的语法其实很轻量,你花半小时就能上手。但真正写出高性能、易维护的页面,需要你对数据流和渲染机制有深入理解。别急,后面几章我会带你一步步深入。

下一章我们聊 TTSS——也就是抖音小程序的样式语言。你会发现它和 CSS 很像,但有些坑你必须提前知道。