You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React-Quill中集成highlight.js并解决代码高亮消失问题

React-Quill代码块高亮丢失及语言类名设置解决方案

问题根源

  1. 原生syntax模块的highlightAuto无法精准匹配语言,且Quill默认不会为<pre><code>标签添加对应语言类名
  2. 编辑内容时Quill会重新渲染DOM,未被持久化的高亮样式会被重置

修复后的完整代码

import React, { useState } from 'react';
import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.snow.css';
import hljs from 'highlight.js';
import 'highlight.js/styles/github.css';

// 配置支持的语言列表
const supportedLanguages = [
  { value: 'javascript', label: 'JavaScript' },
  { value: 'python', label: 'Python' },
  { value: 'java', label: 'Java' },
  { value: 'cpp', label: 'C++' },
  { value: 'c', label: 'C' },
  { value: 'html', label: 'HTML' },
  { value: 'css', label: 'CSS' }
];

hljs.configure({
  languages: supportedLanguages.map(lang => lang.value)
});

export default function App() {
  const [value, setValue] = useState('');
  const [selectedLanguage, setSelectedLanguage] = useState('javascript');

  const modules = {
    syntax: {
      // 重写高亮函数,根据选中的语言处理
      highlight: (text, language) => {
        const lang = language || selectedLanguage;
        if (hljs.getLanguage(lang)) {
          try {
            const result = hljs.highlight(text, { language: lang });
            // 给code标签添加语言类名
            return result.value.replace('<code>', `<code class="language-${lang}">`);
          } catch (_) {}
        }
        //  fallback到自动识别
        const result = hljs.highlightAuto(text);
        return result.value.replace('<code>', `<code class="language-${result.language}">`);
      }
    },
    toolbar: {
      container: [
        [{ header: [1, 2, false] }],
        ['bold', 'italic', 'underline', 'strike', 'blockquote'],
        [{ list: 'ordered' }, { list: 'bullet' }, { indent: '-1' }, { indent: '+1' }],
        ['link', 'image'],
        // 添加语言选择下拉和code-block按钮
        [{ 'code-block': supportedLanguages.map(lang => lang.value) }],
        ['clean']
      ],
      // 处理语言选择事件
      handlers: {
        'code-block': function(value) {
          if (value) {
            setSelectedLanguage(value);
          }
          this.quill.format('code-block', value);
        }
      }
    }
  };

  const formats = [
    'header',
    'bold', 'italic', 'underline', 'strike', 'blockquote',
    'list', 'bullet', 'indent',
    'link', 'image',
    // 确保code-block格式支持语言参数
    { 'code-block': supportedLanguages.map(lang => lang.value) }
  ];

  return (
    <>
      <ReactQuill 
        theme="snow" 
        value={value} 
        modules={modules} 
        formats={formats} 
        onChange={setValue} 
      />
      <button onClick={() => console.log(value)}>查看带格式内容</button>
    </>
  );
}

关键修改说明

  • 扩展工具栏:给code-block添加语言选择下拉菜单,通过handlers捕获语言选择事件,同步当前选中语言
  • 重写高亮逻辑:不再依赖highlightAuto,优先使用选中的语言进行高亮,同时给<code>标签添加language-xxx类名,确保样式持久化
  • 格式配置:更新formats数组,让Quill支持带语言参数的code-block格式
  • 语言持久化:通过状态selectedLanguage保存当前选中的语言,确保插入代码块时使用正确的语言类型

额外提示

  • 可以根据需求调整supportedLanguages列表,添加更多highlight.js支持的语言
  • 如果需要渲染外部传入的带语言类名的代码块,可以在组件挂载时手动调用hljs.highlightAll()触发全局高亮

内容的提问来源于stack exchange,提问作者Sujan Ch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 12:47:20