prosemirror error - Applying a mismatched transaction

bug描述

使用 prosemirror 时,dispatch transcation 报错:

代码如下(简化版):

js 复制代码
import { inject } from "vue";
const editorView = inject("editorView");

function handleClick() {
  const view = editorView.value;
  view.dispatch(view.state.tr.deleteSelection());
}

在 prosemirror discuss 找到了相关问题:RangeError: Applying a mismatched transaction。pm 的作者在讨论中解释了这个 error 的含义:

"Mismatched transaction" errors mean that something is trying to dispatch a transaction that doesn't start from the view's current state---I.e. if you create the transaction but then don't synchronously dispatch it, it'd be possible for another transaction to happen in the meantime, which makes your transaction invalid. The rest of the stack trace for the error likely points at the code that's dispatching the transaction on the outdated (or, possibly, completely unrelated) state.

很奇怪,我没有用异步操作啊。顺着报错stack,找到 applyInner 方法。发现当 eq() 返回 false时,会抛出 error

查看 eq 方法,根据注释知道它是用来判断 thisother 是否代表同一块内容。

查看 this,是 Vue的 Reactive 对象,包着 doc Node。

查看 other:是 doc Node 对象

破案了。

解释

我项目用的 vue3。在父组件中把 editorView 用 ref 包了一下,然后 provide 下去。

js 复制代码
const editorView = ref()
provide("editorView", editorView );
onMounted(() => {
  editorView.value = new EditorView();
});

子组件(也就是调用 dispatch 的组件) inject 进来的是这个 ref 对象。
在 vue 3 中被 ref 包着的对象,通过.value 得到的不是原对象,而是原对象的 proxy!

vue2 vs vue3

js 复制代码
const obj ={a:1}
console.log(obj === ref(obj).value)

同样一段代码,在 vue2 环境中是 true,在 vue3 中是 false

平时工作项目里一直用 vue2,这次测试项目装的 vue3,没注意差别
一定要记得,vue2 和 vue3 的响应式原理是有区别的。平时开发不显眼,一旦踩坑就很麻烦

相关推荐
会周易的程序员3 小时前
js-shm: 高性能 Node.js 共享内存模块
开发语言·javascript·c++·node.js·共享内存·shm
带娃的IT创业者3 小时前
重新定义前端构建速度:深度解析 SWC 如何用 Rust 颠覆 JavaScript 工具链
前端·javascript·rust·前端构建·swc
新中地GIS开发老师5 小时前
零基础WebGIS开发入门 | GeoJSON数据持久化
前端·javascript·gis·webgis·三维gis开发
blns_yxl5 小时前
正则驱动实时表单验证(HTML+CSS+JS+正则)
javascript·css·html
Quz6 小时前
QML 与 JavaScript 交互方式:内联函数、外部文件、信号槽与工作线程
javascript·qt
Allshadow6 小时前
Nest.js - 连接数据库
javascript·nestjs
冰暮流星6 小时前
javascript之date对象
开发语言·javascript·ecmascript
橘子星6 小时前
别光看教程!手把手拆解 React Todo 项目,一文吃透 5 个核心概念
前端·javascript
蜡台6 小时前
使用 uni-popup 实现数据选择器Data-Picker
前端·javascript·html·uniapp·uni-popup·data-picker
blns_yxl6 小时前
Promise封装Fetch + 重试机制(HTML+JS)
前端·javascript·html