首页
/ Tiptap编辑器@提及功能全攻略:从技术选型到企业级实践

Tiptap编辑器@提及功能全攻略:从技术选型到企业级实践

2026-04-15 08:26:31作者:薛曦旖Francesca

痛点分析

在开发富文本编辑器时,实现@用户提及功能往往比想象中复杂。我们团队曾遇到三个典型难题:触发字符输入后建议列表卡顿、大量用户数据导致的性能问题、以及多类型提及(用户/标签)的冲突处理。特别是在协作场景下,传统实现方案要么扩展性不足,要么需要编写大量自定义逻辑,平均开发周期超过10天。

技术选型

实现方案 复杂度 灵活性 性能 适用场景
原生ProseMirror插件 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ 深度定制需求
Tiptap Mention扩展 ⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐ 快速集成场景
第三方UI库集成 ⭐⭐⭐ ⭐⭐ ⭐⭐ 简单交互需求

我们在项目中发现,Tiptap的Mention扩展是平衡开发效率和功能完整性的最佳选择。它就像一个预制好的乐高积木套装,既保留了核心功能,又允许通过配置进行个性化定制。

分步实现

1. 环境准备

📌 首先克隆项目并安装依赖:

git clone https://gitcode.com/GitHub_Trending/ti/tiptap
cd tiptap
npm install @tiptap/core @tiptap/extension-mention @tiptap/react

2. 基础配置

创建基础编辑器组件,配置Mention扩展核心参数:

import { Editor, EditorContent } from '@tiptap/react'
import Mention from '@tiptap/extension-mention'

const MentionEditor = () => {
  const editor = useMemo(() => {
    return new Editor({
      extensions: [
        // 其他必要扩展...
        Mention.configure({
          // 基础样式配置
          HTMLAttributes: { class: 'mention' },
          // 建议系统配置
          suggestion: {
            // 触发字符
            char: '@',
            // 数据源处理
            items: ({ query }) => {
              // 这里可以替换为API请求
              return users.filter(user => 
                user.name.toLowerCase().includes(query.toLowerCase())
              ).slice(0, 5)
            }
          }
        })
      ],
      content: '<p>开始输入@提及用户...</p>'
    })
  }, [])

  return <EditorContent editor={editor} />
}

⚠️ 注意:确保同时加载Document、Paragraph和Text等基础扩展,否则编辑器可能无法正常工作。

3. 自定义建议UI

创建React组件替代默认下拉框:

// 自定义建议组件
const SuggestionList = ({ items, onSelect }) => (
  <div className="suggestion-menu">
    {items.map(item => (
      <div 
        key={item.id}
        onClick={() => onSelect(item)}
        className="suggestion-item"
      >
        <img src={item.avatar} alt={item.name} />
        <span>{item.name}</span>
      </div>
    ))}
  </div>
)

// 在编辑器中集成
Mention.configure({
  suggestion: {
    // ...其他配置
    render: () => {
      return {
        onStart: props => {
          // 渲染自定义组件
          render(<SuggestionList {...props} />, document.body)
        },
        // 其他生命周期方法...
      }
    }
  }
})

4. 前后端协作流程

实现完整的提及功能需要前后端配合:

  1. 前端触发:用户输入@字符后发送查询请求
  2. 后端处理:接收查询参数,返回匹配用户列表
  3. 前端渲染:展示建议列表并处理选择事件
  4. 数据存储:将提及信息以特定格式保存到数据库
  5. 前端展示:从数据库加载内容时渲染提及标签
// API请求示例(使用axios)
const fetchUsers = async (query) => {
  const response = await axios.get('/api/users', { 
    params: { query, limit: 5 } 
  })
  return response.data
}

// 在suggestion.items中使用
items: async ({ query }) => fetchUsers(query)

5. 样式与交互优化

添加基础样式并优化用户体验:

.mention {
  background: #e8f0fe;
  border-radius: 4px;
  padding: 0 2px;
  color: #1967d2;
}

.suggestion-menu {
  position: absolute;
  background: white;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.15);
  min-width: 200px;
}

.suggestion-item {
  padding: 8px 12px;
  display: flex;
  align-items: center;
  cursor: pointer;
  
  &:hover {
    background: #f5f5f5;
  }
}

场景拓展

1. 评论系统中的@通知

在社交产品评论区,用户@其他用户后需要发送实时通知。实现方案:

// 监听编辑器内容变化
editor.on('update', ({ editor }) => {
  const content = editor.getHTML()
  const mentions = extractMentions(content)
  
  // 发送提及数据到后端
  if (mentions.length > 0) {
    axios.post('/api/mentions', { 
      contentId: currentContentId,
      mentions 
    })
  }
})

2. 工单系统中的标签关联

在企业工单系统中,使用#标签关联任务类型:

// 多触发配置
Mention.configure({
  suggestions: [
    {
      char: '@',
      pluginKey: 'user-mention',
      items: ({ query }) => fetchUsers(query)
    },
    {
      char: '#',
      pluginKey: 'tag-mention',
      items: ({ query }) => fetchTags(query)
    }
  ]
})

3. 知识库协作编辑

在多人协作的知识库系统中,需要显示用户编辑位置:

import Collaboration from '@tiptap/extension-collaboration'
import CollaborationCaret from '@tiptap/extension-collaboration-caret'

// 同时集成协作和提及扩展
extensions: [
  Collaboration.configure({ document: ydoc }),
  CollaborationCaret.configure({
    users: [
      { id: 'user-1', name: '张三', color: '#ff0000' },
      // 其他用户...
    ]
  }),
  Mention.configure({ /* 配置 */ })
]

避坑指南

问题诊断树

  1. 提及节点无法删除

    • 检查deleteTriggerWithBackspace配置
    • 确认是否自定义了键盘事件处理
  2. 建议列表不显示

    • 验证items函数是否正确返回数据
    • 检查CSS是否隐藏了建议框
    • 确认render函数实现是否正确
  3. 性能问题

    • 实现查询防抖(300ms最佳)
    • 添加结果缓存机制
    • 对长列表实现虚拟滚动
// 防抖实现示例
import { debounce } from 'lodash'

const fetchUsers = debounce(async (query) => {
  const response = await axios.get('/api/users', { params: { query } })
  return response.data
}, 300)

API参数速查表

参数 类型 默认值 描述
char string '@' 触发字符
HTMLAttributes object {} 提及节点的HTML属性
suggestion object {} 建议系统配置
deleteTriggerWithBackspace boolean false 是否允许退格删除触发字符

浏览器兼容性

浏览器 支持版本 注意事项
Chrome 60+ 完全支持
Firefox 63+ 建议使用最新版本
Safari 12+ 部分样式可能需要调整
Edge 79+ 完全支持

交互效果演示

当用户输入@字符时,编辑器下方会显示匹配的用户列表,支持键盘上下键选择和Enter确认。选择后会插入格式化的提及标签,标签带有特殊背景色和字体颜色,鼠标悬停时会显示用户详情卡片。

工具函数库

我们封装了常用工具函数,可直接集成到项目中:

  • mention-utils.js:包含提及内容提取、格式化等工具函数
  • suggestion-enhancer.js:提供防抖、缓存等增强功能
  • mention-styles.css:预定义的样式方案

通过这些工具,可以将提及功能的集成时间从原来的10天缩短到2天内,同时保证代码质量和性能表现。

Tiptap编辑器Logo

登录后查看全文
热门项目推荐
相关项目推荐