如何使用React实现AI聊天对话中的Markdown输出转换

前端 潘老师 来源:睡觉zzz 1周前 (04-14) 24 ℃ (0) 扫码查看

在开发AI聊天对话项目时,将聊天内容以Markdown格式输出并进行转换展示是一个常见需求。我在做相关项目时,发现网上资料有限,经过一番研究,总结出了一套实现方法。下面就给大家详细讲讲,主要是借助react-markdown ,搭配remark-gfmrehype-highlighthighlight.js等插件以及一些CSS样式来完成转换。先看下转换前后的效果图:

一、功能需求与实现思路

在AI聊天对话场景中,我们期望聊天内容能以Markdown格式呈现,像标题、列表、代码块、链接、图片等元素都能正确显示。比如输入一段包含各种Markdown元素的文本,经过处理后,在聊天界面中可以清晰地展示出对应的格式效果。

实现这个功能,关键在于利用合适的工具将Markdown文本转换为React组件。react-markdown库负责将Markdown文本转化为React组件,remark-gfm插件用来支持GitHub Flavored Markdown(GFM)的特性,像表格、任务列表等格式都能正常显示。同时,借助rehype-highlighthighlight.js实现代码块的语法高亮,再通过自定义CSS样式美化整体展示效果。

二、具体实现步骤

(一)创建ChatMessage组件

components文件夹下创建ChatMessage.jsx组件,这个组件用来处理聊天消息。实现时,需要安装react-markdownremark-gfm这两个库,命令如下:

npm install react-markdown remark-gfm

react-markdown能把Markdown文本转换为React组件,remark-gfm则为其添加对GFM格式的支持。以下是ChatMessage.jsx的代码:

import React from'react';
import ReactMarkdown from'react-markdown';
import remarkGfm from'remark-gfm';

const ChatMessage = ({ message, role }) => {
    return (
        role === 'assistant'? (
            <div className="chat-message">
                <ReactMarkdown remarkPlugins={[remarkGfm]}>
                    {message}
                </ReactMarkdown>
            </div>
        ) : (
            <div className="user-message">
                {message}
            </div>
        )
    );
};

export default ChatMessage;

这段代码接收message(聊天消息内容)和role(消息产生者)两个参数,根据role判断是助手消息还是用户消息,分别进行不同的展示。助手消息会通过ReactMarkdown组件将Markdown格式的message渲染出来,用户消息则直接显示。

(二)在聊天页面使用组件

在AI聊天页面中引入ChatMessage组件,假设聊天消息存储在messages数组中,每个消息对象包含idcontent(消息内容)和role等属性,实现代码如下:

import ChatMessage from '@/components/ChatMessage';

{/* 消息区域-添加固定高度和滚动 */}
<div className="flex-1 overflow-y-auto p-4 w-full max-w-4xl mx-auto">
    <div className="space-y-4 min-h-[calc(100vh-200px)]">
        {messages.map(message => (
            <div
                key={message.id}
                className={`flex flex-row ${message?.role === 'assistant'? 'justify-start' : 'justify-end'} mb-4`}>
                <div className={`max-w-[80%] rounded-2xl px-4 py-3 ${message?.role === 'assistant'? 'bg-blue-100 rounded-bl-none' : 'bg-indigo-100 rounded-br-none'}`}>
                    <div className={`text-gray-800 ${message?.role === 'assistant'? 'text-left' : 'text-right'}`}>
                        <ChatMessage message={message.content} role={message.role} />
                    </div>
                </div>
            </div>
        ))}
        <div ref={endRef} className="h-8" />
    </div>
</div>

这段代码遍历messages数组,根据消息的role决定消息在页面中的排版位置,并将每个消息传递给ChatMessage组件进行展示。

(三)美化Markdown格式

为了让Markdown内容展示得更美观,创建一个markdownStyles.css文件,添加以下样式代码:

/* 消息容器-添加平滑过渡和更现代的阴影 */
.chat-message {
    margin: 12px 0;
    padding: 16px;
    transition: all 0.2s ease;
}

/* 标题-添加渐变颜色和更好的间距 */
.chat-message h1 {
    color: #1a1a1a;
    border-bottom: 1px solid #eaeaea;
    padding-bottom: 8px;
    margin-bottom: 16px;
}

.chat-message h2 {
    color: #1e40af;
    margin-top: 24px;
}

/* 段落-优化行高和字体 */
.chat-message p {
    color: #4b5563;
    line-height: 1.8;
    font-size: 16px;
    margin-bottom: 16px;
}

/* 列表-更精致的样式 */
.chat-message ul {
    list-style-type: '• ';
    padding-left: 24px;
}

.chat-message ol {
    padding-left: 24px;
}

/* 代码块-更专业的语法高亮样式 */
.chat-message pre {
    background-color: #1e293b;
    color: #f8fafc;
    border-radius: 8px;
    font-family: 'SF Mono', Menlo, monospace;
    font-size: 14px;
    line-height: 1.5;
    margin: 16px 0;
}

/* 内联代码-更突出的样式 */
.chat-message code:not(pre code) {
    background-color: #f3f4f6;
    color: #dc2626;
    border-radius: 4px;
    font-size: 90%;
}

/* 链接-更明显的交互效果 */
.chat-message a {
    color: #2563eb;
    text-decoration: none;
    font-weight: 500;
    transition: color 0.2s;
}

.chat-message a:hover {
    color: #1d4ed8;
    text-decoration: underline;
}

/* 表格样式-新增 */
.chat-message table {
    width: 100%;
    border-collapse: collapse;
    margin: 16px 0;
}

.chat-message th,
.chat-message td {
    padding: 12px;
    border: 1px solid #e5e7eb;
}

.chat-message th {
    background-color: #f3f4f6;
}

/* 引用样式-新增 */
.chat-message blockquote {
    border-left: 4px solid #2563eb;
    background-color: #f8fafc;
    padding: 12px 16px;
    margin: 16px 0;
    color: #4b5563;
}

然后在ChatMessage组件中引入这个CSS文件,这样就能对Markdown元素进行样式美化,让聊天内容展示更清晰美观。如果觉得样式不符合需求,还可以根据实际情况进行修改。

(四)处理代码块

为了实现代码块的语法高亮,需要安装highlight.jsrehype-highlight这两个库,安装命令如下:

npm install highlight.js
npm install rehype-highlight

rehype-highlight插件用于帮助实现代码块的语法高亮,highlight.js则是一个流行的语法高亮库,支持多种编程语言。接下来在ChatMessage组件中引入这两个库并进行配置:

import React from'react';
import ReactMarkdown from'react-markdown';
import remarkGfm from'remark-gfm';
import rehypeHighlight from'rehype-highlight';
import hljs from 'highlight.js';
import './code.css';//引入代码段的css样式
import './markdownStyles.css';

const highlightCode = (node) => {
    // 处理代码段的函数
    if (node.tagName === 'pre') {
        const codeNode = node.children[0];
        if (codeNode.tagName === 'code') {
            const language = codeNode.properties.className?.[0]?.replace('language-', '');
            if (language && hljs.getLanguage(language)) {
                const highlightedCode = hljs.highlight(codeNode.children[0].value, { language }).value;
                codeNode.children[0].value = highlightedCode;
            }
        }
    }
    return node;
};

const ChatMessage = ({ message, role }) => {
    return role === 'user'? (
        <div>{message}</div>
    ) : (
        <div className="chat-message">
            <ReactMarkdown
                remarkPlugins={[remarkGfm]}
                rehypePlugins={[rehypeHighlight, () => highlightCode]}
            >
                {message}
            </ReactMarkdown>
        </div>
    );
};

export default ChatMessage;

上述代码定义了highlightCode函数,用于处理代码块的高亮显示。在ReactMarkdown组件中,通过rehypePlugins配置rehypeHighlighthighlightCode函数,实现代码块的语法高亮。code.css样式文件可以从highlight.js/styles/atom-one-dark.css修改而来,根据实际需求调整样式,让代码块展示更美观。

三、总结

通过上述步骤,我们成功在React项目中实现了AI聊天对话的Markdown输出转换和美化。从创建组件处理消息,到利用插件实现Markdown解析和代码高亮,再到通过CSS样式美化展示效果,每个环节紧密配合。如果在实现过程中遇到问题,欢迎交流。希望这篇文章能帮助大家在相关项目开发中少走弯路。


版权声明:本站文章,如无说明,均为本站原创,转载请注明文章来源。如有侵权,请联系博主删除。
本文链接:https://www.panziye.com/front/17194.html
喜欢 (0)
请潘老师喝杯Coffee吧!】
分享 (0)
用户头像
发表我的评论
取消评论
表情 贴图 签到 代码

Hi,您需要填写昵称和邮箱!

  • 昵称【必填】
  • 邮箱【必填】
  • 网址【可选】