wangeditor自己实现关键字高亮

news/2025/3/26 11:28:05/文章来源:https://www.cnblogs.com/wzcsqaws/p/18789520

工作中用到了这个编辑器,本以为关键字高亮这个如此高频的功能它肯定是实现了的,结果竟然没有!!网上找了一圈也没有,好家伙我排期也没排这块时间啊,所以只能自己加班写一个了。

方案简析

wangeditor底层其实使用的是Slate这个编辑器,你要自己实现此功能,本质上就是调用Slate对应的方法。

主要使用了以下几个大类SlateEditor、SlateTransforms

SlateEditor

调用SlateEditor.nodes获取到所有的文本节点

    // 使用 Editor.nodes 方法遍历所有节点const textNodes = Array.from(SlateEditor.nodes(editorRef, {at: [],match: matchText,}));
SlateTransforms

调用SlateTransforms.setNodes 传入参数首位坐标让指定关键字单独形成一个文本节点,从而实现高亮

    // au 为首尾坐标SlateTransforms.setNodes(editorRef,{//@ts-ignorecolor,},{at: au,split: true,match: (value) => {//@ts-ignorereturn isPlainObject(value) && typeof value?.text === "string";},});

调用SlateTransforms.mergeNodes 传入指定节点让其与其他节点合并,用于关键字被删除后取消高亮

SlateTransforms.mergeNodes(editorRef, {at: au.anchor.path,});

完整代码

直接上代码,也不难,主要是大家对slate的api不熟悉,相信大家一看就懂,
注意一下findTemplatePositions方法,为判断文字是否高亮的条件,大家按需修改即可

<script setup lang="ts">
import { onBeforeUnmount, ref, shallowRef, onMounted } from "vue";
import { SlateEditor, SlateTransforms } from "@wangeditor/editor";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";// 编辑器实例,必须用 shallowRef,重要!
const editorRef = shallowRef();// 内容 HTML
const valueHtml = ref("<p>hello</p>");function isObject(value) {return value !== null && typeof value === "object" && !Array.isArray(value);
}
function isPlainObject(o) {let ctor, prot;if (isObject(o) === false) return false;// If has modified constructor// eslint-disable-next-line prefer-constctor = o.constructor;if (ctor === undefined) return true;// If has modified prototype// eslint-disable-next-line prefer-constprot = ctor.prototype;if (isObject(prot) === false) return false;// If constructor does not have an Object-specific methodif (prot.hasOwnProperty("isPrototypeOf") === false) {return false;}// Most likely a plain Objectreturn true;
}
function matchText(value) {return isPlainObject(value) && typeof value.text === "string";
}function findTemplatePositions(str) {const regex = /{([^}]*)}/g; // 创建正则表达式,匹配以{开头并以}结尾的内容let match;const positions: any = [];while ((match = regex.exec(str)) !== null) {const startIndex = match.index;const endIndex = startIndex + match[0].length;positions.push({ startIndex, endIndex, content: match[0] });}return positions;
}function mergeNodes(au, editorRef) {SlateTransforms.setNodes(editorRef,{//@ts-ignorecolor: "",},{at: au,split: false,match: matchText,});SlateTransforms.mergeNodes(editorRef, {at: au.anchor.path,});
}
function setNodes(au, editorRef, color) {SlateTransforms.setNodes(editorRef,{//@ts-ignorecolor,},{at: au,split: true,match: (value) => {//@ts-ignorereturn isPlainObject(value) && typeof value?.text === "string";},});
}// 模拟 ajax 异步获取内容
onMounted(() => {});// 编辑器配置
const editorConfig = {placeholder: "请输入内容...",MENU_CONF: {/* 菜单配置,下文解释 */},
};function parseTTSContentWithJsonPathToHtml(editorRef, color) {// setTimeout(() => {try {// 使用 Editor.nodes 方法遍历所有节点const textNodes = Array.from(SlateEditor.nodes(editorRef, {at: [],match: matchText,}));// 打印所有文本节点textNodes.forEach(([node, path]: any) => {const arr = findTemplatePositions(node.text);if (node.color === color) {if (!arr.length ||arr[0].startIndex !== 0 ||arr[0].endIndex !== node.text.length) {const au = {anchor: {path: path,offset: 0,},focus: {path: path,offset: node.text.length,},};mergeNodes(au, editorRef);}} else {if (arr.length) {arr.forEach((item) => {const au = {anchor: {path: path,offset: item.startIndex,},focus: {path: path,offset: item.endIndex,},};setNodes(au, editorRef, color);});}}});} catch (error) {}// }, 100)
}function handChange() {parseTTSContentWithJsonPathToHtml(editorRef.value, "#FAAD14");
}const handleCreated = (editor) => {editorRef.value = editor; // 记录 editor 实例,重要!
};// 组件销毁时,及时销毁编辑器
onBeforeUnmount(() => {const editor = editorRef.value;if (editor == null) return;editor.destroy();
});
</script><template><div style="border: 1px solid #ccc"><Toolbar:editor="editorRef"style="border-bottom: 1px solid #ccc"/><!-- 编辑器 --><Editorv-model="valueHtml":defaultConfig="editorConfig"style="height: 500px; overflow-y: hidden"@onCreated="handleCreated"@on-change="handChange"/></div>
</template><!-- 别忘了引入样式 -->
<style src="@wangeditor/editor/dist/css/style.css"></style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/904822.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PPT 转高精度图片 API 接口

PPT 转高精度图片 API 接口 文件处理 / 图片处理,将 PPT 文件转换为图片序列。1. 产品功能支持将 PPT 文件转换为高质量图片序列; 支持 .ppt 和 .pptx 格式; 保持原始 PPT 的布局和样式; 转换后的图片支持永久访问; 全接口支持 HTTPS(TLS v1.0 / v1.1 / v1.2 / v1.3); …

20242931 2024-2025-2 《网络攻防实践》第四周作业

20242931 2024-2025-2 《网络攻防实践》第四周作业 1. 实验内容 1.1 实验要求 在网络攻防实验环境中完成TCP/IP协议栈重点协议的攻击实验,包括ARP缓存欺骗攻击、ICMP重定向攻击、SYN Flood攻击、TCP RST攻击、TCP会话劫持攻击。 1.2 知识点梳理与总结攻击类型 攻击原理 攻击目…

面试官:工作中优化MySQL的手段有哪些?

MySQL 是面试中必问的模块,而 MySQL 中的优化内容又是常见的面试题,所以本文来看“工作中优化MySQL的手段有哪些?”。工作中常见的 MySQL 优化手段分为以下五大类:索引优化:确保高频查询字段有合适索引。 SQL优化:减少全表扫描、避免不必要计算。 事务与锁优化:避免长事…

分享一个神器免费解释你的梦境

分享一个神器免费解释你的梦境 周公解梦 - 玄机解梦AI 它能运用先进的 AI 技术解析梦境含义,为用户提供便捷、智能的解梦服务。## 一、独特的解梦算法——“三元解梦法”玄机解梦平台的核心技术是其独创的“三元解梦法”,这一方法巧妙地融合了东方传统解梦智慧、现代心理学理…

2025长城杯国赛半决赛 应急响应

2025 长城杯 国赛 半决赛 ISW 应急响应赛场上做应急响应的时候完全是摸不到一点思路,恨不得是见一个ip就交上去试一下.. 赛后复现时刻 1 找ip RStudio加载镜像raw文件对镜像文件进行扫描我们能看到 root 目录下没有文件,以及存在非 root 用户 ubuntu 补充一下:如果root目录下…

picoctf 2025

picoctf 2025 web n0s4n1ty 1 内容 开发人员已将个人资料图片上传功能添加到网站。但是,该实现存在缺陷,这为您提供了一个机会。您的任务(如果您选择接受)是导航到提供的网页并找到文件上传区域。您的最终目标是找到位于/root目录中的隐藏标志 提示File upload was not san…

hgame2025

hgame2025 web Level 24 Pacmanbase64解码 misc Hakuya Want A Girl Friend txt导出zipzip文件被损坏用WinRAR打开 在工具选项下 找到修复压缩文件没发解压缩 显示不是zip文件格式,再看txt文件尾,看到是倒着的png去爆一下长宽高得到压缩包密码,解压缩 得到flag hagme{h4kyu4…

2025 长城杯 国赛 半决赛 ISW 应急响应

2025 长城杯 国赛 半决赛 ISW 应急响应赛场上做应急响应的时候完全是摸不到一点思路,恨不得是见一个ip就交上去试一下.. 赛后复现时刻 1 找ip RStudio加载镜像raw文件对镜像文件进行扫描我们能看到 root 目录下没有文件,以及存在非 root 用户 ubuntu 补充一下:如果root目录下…

Ubuntu中apt设置国内源(以阿里云为例)

摘自:https://zhuanlan.zhihu.com/p/7107285821 在 Ubuntu 系统中,将 APT 源设置为阿里云源可以提高软件包更新和下载速度。设置国内源 1. 备份现有的源列表: sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak 2. 编辑 sources.list 文件: 使用以下命令打开 sourc…

建筑行业PLM实施案例:5种资源分配矩阵在EPC项目中的创新应用

——PLM如何破解建筑行业资源困局 根据住建部数据,2025年中国建筑行业EPC(设计-采购-施工)项目平均资源浪费率达18%,关键路径延误超30%。而中南建筑设计院通过PLM(产品生命周期管理)系统,在钟祥文化振兴项目中实现资源利用率提升42%,工期缩短10%。本文结合5大资源分配矩…

.NET 生成PDF文件

1、网上检索N种解决方案 QuestPDF:简单方便实用,文档也相对来说全,但是开源协议,当企业规模大的100W美金需要收费,未来存在潜在版权问题。 itext7:感觉实用偏复杂,项目类库引用复杂,不够轻量,看中了 该开源库根据HTML生成PDF,gitlab 查看N套解决方案,经过测试用例编…

关于Transformer中Decoder模块是如何预测下一个字符的算法

关于Transformer模型的Encoder-Decoder模块网上介绍的文章非常多,写的非常详尽,可谓汗牛充栋,尤其关于注意力计算这块,不仅给出了公式而且还有具体的计算步骤。关于Transformer模型我觉得大部分文章语焉不详的有两块(可能是我的理解力比较差): 一是关于FNN层的,就是FNN…