使用 Ant design X vue 组件库怎么解决无法正确展示 MarkDown 格式字符串的问题? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
tiRolin
V2EX    Vue.js

使用 Ant design X vue 组件库怎么解决无法正确展示 MarkDown 格式字符串的问题?

  •  
  •   tiRolin 272 天前 2022 次点击
    这是一个创建于 272 天前的主题,其中的信息可能已经有所发展或是发生改变。

    是这样的,我毕设搞了一个 AI 对话,但是呢,这个 AI 对话返回的字符串是 markdown 格式,但是我前端无法正确解析,最后字符串格式就会变成下面这样

    这里显然没有正确解析出样式来,我试了很多方法都没能解决这个问题,各个 ai 问了个遍了,然后去网上找了好多方法,还是没搞定,下面是我这个页面的源码,有没有大佬帮我看看到底该怎么解决这个问题啊?小弟我感激不尽啊

    <template> <div class="layout"> <div class="menu"> <RouterLink to="/" class="re-home">返回首页</RouterLink> <!-- Logo --> <div class="logo"> <img :src="logo" draggable="false" alt="logo" class="logo-img" /> <span class="logo-span">柑橘智能问答</span> </div> </div> <div class="chat"> <!-- 消息列表 --> <Bubble.List :items="messages" class="messages" style="flex: 1" :messageRender="renderMarkdown" :roles="{ ai: { placement: 'start', typing: { step: 5, interval: 20 }, styles: { content: { borderRadius: '16px' } } }, local: { placement: 'end', variant: 'shadow' } }" /> <!-- 输入框 --> <Sender :value="content" class="sender" @submit="onSubmit" @update:value="(val) => (cOntent= val)" /> </div> </div> </template> <script setup> import { ref, h } from 'vue' import { Conversations, Prompts, Sender, Bubble } from 'ant-design-x-vue' import { Edit, Delete } from '@element-plus/icons-vue' import reqAIChat from '@/api/chat/index' import { message } from 'ant-design-vue' import { ElMessage } from 'element-plus' import logo from '@/assets/images/logo.png' import { marked } from 'marked' import hljs from 'highlight.js' import 'highlight.js/styles/github.css' marked.setOptions({ highlight: (code) => hljs.highlightAuto(code).value, breaks: true, gfm: true }) marked.use({ renderer: { link(href, title, text) { return `<a href="${href}" target="_blank" rel="noopener">${text}</a>` } } }) const renderMarkdown = (content, item) => { if (item?.isMarkdown) { return h('Typography', { class: 'markdown-container' }, [ h('div', { innerHTML: marked.parse(content), // Vue 3 直接注入 HTML class: 'markdown-body' }) ]) } return content // 普通文本直接返回 } const cOntent= ref('') const messages = ref([ { key: '1', content: '## Markdown 测试\n[链接]( https://x.ant.design)1. **橙( Orange )**:包括甜橙和酸橙,甜橙中又分为脐橙、瓦伦西亚橙等。2. **柑橘( Mandarin )**:也称为蜜橘,包括各种小型、易剥皮的柑橘。3. **柚子( Pomelo )**:也称为文旦,是柑橘类中最大的一种。4. **柠檬( Lemon )**:以其酸味和香气闻名。5. **青柠( Lime )**:比柠檬小,酸味较轻。6. **葡萄柚( Grapefruit )**:大小和形状类似葡萄,味道可以是甜的也可以是酸的。', role: 'ai', variant: 'primary', isMarkdown: true } ]) const activeKey = ref('0') const cOnversationsItems= ref( Array.from({ length: 2 }).map((_, index) => ({ key: `item${index + 1}`, label: `未命名对话 ${index + 1}` })) ) const OnSubmit= async (nextContent) => { if (!nextContent) return messages.value.push({ key: `${messages.value.length + 1}`, content: nextContent, role: 'local', variant: 'shadow' }) content.value = '' try { const res = await reqAIChat({ message: nextContent }) if (!res) { ElMessage({ message: '请求失败', type: 'error' }) return } messages.value.push({ key: `${messages.value.length + 1}`, content: res, role: 'ai', variant: 'primary', isMarkdown: true }) } catch (error) { ElMessage({ message: '请求出错', type: 'error' }) } } const OnAddConversation= () => { conversationsItems.value.push({ key: `${conversationsItems.value.length + 1}`, label: `未命名对话${conversationsItems.value.length + 1}` }) activeKey.value = `${conversationsItems.value.length + 1}` } const menuCOnfig= (conversation) => { return { items: [ { label: '编辑', key: 'edit', icon: () => h(Edit) }, { label: '删除', key: 'delete', icon: () => h(Delete), danger: true } ], onClick: (menuInfo) => { message.info(`点击 ${conversation.key} - ${menuInfo.key}`) } } } </script> <style scoped> .markdown-body { padding: 12px 16px; line-height: 1.7; /* 必须继承字体 */ font-family: inherit; /* 代码块样式 */ pre { padding: 12px; border-radius: 8px; background: #f6f8fa !important; } code { font-family: 'SFMono-Regular', Consolas, monospace; } } .markdown-body { line-height: 1.6; color: #333; } .re-home { display: inline-block; padding: 10px 20px; margin: 12px; background: #ffa500; color: white; text-decoration: none; border-radius: 4px; font-size: 14px; font-weight: bold; text-align: center; transition: background-color 0.3s ease; } .layout { width: 100%; min-width: 1000px; height: 722px; display: flex; background: #fff; font-family: AlibabaPuHuiTi, sans-serif; } .menu { padding: 24px 0; /* background: #fff; */ width: 280px; height: 100%; display: flex; flex-direction: column; background: rgba(245, 245, 245, 0.5); } .logo { display: flex; height: 72px; align-items: center; justify-content: start; padding: 0 24px; } .logo-img { width: 24px; height: 24px; } .logo-span { margin: 0 8px; font-weight: bold; color: #333; font-size: 16px; } .add-btn { background: #1677ff0f; border: 1px solid #1677ff34; width: calc(100% - 24px); cursor: pointer; margin: 0 12px 24px 12px; font-size: 14px; height: 32px; padding: 4px 15px; border-radius: 6px; } .add-btn:hover { color: #69b1ff; } .chat { height: 100%; width: 100%; max-width: 700px; margin: 0 auto; box-sizing: border-box; display: flex; flex-direction: column; padding: 24px; gap: 16px; } </style> 

    这里 content 里已经有一些写死的内容了,那是我用来测试的,就是想着如果可以解析了那么这些写死的内容是会被正确解析上去的,但是我看了好久都没搞懂该怎么解决这个问题,所以这个写死的内容也一直留着了

    4 条回复    2025-03-17 21:59:32 +08:00
    learnshare
        1
    learnshare  
       272 天前
    跟所用的 UI 框架无关,需要将 Markdown 渲染为 HTML
    https://github.com/markdown-it/markdown-it
    learnshare
        2
    learnshare  
       272 天前
    很久以前的代码可以参考,但相关 API 有点不同
    https://github.com/LearnShare/markdown.css/blob/master/index.js#L27
    Linho1219
        3
    Linho1219  
       272 天前
    翻了文档,Bubble.List 应该是不支持 messageRender 属性的,只有 Bubble 支持。试了一下,把 .List 去掉,content 传入字符串就能正常渲染了。所以可以考虑用 v-for 和 Bubble 一起来实现。

    文档: https://antd-design-x-vue.netlify.app/component/bubble#api

    多看文档、在能够复现问题的前提下将项目文件裁剪到最小!出问题的就是 Bubble ,带了一箩筐页面和样式什么的,发出来这么长。把不影响的部分先删掉也方便你自己定位问题。
    都毕设了,我想你应该是有能力独立解决这个问题的。我之前都没碰过这个 ant design X ,花一会时间也找到了
    shintendo
        4
    shintendo  
       272 天前
    楼上+1 ,提问时尽量找最小复现,在这个过程中很可能自己就定位到问题了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1067 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 23:52 PVG 07:52 LAX 15:52 JFK 18:52
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86