html表格本身不渲染数据,需依赖模板引擎执行变量替换、转义及空值处理;jekyll/hugo中常见空列、错位或[object object]问题,根源在于yaml解析错误、模板语法误用或路径引用不当,eleventy通过预处理数据结构可规避模板逻辑复杂性与xss风险。

HTML表格本身不渲染数据,静态网站生成器(SSG)里也一样——它只输出结构,数据得靠模板引擎塞进去。你写 <table><tr><td>{{ item.name }}</td></tr></table>,最终能否正确显示,取决于模板引擎是否执行了变量替换、是否转义、是否处理了空值或嵌套结构。
为什么 Jekyll/Hugo 中的表格常出现空行或错位
常见现象是:本地预览正常,部署后某列全空;或 {{ page.data }} 渲染成 [object Object];或 YAML 数组被当成字符串拼进 <td> 里。<ul>
<li>YAML 中的列表若没缩进对齐,会被解析成字符串而非数组,导致 <code>for 循环不触发
.Params.items 若定义为 items: ["a", "b"],模板中必须用 {{ range .Params.items }},不能直接 {{ .Params.items }}
page.author 缺失),{{ page.author }} 会留白,而 {{ page.author | default: "未知" }} 才安全<td>),浏览器自动补 <code><td>,但位置不可控,视觉错位<h3>Eleventy 中用 <code>renderData 控制表格内容生成时机
Eleventy 的优势在于能提前把原始数据加工成表格所需格式,避免模板里写逻辑。比如原始 Markdown front matter 是扁平对象,但表格需要二维数组:
---
title: 成绩表
students:
- name: 张三
math: 85
english: 92
- name: 李四
math: 76
english: 88
---
在 .eleventy.js 中加计算属性:
eleventyConfig.addCollection("scoreTable", function(collection) {
return collection.getFilteredByTag("score").map(page => ({
...page,
tableRows: page.data.students.map(s => [s.name, s.math, s.english])
}));
});
模板里就直接用 {{ page.tableRows }} 渲染,不用在 Njk 或 Liquid 里做 map/filter —— 减少模板复杂度,也避免 XSS 风险(因为数据已结构化,不拼 HTML 字符串)。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
VuePress/VitePress 中 v-for 渲染表格要防 key 错乱
在 VuePress 的 Markdown 文件里嵌入 Vue 组件时,容易忽略 key 必须唯一且稳定。比如这样写:
<template><table><tbody><tr v-for="(row, i) in data" :key="i">
<td>{{ row.name }}</td>
<td>{{ row.score }}</td>
</tr></tbody></table></template>
当数据按 score 排序后,i 不再对应原始索引,Vue 会复用旧 DOM 节点,导致姓名和分数错位。正确做法是用业务字段(如 row.id)或哈希值作 key:
- 确保数据源有唯一标识字段(如
id或name + timestamp组合) - 避免用
Math.random()或Date.now()生成 key,会导致每次重渲染都重建节点 - 如果数据无 ID,可用
JSON.stringify(row)作 key(仅限小数据量,性能差)
真正麻烦的不是“怎么让表格显示出来”,而是“怎么让表格在数据变更、排序、筛选后仍保持语义正确和 DOM 稳定”。SSG 生成的是快照,但用户看到的页面可能被 JS 动态修改——这两层渲染逻辑一旦脱节,错位、丢失状态、XSS 就都来了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










