mustache 渲染动态列表的关键在于数据结构与模板严格配对:模板中 {{#items}} 要求 data 中存在名为 items 的数组字段,否则静默失败;索引需预埋 index 字段;条件渲染需前置计算 selected 等布尔值;高频渲染应预编译模板。

Mustache 渲染动态列表,关键不是写对语法,而是把数据结构配对好——模板里写 {{#items}},数据里就必须有 items 字段,且值为数组;否则渲染为空,连报错都不会有。
为什么 {{#list}} 渲染不出来?检查三件事
常见现象:模板写了 {{#list}}<div>{{name}}</div>{{/list}},但页面空白,控制台也没报错。
- 确认传入的 data 对象里真有
list这个 key,不是dataList或items - 确认
list的值是数组(哪怕空数组[]),不是null、undefined或对象{} - 确认没在模板里误写成
{{#List}}(大小写敏感)或{{# list }}(空格会导致 lookup 失败)
{{#items}} 里怎么访问当前项的索引?
Mustache 原生不提供 {{@index}} 这类变量。想显示序号,得靠数据层“预埋”:
- 渲染前用
map给每项加index字段:data.items = items.map((item, i) => ({ ...item, index: i + 1 })) - 模板中直接用
{{index}}:{{#items}}<li>{{index}}. {{title}}</li>{{/items}} - 别试图在模板里用
{{@index}}或{{.}}推导——标准 Mustache 实现(包括mustache.js、Zap、facil.io)都不支持
列表项里需要条件渲染 selected 怎么办?
比如下拉框选项要根据当前值自动选中,不能写 {{#value == "a"}}——Mustache 没这种语法。
- 方案一(推荐):把选项做成数组,每项带
selected字段:{ options: [{ value: "a", label: "A", selected: true }, { value: "b", label: "B", selected: false }] } - 模板写法:
{{#options}}<option value="{{value}}" selected>{{label}}</option>{{/options}} - 方案二(简单场景):提前注入布尔字段,如
{ current: "b", selected_b: true },再用{{#selected_b}}selected{{/selected_b}}
性能注意点:频繁渲染别每次都 Mustache.render()
如果同一个模板被调用几十次(比如滚动加载列表),每次调用 Mustache.render(templateStr, data) 都会重新解析模板字符串,浪费 CPU。
- 改用预编译:
const compiled = Mustache.compile(templateStr),之后只调用compiled(data) - 注意:
Mustache.parse()是可选优化,仅当模板含大量 section 时才明显提速,普通小模板不用强求 - 服务端渲染(如
facil.io)建议复用mustache_s*指针,避免反复fiobj_mustache_load
最易被忽略的点:Mustache 的“无逻辑”是硬约束——所有判断、计算、格式化,都必须在数据准备阶段做完。模板里只放纯展示逻辑,否则要么写不出,要么绕远路 hack。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











