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

如何在react-codemirror组件中实现指定文本高亮(如单个字符标红)

解决React-CodeMirror高亮特定字符的问题

要实现aTest bTest cTest中的a、b、c字符红色高亮,你需要用CodeMirror 6的Decoration(装饰)系统来实现,而不是旧版的markTextAPI。下面是完整的实现方案:

完整代码示例

import { useRef, useEffect } from 'react';
import { CodeMirror } from '@uiw/react-codemirror';
import { Decoration, DecorationSet } from '@codemirror/view';
import { EditorState } from '@codemirror/state';

// 定义高亮装饰器:这里直接内联样式,也可以用类名(推荐)
const highlightDecoration = Decoration.mark({
  attributes: { style: 'color: red; font-weight: bold;' }
});

// 或者用类名方式(需配合CSS)
// const highlightDecoration = Decoration.mark({ class: 'highlight-red' });

const HighlightEditor = () => {
  const editorRef = useRef(null);
  const decorationsRef = useRef(DecorationSet.empty);

  // 扫描文本,生成所有需要高亮的字符范围
  const updateHighlights = (view) => {
    if (!view) return;
    const { state } = view;
    const decorations = [];
    const text = state.doc.toString();

    // 遍历文本,匹配a/b/c字符
    for (let i = 0; i < text.length; i++) {
      if (['a', 'b', 'c'].includes(text[i])) {
        decorations.push(highlightDecoration.range(i, i + 1));
      }
    }

    // 更新装饰集合并应用到编辑器
    decorationsRef.current = DecorationSet.create(state.doc, decorations);
    view.dispatch({
      effects: Decoration.set(decorationsRef.current, true)
    });
  };

  useEffect(() => {
    const view = editorRef.current?.view;
    if (!view) return;

    // 初始化时执行高亮
    updateHighlights(view);

    // 监听编辑器内容变化,自动更新高亮
    const updateListener = view.updateListener.of((update) => {
      if (update.docChanged) {
        updateHighlights(view);
      }
    });

    // 组件卸载时清理监听
    return () => {
      view.dispatch({ effects: updateListener.destroy() });
    };
  }, []);

  return (
    <CodeMirror
      ref={editorRef}
      basicSetup={{ lineNumbers: false }}
      value="aTest bTest cTest"
      onChange={(value) => console.log("value:", value)}
    />
  );
};

export default HighlightEditor;

关键要点说明

  1. 使用Decoration系统:CodeMirror 6推荐用装饰系统来处理文本标记,Decoration.mark可以创建文本范围的样式装饰,比旧版markText更灵活,符合新版的状态管理逻辑。

  2. 处理内容更新:通过view.updateListener监听文档变化,每次内容修改后重新扫描文本并更新高亮,避免内容变化后高亮失效。

  3. 样式的两种方式:

    • 内联样式:直接在装饰器里写style属性,适合简单场景。
    • 类名方式:定义CSS类(比如.highlight-red { color: red; }),装饰器用class属性,方便样式复用和维护。

你之前代码的问题

  • API版本不匹配:你用了view.markText,这是CodeMirror 5的API,而react-codemirror基于CodeMirror 6,API已经变更。
  • 依赖项错误:useEffect依赖refs.current不会正确触发,因为ref的引用不会随内部属性变化而更新,应该用空依赖+内部监听。
  • 未处理内容更新:只在初始化时标记,输入新内容后不会重新高亮。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 04:55:30