Skip to content

自定义块组件

内置块

v2 内置 8 个块组件:

块语法组件说明
:::alertAlertBlock告警提示(info/success/warning/error)
:::cardDataCard数据卡片
:::confirmConfirmBlock确认操作
:::selectSelectBlock选择/消歧
:::formFormBlock动态表单
:::progressProgressBlock进度展示
:::datatableDataTableBlock数据表格
:::actionsActionPills快捷操作气泡
:::artifactArtifactBlockArtifact 内容面板(代码/HTML/SVG/文档)

详细用法见 Agent 交互组件

:::alert

markdown
::: alert info
信息提示
:::

::: alert warning
注意提示
:::

:::card

markdown
::: card 卡片标题
支持 **Markdown** 内容、表格等。
:::

通过 defineBlock 注册自定义块 v3 推荐

v3 提供 defineBlock 统一 API —— 一行声明即可打通 markdown-it 容器、componentMap、info-string 解析、Props 校验、LLM prompt 文档。

vue
<script setup lang="ts">
import { MarkdownRenderer, defineBlock } from '@krishanjinbo/vue-markdown-stream'
import JobCardBlock from './components/JobCardBlock.vue'
import SkillRadarBlock from './components/SkillRadarBlock.vue'

const blocks = [
  defineBlock({
    name: 'job-card',
    component: JobCardBlock,
    parseInfo: 'json',              // :::job-card {"title":"..."}
  }),
  defineBlock({
    name: 'skill-radar',
    component: SkillRadarBlock,
    parseInfo: 'json',
    schema: { items: { type: 'array', maxLength: 20 } },
    docs: {
      description: '技能雷达图',
      example: '::: skill-radar {"items":[{"name":"Vue","score":9}]}\n\n:::',
    },
  }),
]
</script>

<template>
  <MarkdownRenderer :content="text" :blocks="blocks" streaming />
</template>

parseInfo 四种策略

策略::: 语法组件 props
'attrs'(默认):::confirm action=delete level=danger{ action, level }
'json':::job-card {"title":"前端"}整个对象注入 data-props
'title':::card 技术栈对比{ title: '技术栈对比' }
(rest) => {...}自定义函数返回对象;__props 字段会进 JSON payload

工厂式:一次配置,全应用复用

typescript
// app/markdown.ts
import { createMarkdownStream, defineBlock } from '@krishanjinbo/vue-markdown-stream'
import JobCard from './blocks/JobCard.vue'

export const { MarkdownRenderer } = createMarkdownStream({
  blocks: [defineBlock({ name: 'job-card', component: JobCard, parseInfo: 'json' })],
})

// 任意页面
// <MarkdownRenderer :content="text" streaming />

详见 Block Registry APIcreateMarkdownStream

通过 Props 注册自定义组件(v2 兼容写法)

如果你还在用 v2 的 components prop,完全兼容:

vue
<script setup lang="ts">
import { MarkdownRenderer } from '@krishanjinbo/vue-markdown-stream'
import MyChartBlock from './components/MyChartBlock.vue'

const customComponents = {
  ChartBlock: MyChartBlock,
}

const customSchemas = {
  ChartBlock: {
    allowed: {
      type: { type: 'enum', enum: ['bar', 'line', 'pie'], default: 'bar' },
      title: { type: 'string', maxLength: 50 },
    },
  },
}
</script>

<template>
  <MarkdownRenderer
    :content="text"
    :components="customComponents"
    :props-schemas="customSchemas"
  />
</template>

TIP

自定义组件会与内置组件合并,同名时用户组件优先。新项目建议使用 defineBlock —— 它在 v2 机制之上补齐了 info-string 解析、docs 元信息与 LLM prompt 生成。

Props 传递规则

data-* 属性会被自动提取并转换为 props:

Markdown 属性转换组件 prop
data-type="warning"kebab→camelCasetype="warning"
data-confirm-text="OK"kebab→camelCaseconfirmText="OK"

v2 新增 PropValidator 对 props 做类型转换:

Schema 类型转换规则
string截断到 maxLength
numberNumber() + min/max clamp
boolean'true'/'1'/'yes'true
enum不在允许列表内 → default

Slot 内容

<vue-block> 标签内的内容(已被 markdown-it 渲染为 HTML)会作为 default slot 传入组件。组件使用 <slot /> 接收即可。

安全机制

Props 经过两层过滤:

  1. 全局黑名单onclickinnerHTMLstylehrefsrc 等危险属性永远被过滤
  2. 组件白名单 — 每个组件只接受 schema 中声明的 props,未声明的被丢弃

Released under the MIT License.