Tiptap Vue 3 中 BubbleMenu 的 shouldShow 回调问题解析与解决方案
问题背景
在 Tiptap Vue 3 项目中,开发者在使用 BubbleMenu 扩展时遇到了一个关于 shouldShow 回调函数的异常行为。具体表现为当使用 editor.isActive 方法作为条件判断时,返回的状态值不符合预期,导致气泡菜单的显示逻辑出现延迟或错误。
问题现象
当开发者在 shouldShow 回调中使用类似 editor.isActive('bold') 的条件时,首次点击已加粗的文本时,回调函数返回的 isActive 值为 false,而只有在第二次点击时才会返回正确的 true 值。这种状态延迟使得气泡菜单无法在正确时机显示。
根本原因分析
经过深入研究发现,问题根源在于 Vue 3 实现中的 reactiveState 属性。在 BubbleMenu 插件调用 shouldShow 回调时,reactiveState 尚未完成更新,导致获取的编辑器状态是过时的。虽然最初怀疑与 requestAnimationFrame 相关的防抖机制有关,但禁用相关调用后问题依然存在,这表明问题更可能与 Vue 3 的响应式系统更新时序有关。
解决方案
直接使用视图状态
最有效的解决方案是绕过 editor.isActive 方法,直接从编辑器的视图状态获取当前激活状态:
import { isMarkActive } from '@tiptap/core';
const shouldShowBubbleMenu = ({ editor }) => {
return isMarkActive(editor.view.state, 'link');
};
这种方法利用了 editor.view.state,该状态在回调时总是最新的,避免了响应式状态延迟的问题。
文本选择判断的适配方案
对于需要判断文本是否被选中的场景,可以类似地直接从视图状态获取信息:
function isTextSelected({ editor }) {
const {
state: {
doc,
selection,
selection: { empty, from, to },
},
} = editor.view;
const isEmptyTextBlock = !doc.textBetween(from, to).length && isTextSelection(selection);
if (empty || isEmptyTextBlock || !editor.isEditable)
return false;
return true;
}
技术原理
Tiptap 在 Vue 3 实现中使用了响应式系统来管理编辑器状态,这导致了状态更新的异步特性。而 BubbleMenu 插件在判断显示条件时,需要同步获取最新状态。通过直接访问 editor.view.state,我们绕过了响应式系统的延迟,获取了即时的编辑器状态。
适用场景
该解决方案适用于:
- Vue 3 项目中使用 Tiptap 的 BubbleMenu 扩展
- 需要基于编辑器状态动态显示/隐藏气泡菜单的场景
- 使用
isActive或其他状态相关方法作为显示条件的实现
注意事项
- 此问题主要存在于 Vue 3 实现中,React 和纯 JavaScript 实现不受影响
- 解决方案同样适用于其他需要即时状态判断的场景
- 对于节点激活状态的判断,可以使用
isNodeActive替代isMarkActive
总结
通过直接访问编辑器视图状态而非依赖响应式状态,开发者可以解决 Tiptap Vue 3 中 BubbleMenu 显示条件的时序问题。这种方案不仅解决了当前问题,也为理解 Tiptap 状态管理机制提供了有价值的参考。
kernelopenEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。C042
MiniMax-M2.1从多语言软件开发自动化到复杂多步骤办公流程执行,MiniMax-M2.1 助力开发者构建下一代自主应用——全程保持完全透明、可控且易于获取。Python00
kylin-wayland-compositorkylin-wayland-compositor或kylin-wlcom(以下简称kywc)是一个基于wlroots编写的wayland合成器。 目前积极开发中,并作为默认显示服务器随openKylin系统发布。 该项目使用开源协议GPL-1.0-or-later,项目中来源于其他开源项目的文件或代码片段遵守原开源协议要求。C01
PaddleOCR-VLPaddleOCR-VL 是一款顶尖且资源高效的文档解析专用模型。其核心组件为 PaddleOCR-VL-0.9B,这是一款精简却功能强大的视觉语言模型(VLM)。该模型融合了 NaViT 风格的动态分辨率视觉编码器与 ERNIE-4.5-0.3B 语言模型,可实现精准的元素识别。Python00
GLM-4.7GLM-4.7上线并开源。新版本面向Coding场景强化了编码能力、长程任务规划与工具协同,并在多项主流公开基准测试中取得开源模型中的领先表现。 目前,GLM-4.7已通过BigModel.cn提供API,并在z.ai全栈开发模式中上线Skills模块,支持多模态任务的统一规划与协作。Jinja00
agent-studioopenJiuwen agent-studio提供零码、低码可视化开发和工作流编排,模型、知识库、插件等各资源管理能力TSX0121
Spark-Formalizer-X1-7BSpark-Formalizer 是由科大讯飞团队开发的专用大型语言模型,专注于数学自动形式化任务。该模型擅长将自然语言数学问题转化为精确的 Lean4 形式化语句,在形式化语句生成方面达到了业界领先水平。Python00