在React中使用WangEditor实现@提及功能

作者:很菜不狗2024.03.15 05:09浏览量:27

简介:本文将介绍如何在React项目中使用WangEditor,一个轻量级的Web富文本编辑器,来实现@提及功能。我们将通过步骤解析和代码示例,帮助读者快速集成并应用此功能。

一、引言

在现代Web应用中,@提及功能已成为用户交互的重要部分,特别是在社交网络、聊天应用或团队协作工具中。在React中,我们可以使用WangEditor这个富文本编辑器来快速实现这一功能。WangEditor是一个轻量级、易于扩展的Web富文本编辑器,它提供了许多内置功能,并支持自定义扩展。

二、安装WangEditor

首先,我们需要在React项目中安装WangEditor。可以通过npm或yarn进行安装:

  1. npm install wangeditor --save
  2. # 或者
  3. yarn add wangeditor

三、在React组件中引入WangEditor

接下来,在需要使用@提及功能的React组件中引入WangEditor:

  1. import React, { useRef, useEffect } from 'react';
  2. import E from 'wangeditor';
  3. const MentionEditor = () => {
  4. const editorRef = useRef(null);
  5. useEffect(() => {
  6. const editor = new E(editorRef.current);
  7. editor.create();
  8. // 自定义@提及功能
  9. editor.config.customConfig.onmenu = function (pos) {
  10. // 在这里添加自定义菜单项,例如@提及
  11. // pos参数为当前光标位置
  12. };
  13. // 处理@提及事件
  14. editor.config.customConfig.onkeydown = function (cmd, evt) {
  15. // 当用户按下键盘时触发
  16. // 可以在这里处理@提及的逻辑
  17. };
  18. return () => {
  19. editor.destroy(); // 组件卸载时销毁编辑器实例
  20. };
  21. }, []);
  22. return <div ref={editorRef} style={{ height: '500px' }} />;
  23. };
  24. export default MentionEditor;

四、实现@提及功能

要在WangEditor中实现@提及功能,我们需要自定义一些逻辑。这里提供一个简单的实现思路:

  1. onmenu配置中添加一个自定义菜单项,用于触发@提及功能。
  2. onkeydown配置中监听用户的键盘输入,当用户输入“@”时,显示一个下拉菜单供用户选择要提及的人。
  3. 用户选择提及的人后,将相应的文本插入到编辑器中。

以下是一个简化的实现示例:

```jsx
// …

useEffect(() => {
const editor = new E(editorRef.current);
editor.create();

// 自定义@提及下拉菜单
const mentionDropdown = document.createElement(‘div’);
mentionDropdown.style.position = ‘absolute’;
mentionDropdown.style.zIndex = ‘9999’;
mentionDropdown.style.display = ‘none’;

// 模拟的提及人员列表
const mentions = [‘张三’, ‘李四’, ‘王五’];

editor.config.customConfig.onmenu = function (pos) {
// 显示@提及下拉菜单
if (evt.key === ‘@’) {
mentionDropdown.innerHTML = mentions.map(mention =>
<div>${mention}</div>
).join(‘’);
mentionDropdown.style.left = ${pos.x}px;
mentionDropdown.style.top = ${pos.y}px;
document.body.appendChild(mentionDropdown);
mentionDropdown.style.display = ‘block’;
}
};

editor.config.customConfig.onkeydown = function (cmd, evt) {
if (evt.key === ‘ ‘) {
// 用户按下空格键,检查是否有选中的@提及人员
const selectedMention = mentionDropdown.querySelector(‘div.active’);
if (selectedMention) {
// 插入@提及文本到编辑器
editor.cmd.do(‘insertHTML’, @${selectedMention.innerText});
mentionDropdown.style.display = ‘none’;
}
}
};

// 处理下拉菜单的点击事件
mentionDropdown.addEventListener(‘click’, function (event) {
event.preventDefault();
const clickedMention = event.target;
if (clickedMention.tagName === ‘DIV’) {
clickedMention.classList.add(‘active’);
setTimeout(() => {
clickedMention.classList.remove(‘active’);
}, 100);
}
});