前言
目前各家公司的大模型应用如火如荼,除了大模型算法应答能力外,在前端交互上也有差异化展示。 期望在模型输出markdown
文本的表格时,能展示如下的表格样式与交互:

表格样式可以通过css
处理,但是表头上面的标题+按钮需要新增dom元素和js操作。
通常情况下,会想到在渲染表格后通过dom接口添加新的dom元素满足交互,稍显复杂,也不利于代码维护。而且模型输出,同一个页面上也可以存在多个表格,如果能抽离成组件使用,每个表格各自维护状态,互不影较好。
提到组件编写,可以采用笔者使用webcomponent
编写的自定义表格组件👉my-table
:Web Component用得少?在大模型中寻找使用场景,里面包含了表格样式、交互、以及状态维护。
my-table
组件编写完成且已完成注册,接下来就考虑如何与模型输出的markdown
表格渲染关联使用。
markdown
解析器
采用marked.js
解析器:marked.js.org
按照文档将引入项目内,由于我们需要对表格进行扩展,因此是针对表格渲染时处理,return返回的就是对应的表格html。
js
marked.use({
renderer: {
table(token){
return '<table>xxx</table>'
}
}
})
拓展表格交互
按照my-table
表格组件的入参,将marked.js
解析生成的表格html放在my-table
标签包裹即可。
由于renderer
函数是重写的,因此原有生成table的富文本也需要重写,当然不是让人从无到有地重写,这一点可以查阅marked.js
源码,复制原有的table renderer富文本格式,再使用my-table
标签包裹,一并return返回。
这是marked.js
中table renderer的源码(查阅GitHub:marked.js):

把table render的代码复制一份再稍微调整一下语言,最终return时使用自定义组件my-table
:
js
marked.use({
renderer: {
table(token){
let header = '';
// header
let cell = '';
for (let j = 0; j < token.header.length; j++) {
cell += this.tablecell(token.header[j]);
}
header += this.tablerow({ text: cell });
let body = '';
for (let j = 0; j < token.rows.length; j++) {
const row = token.rows[j];
cell = '';
for (let k = 0; k < row.length; k++) {
cell += this.tablecell(row[k]);
}
body += this.tablerow({ text: cell });
}
if (body) body = `<tbody>${body}</tbody>`;
// 这里使用自定义组件my-tabel包裹原来的table文本
return `
<my-table>
<table>
<thead>${header}</thead>
${body}
</table>
</my-table>
`;
}
}
})
经过重写table renderer的处理,解析输出的表格富文本自带了my-table
标签,在页面渲染时能直接渲染出对应的样式与交互。
通过webcomponent
编写的表格浏览器原生支持,不用考虑前端技术栈。
最后
对markdown
文本输出的富文本添加自定义的样式与交互是很常见的操作,每个平台的主题风格、产品要求不尽相同。
文中提到的表格交互是比较复杂一点的,抽离成组件维护。一般场景没有这么复杂,没必要抽离组件,就在renderer
函数对应标签重新输出,或者为markdown
渲染的html提供css
文件即可。